Java学习笔记Java 杂谈

对interface及抽象类的理解

2016-11-04  本文已影响70人  淋雨仔

接触Java已经有一段时间了,接口和抽象类也到处在用,用着用着就习惯了,也没去想接口和抽象类到底应该怎么用。
什么是接口,什么是抽象类,不需要Google,连百度都一大堆。什么是接口?
其实这些书上都讲过,可能也都举过例子。但是就我自己来说,我看完教科书对接口的描述,并不是很懂,虽然我很清楚怎么用,甚至用的很好,却就是不知道怎么描述。


我为什么突然想要去了解他,而不是反正我现在用的好好的,只要会用就行了。我记得我当时在看设计模式,工厂方法和抽象工厂,对于接口突然产生了疑问,当时我举了一个这样的例子(第一种写法)

interface Food {    
}

interface Cook {    
    Food cook();
}

厨师可以做出食物,厨师和食物都是接口

class Dumpling implements Food {
}

class ChineseFoodChef implements Cook {
    @Override
    public Food cook() {    
        return new Dumpling();
    }
}

中国厨师做饺子,并没有什么错,跑的好好的。但是有没有觉得,Cook和Food其实作为抽象类更符合逻辑一点,所以我这样写,直接用抽象类(第二种写法)

abstract class Food {
}

class Dumpling extends Food {    
}

abstract class Cook{
    public abstract Food cook();
}

class ChineseFoodChef extends Cook {    
    @Override    
    public Food cook() {        
        return new Dumpling();    
    }
}

或者下面这种(第三种写法)

interface Eatable {    
}

abstract class Food implements Eatable{
}

class Dumpling extends Food {    
}

interface CanCook {    
    Eatable cook();
    //Food cook();
}

abstract class Cook implements CanCook{
    public abstract Food cook();
}

class ChineseFoodChef extends Cook {    
    @Override    
    public Food cook() {        
        return new Dumpling();    
    }
}

这样是不是符合逻辑多了,但是代码也变多了。然后接下来需求变了,多了一类人,教师。另外我妈妈是教师,并且会做菜。说简单一点就是,我妈妈是一个会做饭的教师。所以按照第一种写法

interface Teacher {
    void teach();
}

class MyMonther implements Teacher,Cook {
    @Override 
    public void teach() {
    }

    @Override 
    public Food cook() { 
        return null; 
    }
}

感觉上表达出来的意思是,我妈妈是一个教师也是一个厨师,或者我妈妈会教书也会做菜,也并没有什么错。然后第二种写法

abstract class Teacher{
    public abstract void teach();
}

class MyMonther extends Teacher {
    @Override 
    public void teach() {
    }

    public Food cook() { 
        return null; 
    }
}

因为不能继承两个父类,所以只能自己另外加一个方法。然后第三种写法

interface CanTeach { 
    void teach();
}

abstract class Teacher implements CanTeach { 
}

class MyMonther extends Teacher implements CanCook{ 
    @Override 
    public void teach() {
     } 

    @Override
    public Food cook() { 
        return null; 
    }
}

第三种是不是更符合要表达的意思,我妈妈是一个会做菜的教师。不过对于上面的题材三种写法都可以,现在用下面这些(鸟,鸵鸟,麻雀,飞机,会飞的)

interface 鸟 {
    void 飞();
}

class 鸵鸟 implements 鸟 {
    @Override 
    public void 飞() { 
    }
}

class 麻雀 implements 鸟 {
    @Override 
    public void 飞() { 
    }
}

class 飞机 implements 鸟 {
    @Override 
    public void 飞() { 
    }
}

看到这里其实显而易见,用一类事物的抽象名词作为接口名是很不符合逻辑的,鸵鸟是鸟但不会飞,飞机会飞但不是鸟。所以其实这类名词用抽象类是最符合的

abstract class 鸟 { 
    public abstract void 飞();
}

class 鸵鸟 extends 鸟 { 
    @Override 
    public void 飞() {
    }
}

class 麻雀 extends 鸟 { 
    @Override 
    public void 飞() { 
    }
}

abstract class 飞机  { 
    public abstract void 飞();
}

class 波音747 extends 飞机 {
    @Override 
    public void 飞() { 
    }
}

于是,鸵鸟还是会飞?exm?鸟和飞机有一样的方法,多写一遍不累么?所以接口的价值就体现出来了

interface 会飞的 {
    void 飞();
}

abstract class 鸟 { 
}

class 鸵鸟 extends 鸟 { 
   //鸵鸟是鸟但不会飞
}

class 麻雀 extends 鸟 implements 会飞的{ 
    @Override 
    public void 飞() { 
    }
}

abstract class 飞机 implements 会飞的{ 
}

class 波音747 extends 飞机 { 
    @Override 
    public void 飞() { 
    }
}

其实接口就像一个可以灵活拆装的组件,你想让猪飞,只要给它装个会飞的接口就行了,你想让你的爸妈会做饭,给他们装个会做饭的接口就好了,哈哈哈


以上就是我的理解,不敢说不服来辩,如果有好的见解希望可以一起讨论。觉得多个例子对比着来应该比单个举例效果要好,最近也在断断续续的看设计模式,也会写一写自己的理解,一方面写下来能让自己的理解更深刻甚至产生新疑问,另一方面也是为了能和大神们分享讨论(感觉大神们都应该不需要看我这么浅显的理解=。=)

上一篇下一篇

猜你喜欢

热点阅读