写优雅代码之聊一聊继承2

来源:互联网 发布:after effects mac版 编辑:程序博客网 时间:2024/06/05 00:52

在阅读spring源码的时候,发现了一个关于继承的非常有意思的现象,按照常理,在继承链上,子类是完全继承了父类的方法的.那么使用super关键字调用父类的时候,会首先调用到它的直接父类中.但有一种情况,子类没有override父类的某个方法,会导致最底层的类直接调用到它的超类中,我写了一个demo,先来看一下继承图


从继承图中,我们可以看到,儿子继承男人,男人继承人.

接下来我们来定义People类

package com.lazy.demo;public abstract class People {//定义了一个age属性private String age;//实现get方法public String getAge() {return age;}//实现set方法public void setAge(String age) {this.age = age;System.out.println("我在People类中setAge");}//定义一个具体的run方法public void run() {System.out.println("我在People类中跑起来!");}//定义一个抽象的say方法,钩子方法protected abstract void say();}
定义Man类

package com.lazy.demo;public class Man extends People {@Override//重写父类的run方法public void run() {System.out.println("我先进入到了Man类中");super.run();}@Override//重写父类的say方法protected void say() {System.out.println("我在Man类中说: 我29岁了!");}//未重写父类的age属相的get与set方法}

定义Son类

package com.lazy.demo;public class Son extends Man {@Override//重写父类的say方法protected void say() {super.say();}//定义一个setAge方法,在方法体内通过super关键字想调用父类的setAge方法public void setAge() {super.setAge("29");}//定义一个run方法,在方法体内通过super关键字调用父类的run方法public void run() {super.run();}}
测试1,测试Son类中的setAge方法

package com.lazy.demo;public class Test {public static void main(String[] args) {//实例化Son对象Son son = new Son();//通过Son对象的引用son,调用Son中定义的setAge方法son.setAge();}}
运行结果



看到这个现象,有趣吧!在Son类的父类Man类中,我们并没有重写People类中的setAge方法,但是在Son类中,我们通过super关键字,居然不是调用到父类中,而是调用到了超类(People)的setAge方法中.当然,这只是个小知识点,不足为奇,在spring的源码中,就有这种写法,读懂这个小程序,能为我们读spring的源码省下一些气力. so,路要一步一步走,饭要一口一口吃.只有掌握了扎实的基础,才能让自己的内功大增.

测试2,测试Son类中的run方法

package com.lazy.demo;public class Test {public static void main(String[] args) {//实例化Son对象Son son = new Son();//通过Son对象的引用son,调用Son中定义的run方法son.run();}}
运行结果


由于Man类中重写了People类中的run方法,所以在Son类中run方法中,通过super关键字调用父类的run方法,会首先调用的Man类中的run方法,Man类中的run方法又通过关键字调用到People类中的run方法,这不足为奇,符合我们的预期.

测试3.测试Son类中的say方法

package com.lazy.demo;public class Test {public static void main(String[] args) {//实例化Son对象Son son = new Son();//通过Son对象的引用son,调用Son中定义的say方法son.say();}}
运行结果


Man类中,我们重写了People类中的say方法,但是在People类中的say方法体中,并没有通过super关键字在往上调用People类中的say方法,而且在People类中的say方法是一个抽象方法,我们也不可以通过关键字去调用,否则编译器都会报错.所以,在Son类中的say方法中,只可通过super关键字调用到在People类中定义的抽象方法say方法的实现类,也就是Son类的直接父类.


小结: 

1.通过以上例子,我们看到了面向对象的精华--多肽的一些影子

2.类可以被单继承,但可以不重写某些方法,这样一来,在子类中,通过关键字super调用父类的方法,会直接进入到超类中

3.public protected方法,可以层层继承下来,也可以在底层通过super关键字,层层调用上去



原创粉丝点击