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

在阅读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关键字,层层调用上去



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值