接口 interface
Definition: An interface is a named collection of method definitions, without implementations.
接口是一组没有实现的方法的集合
问题的由来:
Animal 类
Canine 类 继承Animal
Dog 类 继承Canine
Animal 类
Feline 类 继承Animal
Cat 类 继承Feline
如果要是需要Dog 加上撒娇和耍宝的功能呢
1 解决办法直接修改Dog类,增加pet()需要的方法
问题如果cat类也要有pet功能怎么办呢?
下面方法是那些可以在Petshop程序中重用现有的类
方法1 把宠物的方法加入到Animal 类中
优点:马上就好了
缺点 河马也是宠物?也会撒娇?
方法2 把宠物的方法设定成抽象的加入到Animal 类中
优点:非宠物的类的动物覆盖的时候什么也不做,是宠物的作出正确的行为
缺点 所有的具体动物都要实现宠物的行为,降低了代码的重用性
方法3 把宠物的方法加入到DOG 类中(需要的地方)
优点:不必担心河马的亲热行为了
缺点 失去了合约保证(方法的名称,返回值),多态无法保证,因为Animal不会有共同的宠物行为,得针对不同的宠物去设计程序。
我们真正需要的是:
1 让宠物的行为只能应用到宠物的身上
2 确保所有宠物类都有相同的方法定义的方法
3 一种可以运行到多态的方法
解决办法:
增加pet类,dog类在继承Canine类(animal子类)的同时继承pet类,这样就有了pet的行为
java 不支持多重继承
原因:“致命方块”
eg: DigitalRecorder burn()方法
CDBurner extends DigitalRecorder override burn()
DVDBurner extends DigitalRecorder override burn()
ComboDriver extends DVDBurner ,CDBurner 这个时候要是调用burn()方法到底是调用的那个父类的方法呢?
情况会非常的糟,增加了程序的复杂性。:“致命方块”
这个时候接口就出现了!!!(interface)
接口解决了多重继承的问题的同时又不会产生“致命方块” 这样的问题
接口的解决办法就是把所有的方法都设为抽象的。子类必须实现所有的方法
问题: 接口并不能真正的多重继承,因为他的里面无法实现程序代码
首先接口保证了多态!
不管你来自那里,只有实现了这个接口,别人就知道你一定会履行这个合约,接口只是一个抽象的层次,好的设计不需要在抽象层次
定义出具体实现。让细节在具体的子类上面实现吧。
要如何判断应该是设计类,子类,抽象类或者接口
新的类无法对其他类通过is-a的测试时候,不继承其他类
在需要某类的特殊化版本的时候以覆盖或者增加新的方法来继续现有的类
当需要定义一群子类的模板,又不想让程序员初始化的时候,谁叫抽象类
如果想要定义类可以扮演的角色,使用接口(dot实现了pet接口)
在接口中所有的方法都必须是 public的
Illegal modifier for the interface method testAble.test(); only public & abstract are permitted
子类调用父类的方法可以用super.xx()来实现
接口和抽象类的区别是很明显的
an abstract class. The differences are significant.
- An interface cannot implement any methods, whereas an abstract class can.
- A class can implement many interfaces but can have only one superclass.
- An interface is not part of the class hierarchy.
- Unrelated classes can implement the same interface.
Warning! Interfaces Cannot Grow
如果想给你的接口增加功能,你新增加了一个方法
public interface StockWatcher { void valueChanged(TickerSymbol tickerSymbol, BigDecimal newValue); void currentValue(TickerSymbol tickerSymbol, BigDecimal newValue); }
所有实现了这个接口的人都会抱怨的
避免这种情况的话,就是使用接口的继承
public interface StockTracker extends StockWatcher { void currentValue(TickerSymbol tickerSymbol, BigDecimal newValue); }