从java看 is-a, has-a, is-like-a

从语法的角度上来讲

is-a代表继承,也就是extends,继承完整实现的类或者用abstract修饰的类(子类需要实现abstract修饰的方法)
has-a代表组合,设计模式中多次推崇组合好处大于继承,这里组合就是指成员变量类型是其他类
is-like-a代表的是 拥有、像某个行为,和继承最大的不同,is-like-a仅仅对某一种行为进行继承,java中使用interface

从使用角度来看

public abstract class Person {
    public void run() {
        hand();
        feet();
    }
    public void toStPrint() {
        System.out.println("Person has hand feet");
    }

    public abstract void hand();
    public abstract void feet();
}
``
    抽象Person类,要实现的就是一个人来做事情,使用手和脚进行搭配,通过子类的继承实现
    多说一点,abstract默认就是public,也只能是public
    java的这种把接口和抽象类分开的机制很好,c++中就全靠自觉了,并且c++中virtual是可以有实现的,c++中使用 virtual = 0实现java的abstract
    如果使用接口

public interface Persion1 {
public abstract void run();
public abstract void toStPrint();
public abstract void hand();
public abstract void feet();
}

   注意的是,接口中的public abstract可以省略,看出区别来没,接口其实就是对抽象的进一步抽象,只不过接口要求更严格,这里讨论静态方法(public static的方法)、默认方法(default的方法)、静态变量(public static修饰的变量)
   接口中仅仅定义的函数,子类需要一一进行实现
   上面来看很明显是abstract更优,使用abstract作为主导,interface作为附加,abstract是必须有的,比如人的手和脚,但是接口不是必须的比如赚钱的数量。
   1.自己实现的类中应该是abstract为主体,interface为附加
   2.对于给第三方提供的调用接口那肯定提供的是接口,因为第三方不关心实现,只关心调用
   3.套用设计模式的道理,变量的类型不能是具体类,应该是其抽象的父类
   4.不应该覆盖父类的方法,如果这样说明你的父类不够抽象,方法不是集中提取的
   5.不要让类派生自具体的类,那样会存在依赖关系
   6.必要的时候使用依赖倒置,现有很多的人,那么你想人的动作是否可以抽象出一个类进行给外界共同调用?
##从编译器角度看
   其实编译器进行的是类型检查,如果是abstract就看abstract修饰的方法是否正确
   如果是interface就看interface修饰的方法是否正确,interface是特殊的abstract
##解耦
   其实解耦最大的目的,就是让代码之间不需要彼此依赖,一般解耦的基础都是多态,所以我们一旦定义的抽象类中的函数那就是给外界调用的,使用抽象类的引用实现这个类的功能就好了
上一篇:10、Strategy 策略模式 整体地替换算法 行为型模式


下一篇:java学习:组合和聚合之间的区别