接口与抽象类的的应用. 面向接口的编程, 以接口为引用变量.
OO基础: 抽象,封装,多态,继承
OO原则:
1. 封装变化
2. 多用组合 , 少用继承
3. 针对接口编程,不针对实现编程
OO模式:
策略模式(Strategy Pattern)--定义算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户.
"一族算法" == "一组行为"
类与类之间的关系 IS-A(是一个), HAS-A(有一个) 或 IMPLEMENTS(实现).
简单的模拟鸭子应用
Joe 上班的公司做了一套相当成功的模拟鸭子游戏: 游戏中会出现各种鸭子,一边游泳戏水,一边呱呱叫.此系统的内部设计使用了标准的OO技术,设计了一个鸭子超类(Suparclass),并让各种鸭子继承此超类.
现在有需求 : 给鸭子 加上fly() 方法 有的 鸭子会飞 有的不会飞.
1. 显然在 Duck 类中加入 fly() 方法是不好的. 因为需要 重写fly()方法 代码太多. 子类不会飞的鸭子代码需为空 重复性太高.
2. 利用接口?
看起来不错. 但 每个子类依旧需要实现 fly() 方法.
3. 把行为抽取出来做为接口
public interface Fly{
public void fly();
}
----------- Fly接口 的实现类 "行为类"
public class FlyWithWings implements Fly{
public void fly(){
System.out.println(" I'm Flying !!"); //这是飞行行为的实现,给"真会"飞的鸭子用
}
}
---------- Fly接口 的实现类 "行为类"
public class FlyNoWay implements Fly{
public void fly(){
System.out.println(" I can't fly "); //这是飞行行为的实现,给"不会"的鸭子用
}
}
在 Duck 类中存在其引用变量 Fly 及 setFly()方法
public abstract Duck{
public Fly fly;
public setFly(Fly fly){ //这里是个接口 具体实现类可以是 FlyNoWay or FlyWithWings
this.fly = fly;
}
}
-----
public class RedDuck extends Duck{
//继承其父类属性
//写一个飞行的方法
public void preFly(){
fly.fly() // fly 是从父类中继承而来(接口内有fly()方法) . 在运行中 通过 setter 方法 为其赋予 真正的实现类.
}
}
最后 动态的给鸭子赋予 飞行 技能(会飞或 不会飞的)
public class Test{
public static void main(String[] args){
Duck readDuck = new RedDuck();
readDuck.setFly(new FlyNoWay() ); //现在是不会飞鸭子.
readDuck. perFly(); //输出的为 I'm can't fly
}
}
策略模式(Strategy Pattern)--定义算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户.
有些头疼 写得比较乱. 总结一下.
把行为方法抽取出来 如 fly() 方法 为接口类 Fly, (然后写其实现类 会飞 或 不会飞 的类 ) (这就是把行为抽取出来为类) //对应上面的 "定义算法族,分别封装起来"
在 抽象类 Duck中 有其(Fly 接口)接口引用. 在运行时为其动态赋值.(贱得值是 Fly接口的实现类) //对应上面的 "让它们之间可以互相替换"
面向接口 编程