动手动脑(三)

继承条件下的构造方法调用

运行下面代码,观察输出,注意总结父类与子类之间构造方法的调用关系修改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)接口多态:使用接口代替抽象基类。



 

posted @   万事胜意k  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示