《深入理解 Java 中的多态性》

目录

一、多态性的基本理解

二、Java 中多态性的体现:虚拟方法调用

编译时与执行时的行为差异

三、多态的使用前提

要有类的继承关系

要有类的重写

四、多态的适用性

五、多态的好处与弊端

好处

弊端


一、多态性的基本理解

多态性,简单来说,就是一个事物可以呈现出多种形态。就好比在现实生活中,一个人可以同时拥有多种身份,在不同的场景下展现出不同的行为特点。在 Java 编程的语境中,多态性使得同一个操作在不同的对象上会产生不同的执行结果,这为我们编写灵活且可维护性高的代码提供了强大的支持。

二、Java 中多态性的体现:虚拟方法调用

编译时与执行时的行为差异

在多态场景下调用方法时,会出现一种很有意思的现象。在编译阶段,Java 编译器会认为是在调用方法左边声明的父类的类型的方法。而到了执行时,实际指向执行的却是子类重写的那个方法。我们通常把这种情况简称为 “编译看左边,运行看右边”。

下面通过一个简单的代码案例来更好地理解这一点:

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

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("汪汪汪");
    }
}

class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("喵喵喵");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal1 = new Dog();
        Animal animal2 = new Cat();

        animal1.makeSound(); // 编译时看作Animal类的makeSound方法,运行时执行Dog类重写的makeSound方法,输出:汪汪汪
        animal2.makeSound(); // 编译时看作Animal类的makeSound方法,运行时执行Cat类重写的makeSound方法,输出:喵喵喵
    }
}

在上述代码中,我们定义了Animal类作为父类,DogCat类作为子类并分别重写了makeSound方法。在main方法中,我们创建了DogCat类的对象,但将它们声明为Animal类型的引用。当调用makeSound方法时,就体现了 “编译看左边,运行看右边” 的多态特性。

三、多态的使用前提

要在 Java 中实现多态,需要满足两个重要的前提条件:

要有类的继承关系

就像我们上面的例子中,DogCat类继承自Animal类一样。通过继承,子类可以继承父类的属性和方法,并且可以在这个基础上进行扩展和重写,这为多态性的实现奠定了基础。

要有类的重写

子类需要对父类的某些方法进行重写,以实现自己特定的行为逻辑。只有这样,在多态调用时,才能根据实际对象的类型执行子类重写后的方法,而不是仅仅执行父类的原始方法。

四、多态的适用性

多态性在 Java 中主要适用于方法,而不适用于属性。这是因为当我们通过父类引用指向子类对象时,虽然可以调用被子类重写的方法,但对于属性来说,访问的始终是父类中定义的属性(即使子类中可能也有同名属性)。例如:

class Parent {
    protected int value = 10;
}

class Child extends Parent {
    protected int value = 20;
}

public class Main {
    public static void main(String[] args) {
        Parent parent = new Child();
        System.out.println(parent.value); // 输出:10,访问的是父类的属性值
    }
}

在这个例子中,尽管创建的是Child类的对象,但通过父类引用访问value属性时,得到的是父类中定义的属性值。

五、多态的好处与弊端

好处

多态性为我们的代码带来了极大的便利,其最大的好处就是能够极大地减少代码的冗余。想象一下,如果没有多态,我们可能需要为不同类型的对象分别定义多个重载的方法来实现类似的功能。而有了多态,我们只需要在父类中定义一个通用的方法,然后让各个子类根据自身的需求重写该方法即可。这样不仅使代码更加简洁,也提高了代码的可维护性和扩展性。

弊端

然而,多态性也并非完美无缺。例如,当我们像这样创建对象:Person p2 = new Man();(假设ManPerson的子类),在内存中虽然已经加载了Man类中声明的特有的属性和方法,但由于声明为父类引用,导致我们没有办法直接调用Man中加载的特有的属性和方法。也就是说,在多态的场景下,我们创建了子类的对象,也加载了子类特有的属性和方法,但因为引用类型是父类的,所以无法直接访问子类特有的那些属性和方法。这在某些情况下可能会给我们的编程带来一些不便,需要我们通过一些其他的方式(比如类型转换)来解决这个问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值