欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > 【JAVA基础】多态

【JAVA基础】多态

2025/4/27 17:01:55 来源:https://blog.csdn.net/weixin_51325964/article/details/141499521  浏览:    关键词:【JAVA基础】多态

文章目录

  • 多态
  • 向上转型
  • 练习题


多态

父类的引用指向子类的对象

public class A {public String name;public int age;public void run(){ //该run()方法被覆盖System.out.println("a跑的快");}public void eat(String name){System.out.println(name+"吃的很多");}
}public class B extends A{public char sex;public double height;public void fly(){System.out.println("b飞的很高");}@Overridepublic void run(){System.out.println("b跑的快");}
}public class Test {public static void main(String[] args) {A ab = new B();  // 数据类型:决定在内存中的存储形式 ab是A类数据类型// 创建子类对象前提一定会创建父类对象,此时在内存中A和B的对象都存在ab.name = "李四";ab.age = 18;ab.eat("张三");ab.run();}
}

以上代码中对象ab就是多态,其中:

  1. 因为ab为A类的数据类型,以A类为模板,所以他可以调用到A类中的属性

  2. ab为B类的对象,而B为A的子类,那么创建子类对象之前一定会先创建父类对象,所以ab可以访问A类中的方法

  3. 但是ab实际上指向的是子类对象的内存空间,因为受限于父类数据类型,所以只能对父类中的数据进行访问,子类中单独的数据并不能够进行访问

在这里插入图片描述

  1. ab满足了定义父类引用指向子类对象

我们看一下内存图:

创建对象ab的过程如下:

  1. ab属于B类对象,但是B类拥有A父类,那么创建子类对象之前先创建父类对象,为A类对象开辟空间,在其中存储name、age两个变量和run()、eat()两个方法
  2. 再为B类对象,其中包括sex、height两个变量和run()、fly()
  3. 因为B类为A类的子类,所以run()方法被重写,ab对象访问的话只能访问到B类中的run()方法和A中的eat()方法
  4. 因为ab为A类的数据类型,以A类为模板,所以他可以调用到A类中的属性
    在这里插入图片描述

向上转型

public class C {public static void hanlder(A a){System.out.println("C的输出");}
}public class Test {public static void main(String[] args) {B b = new B();C.hanlder(b); // 没有报错,为什么?}
}

在程序中,C类中的静态方法hanlder(A a)需要的参数为一个A类对象,但是在Test类中的main()方法里,我们却向方法传了一个B类的对象,编译器并没有报错,这是因为多态可以向上转型:子类的对象可以被父类所接受,也就是我们一开始说的定义:父类引用指向子类对象

练习题

A类

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

B类

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

C类

public class C extends B{
}

D类

public class D extends B{
}

Test类

public class Test {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(a1.Show(b)); // A and ASystem.out.println(a1.Show(c)); // A and ASystem.out.println(a1.Show(d)); // A and DSystem.out.println(a2.Show(b)); // B and ASystem.out.println(a2.Show(c)); // B and ASystem.out.println(a2.Show(d)); // A and DSystem.out.println(b.Show(b)); // B and ASystem.out.println(b.Show(c)); // B and ASystem.out.println(b.Show(d)); // A and D}
}

我们来逐个分析一下:

首先我们可以看到A类的优先级最高,是其他BCD类的父类,B类直接继承A类,CD类直接继承B类。

  • 那么对于对象a1

    它属于A类对象,创建时只开辟A类对象的内存空间,可以调用A类中的两种Show()方法,虽然B类中有对Show方法重写,但是此时并没有开辟B类对象的内存空间,所以并不会出现重写覆盖的现象

    System.out.println(a1.Show(b)); // A and A
    

    a1为A类对象,只能访问A类中的数据,b属于B类对象,B类为A的子类,所以向上转型,可以被A中的show(A obj)方法接受

    System.out.println(a1.Show(c)); // A and A
    

    同理,c为C类对象,拥有B父类,B父类拥有A父类,所以和第一个同理

    System.out.println(a1.Show(d)); // A and D
    

    虽然也是通过a1访问,但是传入的参数为d,show()方法的重载,选择第一个show(D obj)方法

    在这里插入图片描述

  • 对于对象a2

    它属于A类数据类型的B类对象,也就是多态,创建时B类为A类的子类,创建子类对象之前要创建父类对象,所以会为A类、B类对象都开辟内存空间。因为a2的数据类型为A类数据类型,所以只能访问A类中的数据,但是同时开辟了B类的内存空间,所以B类中如果有对A类方法的重写,则调用B中的重写方法

    System.out.println(a2.Show(b)); // B and A
    

    a2为数据类型为A的B类对象,创建子类对象时先创建父类对象,创建时分别为A类、B类开辟空间,然后因为是A类数据类型,所以应该访问A类中的show(A obj)方法,但是因为中对方法有重写,所以访问B类中的show(A obj)

    System.out.println(a2.Show(c)); // B and A
    

    同理,c为C类对象,但是向上转型,可以被show(A obj)接受

    System.out.println(a2.Show(d)); // A and D
    

    同理,但是传入的参数为d,由于方法重载,所以访问show(D obj)

    在这里插入图片描述

  • 对于对象b

    它属于B类对象,B类是A类的子类,创建子类对象之前先创建父类对象,所以在创建对象b时,会先为A类对象开辟内存空间,再开辟B类对象空间。对象b可以访问A类和B类中的方法,如果B类中存在方法重写,那么访问B类中的重写方法

    System.out.println(b.Show(b)); // B and A
    

    b为B类对象,访问B类中的Show(A obj),这里存在向上转型的情况,从下往上匹配,Object类属于所有类的父类,所以先匹配A类参数,所以访问Show(A obj)

    System.out.println(b.Show(c)); // B and A
    

    b为B类对象,传入c对象,由于方法重写以及向上转型访问B类中的show(A obj)

    System.out.println(b.Show(d)); // A and D
    

    b为B类对象,创建子类对象时先创建父类对象,访问A类中的show(D obj)

    在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词