四java的多态

BUG之神 68

一、什么是多态

在Java中,多态是面向对象编程中的一个重要概念,它允许不同类型的对象对同一方法进行不同的实现。具体来说,多态性指的是通过父类的引用变量来引用子类的对象,从而实现对不同对象的统一操作

例如:狗和猫都是动物,动物共同的行为都有吃这个动作,而狗可以表现为啃骨头,猫则可以表现为吃老鼠。这就是多态的表现,即同一件事情,发生在不同对象的身上,就会产生不同的结果。

二、多态实现的条件

继承关系
存在继承关系的类之间才能够使用多态性。多态性通常通过一个父类用变量引用子类对象来实现。

方法重写
子类必须重写(Override)父类的方法。通过在子类中重新定义和实现父类的方法,可以根据子类的特点行为改变这个方法的行为,如猫和狗吃东西的独特行为。

父类引用指向子类对象
使用父类的引用变量来引用子类对象。这样可以实现对不同类型的对象的统一操作,而具体调用哪个子类的方法会在运行时多态决定

例如,下面的案例是根据猫和狗叫的动作的不同,而实现的多态:

class Animal {
    public void sound() {
        System.out.println("动物发出声音");
    }
}

class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("狗发出汪汪声");
    }
}

class Cat extends Animal {
    @Override
    public void sound() {
        System.out.println("猫发出喵喵声");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal1 = new Dog(); // 父类引用指向子类对象
        Animal animal2 = new Cat(); // 父类引用指向子类对象

        animal1.sound(); // 输出:狗发出汪汪声
        animal2.sound(); // 输出:猫发出喵喵声
    }
}

在这个示例中,Animal 类是父类,Dog 和 Cat 类是它的子类。通过将父类的引用变量分别指向子类对象,实现了多态性。在运行时,根据引用变量的实际类型来调用相应的子类方法,从而输出不同的声音。

三、向上转型和向下转型

1 向上转型

向上转型(Upcasting)是指将一个子类的对象引用赋值给其父类类型的引用变量。这是在面向对象编程中的一种常见操作,用于实现多态性和灵活的对象处理。

下面是一个简单的示例代码,展示了向上转型的使用:

class Animal {
    public void eat() {
        System.out.println("Animal is eating.");
    }
}

class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("Dog is eating.");
    }

    public void bark() {
        System.out.println("Dog is barking.");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Dog();  // 向上转型
        animal.eat();  // 调用的是 Dog 类中的 eat() 方法
        // animal.bark();  // 错误:无法访问 Dog 类中独有的方法

        Dog dog = (Dog) animal;  // 向下转型
        dog.bark();  // 调用 Dog 类中的 bark() 方法
    }
}

2 向下转型

向下转型(Downcasting)是指将一个父类类型的引用变量转换为其子类类型的引用变量。它与向上转型相反,需要进行显式的类型转换操作。

需要注意的是,向下转型是有风险的,因为转换的对象必须是实际上是子类对象才能成功,否则会在运行时抛出 ClassCastException 异常。

下面是一个示例代码,展示了向下转型的使用:

class Animal {
    public void eat() {
        System.out.println("Animal is eating.");
    }
}

class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("Dog is eating.");
    }

    public void bark() {
        System.out.println("Dog is barking.");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Dog();  // 向上转型

        // 使用向下转型之前,需要先检查对象是否实际上是子类的实例
        if (animal instanceof Dog) {
            Dog dog = (Dog) animal;  // 向下转型
            dog.bark();  // 调用 Dog 类中的 bark() 方法
        } else {
            System.out.println("animal is not an instance of Dog");
        }
    }
}

在上述示例中,首先创建了一个 Dog 类的对象,并将其赋值给一个 Animal 类型的引用变量 animal,这就是向上转型的过程。然后,通过使用 instanceof 运算符检查 animal 是否是 Dog 类的实例,以确保进行向下转型时的类型安全。

如果 animalDog 类的实例,那么可以将其转型为 Dog 类型,并使用 dog 引用变量调用 Dog 类中特有的方法 bark()。如果 animal 不是 Dog 类的实例,则可以根据实际需求进行相应的处理。

需要注意的是,在进行向下转型之前,一定要确保对象实际上是子类的实例,否则会导致 ClassCastException 异常。因此,在进行向下转型之前,应该使用 instanceof 运算符进行类型检查,以避免出现异常情况。

四、多态的优缺点

Java多态性的优点:

1.灵活性和可扩展性:多态性使得代码具有更高的灵活性和可扩展性。通过使用父类类型的引用变量,可以以统一的方式处理不同类型的对象,无需针对每个具体的子类编写特定的代码。

2.代码复用:多态性可以促进代码的复用。可以将通用的操作定义在父类中,然后由子类继承并重写这些操作。这样一来,多个子类可以共享相同的代码逻辑,减少了重复编写代码的工作量。

3.可替换性:多态性允许将一个对象替换为其子类的对象,而不会影响程序的其他部分。这种可替换性使得系统更加灵活和可维护,可以方便地添加新的子类或修改现有的子类,而无需修改使用父类的代码。

4.代码扩展性:通过引入新的子类,可以扩展现有的代码功能,而无需修改现有的代码。这种可扩展性使得系统在需求变化时更加容易适应和扩展。

Java多态性的缺点:

1.运行时性能损失:多态性需要在运行时进行方法的动态绑定,这会带来一定的性能损失。相比于直接调用具体的子类方法,多态性需要在运行时确定要调用的方法,导致额外的开销。

2.代码可读性下降:多态性使得代码的行为变得更加动态和不确定。在某些情况下,可能需要跟踪代码中使用的对象类型和具体的方法实现,这可能降低代码的可读性和理解性。

3.限制访问子类特有成员:通过父类类型的引用变量,只能访问父类及其继承的成员,无法直接访问子类特有的成员。如果需要访问子类特有的成员,就需要进行向下转型操作,这增加了代码的复杂性和维护的难度。

虽然多态性具有一些缺点,但在大多数情况下,其优点远远超过缺点,使得代码更具灵活性、可扩展性和可维护性。因此,多态性在Java编程中被广泛应用。

 

 

分享