java编程思想-继承中的多态及相关思考

多态的基本概念

关于多态的理解,属于面向对象的基本概念,这里简单举个教科书中可能经常采用的经典的例子描述一下:
public class Animal {
	public Animal() {}
	public void walk() {
		System.out.println("Animal walk way");
	}	
}

public class Dog extends Animal {
	public Dog() {}
	
	public void walk() {
		System.out.println("Dog walk way");
	}
	public static void main(String[] args) {
		Animal dog = new Dog();
		dog.walk();
	}
}
 这里调用dog.walk()的时候,虽然声明的dog类型是Animal,但是运行时类型为Dog。而因为继承的关系,在执行的时候是按照 运行时类型执行,也就是这里调用的是Dog类的walk方法,而不是Animal类的walk方法。这就是多态的思想, 对象表现为运行时类型的特征,而可以以超类的方式声明它。

为什么要设计多态

为了软件复用和可扩展性。
在上面的例子中,我们如果在其他的类中有一个函数:buy(Animal a),这个函数的参数是Animal类型的,而我们可以向其中传入任何继承自Animal类的子类的实例,当我们增加另一个类如Bird、Cat等的时候,我们就不需要为每一个新添加的类另外新增加buy方法了,原来的buy(Animal a)函数依旧可以使用,因为多态的原因,传入其中的参数会在运行时表现出不同的walk特性,完全可以满足系统的需求,从而减少了代码的冗余。这就是设计多态的原因。
基于接口的编程模式中,我们需要尽可能forget about object type,而更多的基于接口编程,这里多态的设计就是基于超类“接口”Animal进行编程,而不用为每一个具体的derived class进行编程。

多态实现的原理

多态是通过何种方式实现的?
这里我们需要了解方法调用(method call)是如何与定义方法的方法体(method body)绑定起来的。有两种方式:
1)early binding.
2) dynamic binding or late binding. 

第一种在程序运行之前就已经将方法调用和方法体绑定,实施者是编译器或者链接器。C 编译器只有一种绑定方式,即early binding。
第二种在编译时是无法知道具体应该调用什么method的,而需要等到程序运行时(run-time)根据对象的运行时类型来确定调用的是哪个方法体。进一步理解,就是编译器不能确定对象的具体类型,由方法调用机制在运行时确定对象的具体类型并调用合适的方法体。这种dynamic binding是由实现了这个机制的语言自动执行的,你不需要去做任何处理。
在java中,static和final是没有late binding的,在编译时就已经确定了,因此final method可以一定程度上优化java程序的performance,但是效果有限,所以还是建议给予设计的原因使用final method,而不是给予性能调优的原因。
几个注意点:
  1. 只有普通的方法调用才具有多态的特性,public field是不具有多态的特性的,当然private就更不可能具有了(隐式final嘛)。这里的理解是,如果将子类upcast成父类类型,然后通过父类类型变量访问public field,那么编译器就会在编译时确定。因此访问field时是根据声明类型来的确定具体访问的是哪个对象的field的
  2. static methods are associated with the class, and not the individual objects,即静态方法不具有多态特性,实在编译时就已经确定好的。实际上,静态对象是与类相关联的,而不是run-time时的对象,因此不难理解静态方法的调用时根据声明类型确定的

继承vs组合

Thinking in Java 中的观点是:Use inheritance to express differences in behavior, and fields to express variations in state
在你不知道该使用什么的时候,首先选择composition,因为它简单易于扩展并且不会带来不必要的麻烦设计和考虑。当你确实需要在行为上有不同的表现方式,并且确定有超类-子类的关系时,才是使用inheritance的时机。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值