继承条件下的构造方法调用
运行下面代码,观察输出,注意总结父类与子类之间构造方法的调用关系修改Parent构造方法的代码,显式调用GrandParent的另一个构造函数,注意这句调用代码是否是第一句,影响重大!
1 class Grandparent 2 { 3 4 5 public Grandparent() 6 { 7 8 System.out.println("GrandParent Created."); 9 10 } 11 public Grandparent(String string) 12 { 13 14 System.out.println("GrandParent Created.String:" + string); 15 16 } 17 18 } 19 class Parent extends Grandparent 20 { 21 22 23 public Parent() 24 { 25 26 super("Hello.Grandparent."); 27 28 System.out.println("Parent Created"); 29 30 //super("Hello.Grandparent."); 31 32 } 33 34 } 35 36 37 38 class Child extends Parent 39 { 40 41 42 public Child() 43 { 44 45 System.out.println("Child Created"); 46 47 } 48 49 } 50 51 52 53 public class TestInherits 54 { 55 56 57 public static void main(String args[]) 58 { 59 60 Child c = new Child(); 61 62 } 63 64 }
运行结果:
若打开Parent方法中下方的super,会报错
结论: 通过 super 调用基类构造方法,必须是子类构造方法中的第一个语句。
为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来?
构造函数主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。不能反过来,子类继承了父类所有的对象和成员变量,子类肯定要先初始化,才能正确使用父类的对象和成员变量。父类并不知道会有什么子类,也不知道子类有什么特殊的对象和成员变量,无法提前初始化。
子类与父类方法间的关系
由于Java并未对子类方法的命名做过多的限制,因此,子类与父类各自定义的方法之间,可以出现以下三种情况 扩充(Extends):子类定义的方法父类没有同名 覆盖/重写(Override):子类父类定义了完全一样的方法 重载(Overloads):子类有父类的同名方法,但两者的参数类型或参数数目不一样。
运行以下代码,展示程序运行结果并解释为什么会得到这样的输出
1 public class ParentChildTest { 2 public static void main(String[] args) { 3 Parent parent=new Parent(); 4 parent.printValue(); 5 Child child=new Child(); 6 child.printValue(); 7 8 parent=child; 9 parent.printValue(); 10 11 parent.myValue++; 12 parent.printValue(); 13 14 ((Child)parent).myValue++; 15 parent.printValue(); 16 17 } 18 } 19 20 class Parent{ 21 public int myValue=100; 22 public void printValue() { 23 System.out.println("Parent.printValue(),myValue="+myValue); 24 } 25 } 26 class Child extends Parent{ 27 public int myValue=200; 28 public void printValue() { 29 System.out.println("Child.printValue(),myValue="+myValue); 30 } 31 }
运行结果:
结论:当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。 如果子类被当作父类使用,则通过子类访问的字段是父类的!
多态的好处:
通过在编程中应用多态,可以使我们的代码具有更强的适用性。当需求变化时,多态特性可以帮助我们将需要改动的地方减少到最低限度。
多态编程有两种主要形式: (1)继承多态 (2)接口多态:使用接口代替抽象基类。
标签:Parent,子类,动脑,printValue,动手,Child,父类,public From: https://www.cnblogs.com/ysk0904/p/16807902.html