继承里面的重写问题(父类与子类方法重名时,调用的优先级问题) 您所在的位置:网站首页 java如何跳转同名函数的方法 继承里面的重写问题(父类与子类方法重名时,调用的优先级问题)

继承里面的重写问题(父类与子类方法重名时,调用的优先级问题)

2024-03-24 22:45| 来源: 网络整理| 查看: 265

1.父类对象与子类对象分别调用相同方法名的方法 class Person2{ public void show(){ System.out.println("父类Person2的show方法"); } public void show1(){ System.out.println("父类Person2的show1方法"); } } class Student2 extends Person2{ public void show(){ System.out.println("子类Student2的show方法"); } public void show1(){ System.out.println("子类Student2的show1方法"); } } public class OverrideDemo1 { public static void main(String[] args) { Student2 s = new Student2(); s.show(); s.show1(); Person2 p = new Person2(); p.show(); p.show1(); } }

结果为 在这里插入图片描述 父类对象调用父类的方法,打印父类方法的两条语句 子类对象调用与父类同名的方法,优先调用子类自己重写后的方法,打印子类方法里面的两条语句

2. 父类方法和构造器调用被子类重写后的方法 class Person2{ public void show(){ System.out.println("父类Person2的show方法"); show1(); } public void show1(){ System.out.println("父类Person2的show1方法"); show1(); } } class Student2 extends Person2{ public void show(){ super.show(); } public void show1(){ System.out.println("子类Student2的show1方法"); } } public class OverrideDemo1 { public static void main(String[] args) { Student2 s = new Student2(); s.show(); } }

在这里插入图片描述

这里通过子类对象调用子类的show方法,show方法的方法体内是super.show(); ,这句话的意思是调用父类的show()方法,父类的show方法里面是调用show1()方法。 那么问题来了,根据方法调用的优先级顺序,这里应该是优先调用本类的show1()方法。但是因为子类重写了父类的show1()方法,方法重写又叫覆盖,这里会调用子类的show1()方法,而不是父类的。

同理,在父类构造器中出现,被子类重写后的方法时,也是优先调用子类的方法

package test; class Person2{ Person2(){ System.out.println("父类的构造方法"); show(); } public void show(){ System.out.println("父类Person2的show方法"); } } class Student2 extends Person2{ Student2(){ System.out.println("子类的构造方法"); show(); } public void show(){ //super.show1(); System.out.println("子类Student2的show方法"); } } public class OverrideDemo1 { public static void main(String[] args) { new Student2(); System.out.println("======="); new Person2(); } }

结果为 在这里插入图片描述 输出结果中的第二句是调用了子类的show方法 因为在调用子类的构造器之前,会先初始化父类的构造器,所以才会看到先打印了父类的构造方法,然后父类构造方法调用被子类重写后的show方法,最后才是子类的构造器输出结果并且调用子类的show方法

如果对为什么先调用父类构造器有点晕的话,可以看这篇博客(这个超链接指向的博客)的后半部分

当然,如果用父类对象直接调用父类的构造器或者方法,那么是不会调用子类中被重写的方法的,上面的例子的后半部分结果证明了构造器,下面这个例子证明了调用的是父类的方法

class Person2{ public void show(){ System.out.println("父类Person2的show方法"); show1(); } public void show1(){ System.out.println("父类Person2的show1方法"); } } class Student2 extends Person2{ public void show(){ //super.show1(); System.out.println("子类Student2的show方法"); } public void show1(){ System.out.println("子类Student2的show1方法"); } } public class OverrideDemo1 { public static void main(String[] args) { Person2 p = new Person2(); p.show(); } }

在这里插入图片描述

父类对象调用父类的show方法,哪怕方法体中有 show1(); 也是调用父类自己的方法,而不是子类重写后的。

在子类用super调用父类的show1方法也一样,方法体中的 show1(); 语句会自动跳转到子类的show1()方法

package test; class Person2{ public void show(){ System.out.println("父类Person2的show方法"); show1(); } public void show1(){ System.out.println("父类Person2的show1方法"); show1(); } } class Student2 extends Person2{ public void show(){ super.show1(); System.out.println("子类Student2的show方法"); } public void show1(){ System.out.println("子类Student2的show1方法"); } } public class OverrideDemo1 { public static void main(String[] args) { Student2 s = new Student2(); s.show(); } }

在这里插入图片描述

不过有一点要记住的是,super调用父类的show,show1方法后,这两个方法都被执行了,里面的内容会被打印,不过是方法体中的 show1(); 语句会跳转到子类的show1方法

从上面的这个结果也能看出来, super.show1(); 调用了父类的show1方法,打印了 “父类Person2的show1方法” 这句话。然后父类show1方法中的 在这里插入图片描述 语句调用了子类的show1方法,打印了 “子类Student2的show1方法这句话” 最后继续执行子类的show方法剩下的方法体部分,打印 “子类Student2的show方法” 这句话

一个例子 package test1; public class Demo1 { class Father{ int num = 11; Father(){ System.out.println("父类构造器"); show(); } void show(){ System.out.println("父类的show方法,并且num的值为"+num); } } class Son extends Father{ //int num = 22; Son(int i){ num = i; System.out.println("子类构造器"); show(); } void show(){ System.out.println("子类的show方法,并且num的值为"+num); } } public static void main(String[] args) { Demo1 d = new Demo1(); d.new Son(10); System.out.println("=============="); d.new Father(); } }

在这里插入图片描述 在调用子类构造器之前,会先初始化父类的构造器,所以第一句话打印的是*“父类构造器”*

父类构造器里面通过 show(); 调用了子类的show()方法,此时子类的构造器还没有初始化,所以是继承父类的num值,num值为11。所以第二句是*“父类的show方法,并且num的值为11”*

父类构造器初始化完毕之后,才开始执行子类的构造器,所以打印第三句,”子类构造器“

之后子类构造器自己调用自己的show方法,并且num值变成了创建对象时传入的值10,所以第四句话是*”子类的show方法,并且num的值为10”*

总结一下 子类调用构造方法时,不论是有参还是无参构造,都是默认访问父类的无参构造方法 父类构造方法中的语句执行完毕后,才会执行子类构造方法中的语句 (可以用super(参数列表)的方式,改变要先初始化的父类构造方法)子类调用构造方法,初始化父类时,父类的构造方法会调用子类重写后的重名方法子类用super调用父类方法时,父类方法会调用子类重写后的重名方法父类自身调用构造方法和普通方法时,都是访问自身的方法,不会访问子类的同名方法

我写了一段比较绕的代码当最后总结的例子

package review; class Father{ public int age = 30; { System.out.println("父类构造代码块"); } public Father(){ System.out.println("父类无参构造方法"); Show(); } public void Show(){ System.out.println("父类的方法一"); Show2(); } public void Show2(){ System.out.println("父类的方法二"); } } class Son extends Father{ { System.out.println("子类的构造代码块"); } public Son(){ System.out.println("子类的无参构造方法"+"---"+age); } public Son(int age){ System.out.println("子类的有参构造方法"+"---"+age); } public void Show(){ System.out.println("子类的方法一"); super.Show2(); } public void Show2(){ System.out.println("子类的方法二"); } } public class extendsDemo { public static void main(String[] args) { Son s = new Son(10); System.out.println("---------"); Father f = new Father(); } }

在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有