接触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 飞() {
}
}
其实接口就像一个可以灵活拆装的组件,你想让猪飞,只要给它装个会飞的接口就行了,你想让你的爸妈会做饭,给他们装个会做饭的接口就好了,哈哈哈
以上就是我的理解,不敢说不服来辩,如果有好的见解希望可以一起讨论。觉得多个例子对比着来应该比单个举例效果要好,最近也在断断续续的看设计模式,也会写一写自己的理解,一方面写下来能让自己的理解更深刻甚至产生新疑问,另一方面也是为了能和大神们分享讨论(感觉大神们都应该不需要看我这么浅显的理解=。=)
网友评论