Java中的继承使用关键字extends ,跟C#的语法略有差别。
java会自动在子类的构造器中插入对父类构造器的调用,也就是说在子类可以访问父类之前已经完成了父类的初始化。
如果想调用带参数的父类构造器,应该使用super关键字。
<a></a>
我们创建一个Bread类的实例,看看调用顺序。
打印结果:
[Product constructor]
[Bread constructor]
子类是不能直接访问到父类的私有域的,如果想访问只能借助父类公开的get访问器。子类调用父类中的方法也需要使用super关键字。
然后写个单元测试:
需要说明一点,super并不是一个对象的引用,不能将super赋值给变量,它只是一个特殊的关键字,告诉编辑器要调用父类中的方法。
如果父类中存在重载方法,子类又进行了重载,会覆盖父类中的方法吗?实际上,父类和子类中的方法都可以正常重载,不会被覆盖。
首先在父类Product中添加方法getDescription():
然后在子类中重载该方法:
增加一个单元测试:
输出:
[Product]name=豆沙面包
[Bread]storename=味多美
继承准则:尽量少用继承。一般用继承表达行为间的差异,用组合表示状态上的变化。
在Java中对象变量是多态的,一个Product变量可以引用Product对象,也可以引用一个Product子类的对象。
由于Bread实例向上转型为Product类型,所以不能再调用Bread.getDescription(String storeName)方法。
如果需要将父类强制转换为子类时,要先通过instanceof检测对象类型,我们最好尽量避免使用强制类型转换。
所谓动态绑定,就是在运行时根据对象的类型决定要调用的方法。在java中,动态绑定是默认行为,不需要添加额外的关键字实现多态。
再写个demo来看一下,在父类和子类中重载了display方法。
添加单元测试:
虚拟机为每个类创建一个方法表,列出所有方法的签名和实际调用的方法。这样一来,当动态调用方法的时候,只需要查找方法表就能快速的找到真正调用的方法了。
Product:
display()->Product.display()
Bread:
display()->Bread.display()
display(String name)->Bread.display(String name)
定义抽象方法用用abstract关键字,它仅有声明而没有方法体。
包含抽象方法的类叫做抽象类,如果一个类包含一个或多个抽象方法,那么必须被定义为抽象类。
如果一个类从抽象类继承,那么必须为抽象类中的所有抽象方法提供实现,否则该类也必须被定义为抽象类。
看一个场景:我们有一些定时任务,要进行的工作流程类似,只有具体一部分细节内容不同。我们可以定义一个抽象基类BaseJob,再不同的部分封装为抽象方法,具体的实现在子类中进行。
创建单元测试,调用ArticleJob看看。
运行结果:
当再次添加符合该流程的定时任务时,只需要新建一个类,实现BaseJob就可以了。
本文转自 陈敬(Cathy) 博客园博客,原文链接:http://www.cnblogs.com/janes/p/8309741.html,如需转载请自行联系原作者