多态和继承

多态是面向对象的三大特性之一,允许父类引用指向子类对象,调用相同的方法得到不同的结果。本文详细介绍了向上转型、向下转型、多态的意义以及经典案例,并探讨了方法调用的优先级和继承链中的方法执行顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多态

一个父类可以有多个子类,而在子类里可以重写父类的方法,这样每个子类里重写的代码不一样,自然表现形式就不一样。这样用父类的变量去引用不同的子类,在调用这个相同的方法的时候得到的结果和表现形式就不一样了,这就是多态,相同的消息(也就是调用相同的方法)会有不同的结果。
多态通过动态绑定(dynamic binding)技术来实现,是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。也就是说,只有程序运行起来,你才知道调用的是哪个子类的方法。

子类是对父类的改进和扩充。正是因为父类和不同子类之间有共性,所以才由父类的引用指向不同的子类。Father既可以指向Son1又可以指向Son2就是因为他们有相同的共性

1.向上转型

向上转型是父类引用指向子类对象。通俗地说就是是将子类对象转为父类对象。

父类引用指向子类对象指的是:例如父类Animal,子类Cat,Dog。其中Animal可以是类也可以是接口,Cat和Dog是继承或实现Animal的子类。

Animal animal = new Cat(); 

即声明的是父类,实际指向的是子类的一个对象。

2.向下转型

java中“向上转型”是自动的。但是“向下转型”却不是自动的。需要我们用强制类型转化。

Animal c = new Cat();
Cat c1 = (Cat)c;    //不允许“向下转型”,需用强制类型转化

3.多态的意义

多态方式声明是一种好的习惯。当我们创建的类,使用时,只用到它的超类或接口定义的方法时,我们可以将其索引声明为它的超类或接口类型。

它的好处是,如果某天我们对这个接口方法的实现方式变了,对这个接口又有一个新的实现类,我们的程序也需要使用最新的实现方式,此时只要将对象实现修改一下,索引无需变化。

比如Map<String,String> map = new HashMap <String,String>();
想换成HashTable实现,可以Map<String,String> map = new HashTable <String,String>();

这种小范围的使用可能体现的用处不明显。

当我们使用Spring,或者设计数据库连接使用时,可能会明显些。

我们可能会随着业务发展,数据库的实现从mySql改为Oracle等。如果我们设计的时候,将数据库驱动的索引直接定义为mySql特定的驱动时,切换Oracle就要修改源码了。如果定义为接口的方式,如Dirver等,此时的切换,只要修改配置文件数据库驱动即可,源码中对数据库的各种操作都无需修改。

4.经典案例

class A {
    public String show(D obj) {
        return ("A and D");
    }

    public String show(A obj) {
        return ("A and A");
    }

}

class B extends A{
    public String show(B obj){
        return ("B and B");
    }

    public String show(A obj){
        return ("B and A");
    }
}

class C extends B{

}

class D extends B{

}

public class Demo {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new B();
        B b = new B();
        C c = new C();
        D d = new D();

        System.out.println("1--" + a1.show(b));
        System.out.println("2--" + a1.show(c));
        System.out.println("3--" + a1.show(d));
        System.out.println("4--" + a2.show(b));
        System.out.println("5--" + a2.show(c));
        System.out.println("6--" + a2.show(d));
        System.out.println("7--" + b.show(b));
        System.out.println("8--" + b.show(c));
        System.out.println("9--" + b.show(d));
    }
}
//结果:
//1--A and A
//2--A and A
//3--A and D
//4--B and A
//5--B and A
//6--A and D
//7--B and B
//8--B and B
//9--A and D

注意:
1.父类中的方法只有在子类中没被重载,才可以被父类类型的引用调用;
2.对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法
3.子类会继承父类的所有函数,有些没有明确写出来但是还是存在于子类中
4.父类不能调用父类中没有声明而子类新声明的方法

补充知识点:

1.当父类对象的引用指向子类对象时,声明对象的类型决定了可调用的成员方法的范围(范围是父类已声明的方法),新建对象的类型决定具体执行哪一个实现。

class X {
    public void show(Y y){
        System.out.println("x and y");
    }

    public void show(){
        System.out.println("only x");
    }
}

class Y extends X {
    public void show(Y y){
        System.out.println("y and y");
    }
    public void show(int i){

    }
}

class Z extends X {
    public void show(Y y){
        System.out.println("z and z");
    }
    public void show(int i){

    }
}
class main{
    public static void main(String[] args) {
        X x = new Y();
        x.show(new Y());
        x=new Z();
        x.show(new Y());
        x.show();
    }
}
//结果
//y and y
//z and z
//only x

X x=new Y();声明类型是X表示可以调用show(Y y)和show()方法,新建类型是Y说明要调用Y中的show(Y y)和show()

2.继承链中对象方法的调用的优先级:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。

abcd的关系是这样的:C/D —> B —> A

我们先来分析4 : a2.show(b)

  • 首先,a2是类型为A的引用类型,它指向类型为B的对象。A确定可调用的方法:show(D obj)和show(A obj)。
  • a2.show(b) ==> this.show(b),这里this指的是B。
  • 然后.在B类中找show(B obj),找到了,可惜没用,因为show(B obj)方法不在可调用范围内,this.show(O)失败,进入下一级别:super.show(O),super指的是A。
  • 在A 中寻找show(B obj),失败,因为没用定义这个方法。进入第三级别:this.show((super)O),this指的是B。
  • 在B中找show((A)O),找到了:show(A obj),选择调用该方法。 输出:B and A

我们再来看一下9:b.show(d)

  • 首先,b为类型为B的引用对象,指向类型为B的对象。没有涉及向上转型,只会调用本类中的方法。
  • 在B中寻找show(D obj),方法。现在你不会说没找到了吧?找到了,直接调用该方法。 输出 A and D。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值