继承条件下的构造方法调用
输出结果为
首先构造基类。通过 super 调用基类构造方法,必须是子类构造方法中的第一个语句。
为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来?
答:子类的构造方法在运行之前必须调用父类的构造方法,是因为子类继承了父类的属性和方法,所以在子类构造方法中必须先初始化父类的成员变量和方法。不能反过来,因为子类继承了父类的属性和方法,如果不先初始化父类的成员变量和方法,那么子类在使用父类的属性和方法时就会出现问题,因为这些属性和方法没有被正确初始化。此外,父类可能还有一些必要的操作需要在子类构造方法之前进行,如资源的分配和初始化等。因此,为了确保子类对象的正确创建和使用,必须先调用父类的构造方法。
1 package org.example; 2 3 class Parent 4 5 { 6 7 public int value=100; 8 9 public void Introduce() 10 { 11 12 System.out.println("I'm father"); 13 14 } 15 16 17 } 18 19 class Son extends Parent 20 { 21 22 public int value=101; 23 24 public void Introduce() 25 { 26 27 System.out.println("I'm son"); 28 29 } 30 31 } 32 33 34 class Daughter extends Parent 35 { 36 37 public int value=102; 38 public void Introduce() 39 { 40 41 System.out.println("I'm daughter"); 42 43 } 44 45 } 46 47 public class Main 48 { 49 50 51 public static void main(String args[]) 52 { 53 54 Parent p=new Parent(); 55 56 p.Introduce(); 57 58 System.out.println(p.value); 59 60 p=new Son(); 61 62 p.Introduce(); 63 64 System.out.println(p.value); 65 66 p=new Daughter(); 67 68 p.Introduce(); 69 70 System.out.println(p.value); 71 72 73 } 74 75 76 }
执行结果。
I'm father
100
I'm son
100
I'm daughter
100
在这段代码中,我们定义了一个父类Parent和两个子类Son和Daughter。父类Parent有一个成员变量value和一个方法Introduce,子类Son和Daughter分别有一个自己的成员变量value和方法Introduce。
在主方法中,我们首先创建了一个Parent对象p,并调用了p的Introduce方法和打印了p的value值。由于p是一个Parent对象,所以调用的是父类Parent的方法和访问的是父类Parent的value值,输出结果为"I'm father"和100。
接下来,我们将p的引用指向一个Son对象,并再次调用p的Introduce方法和打印p的value值。由于p指向的是Son对象,所以调用的是子类Son的方法和访问的是子类Son的value值。然而,由于Son类中没有重写父类的value变量,所以访问的仍然是父类Parent的value值,输出结果为"I'm son"和100。
最后,我们将p的引用指向一个Daughter对象,并再次调用p的Introduce方法和打印p的value值。同样地,由于p指向的是Daughter对象,所以调用的是子类Daughter的方法和访问的是子类Daughter的value值。然而,由于Daughter类中也没有重写父类的value变量,所以访问的仍然是父类Parent的value值,输出结果为"I'm daughter"和100。
总结:在Java中,父类和子类对象中的成员变量和方法的访问方式取决于对象的实际类型。当父类引用指向子类对象时,调用的是子类的方法,但是访问的是父类的成员变量。这是因为成员变量是根据对象的声明类型来访问的,而方法是根据对象的实际类型来调用的。所以,无论p引用指向什么类型的子类对象,访问的都是父类Parent的value值。
下面代码输出为
I'm father
100
I'm son
101
I'm daughter
102
1 package org.example; 2 3 import com.sun.xml.internal.bind.annotation.OverrideAnnotationOf; 4 5 class Parent 6 7 { 8 9 public int value=100; 10 11 public void Introduce() 12 { 13 14 System.out.println("I'm father"); 15 16 } 17 18 19 } 20 21 class Son extends Parent 22 { 23 24 public Son() { 25 super(); // 调用父类的构造方法 26 value = 101; // 给父类的value赋予新的值 27 } 28 29 public void Introduce() 30 { 31 32 System.out.println("I'm son"); 33 34 } 35 36 } 37 38 39 class Daughter extends Parent 40 { 41 public Daughter() { 42 super(); // 调用父类的构造方法 43 value = 102; // 给父类的value赋予新的值 44 } 45 public void Introduce() 46 { 47 48 System.out.println("I'm daughter"); 49 50 } 51 52 } 53 54 public class Main 55 { 56 57 58 public static void main(String args[]) 59 { 60 61 Parent p=new Parent(); 62 63 p.Introduce(); 64 65 System.out.println(p.value); 66 67 p=new Son(); 68 69 p.Introduce(); 70 71 System.out.println(p.value); 72 73 p=new Daughter(); 74 75 p.Introduce(); 76 77 System.out.println(p.value); 78 79 80 } 81 82 83 }
标签:Java,Parent,子类,动脑,value,动手,Introduce,父类,public From: https://www.cnblogs.com/litianyu1969/p/17760732.html