顺便做个记录
接口和抽象类应该是Java语法中最常见的两个概念
关于两者,网上也是一搜一吨的对比,总体如下:
1,抽象类的成员可以具有访问级别 接口的成员全部public级别2,抽象类可以包含字段 接口不可以
3,抽象类可以继承接口 接口不能继承抽象类
4,抽象类的成员可以具有具体实现 接口不行
5,抽象的子类可以选择性实现其基类的抽象方法 接口的子类必须实现
6,接口是抽象类的一种特例!
概念虽然简单
不过到具体使用场景中,什么情况下用抽象类,什么情况下用接口呢,很多人却搞不明白
下面我举个例子
有一个Door,里面有方法open()和方法close()
我们要把他抽象出来,形成一个类,可以有下面两种方法
1,抽象成抽象类,如下
abstract class Door{
void open() {}
void close(){}
}
interface Door{
void open();
void close();
}
看起来两者好像没啥区别,现在我们要加一个功能,门铃功能
没啥问题,那就加上
1,抽象类
abstract class Door{
void open() {}
void close(){}
void bilibili(){}
}
2,接口
interface Door{
void open();
void close();
void bilibili();
}
那么问题来了,所有门都有开关门功能,是不是所有的门都有门铃呢?
那不是所有的实现Door的类都得具有门铃方法?
所以,我们应该把门铃理解成一种附件,一种Attach,可以加到门上面的一种点缀
对于这种附件形式的类,我们就可以用接口来表示
所以,啥叫接口,就是在门上凿出一个门铃大小的洞,用来放门铃的,就跟电脑上的usb接口一样,一个洞嘛!
我们就可以这样来定义铃声这样一个接口
interface Ring{
void bilibili();
}
这样定义Door这个类
abstract class Door{
void open() {}
void close(){}
}
这样,如果有一个铃铛的门,可以这样来写:
class DoorWithRing extends Door implements Ring{
public void bilibili() {
// TODO Auto-generated method stub
}
}
如果是一个没有铃铛的门
class DoorWithRing extends Door{
}
买个猫眼:
interface CatEye{
void see();
}
class DoorWithRingAndCatEye extends Door implements Ring,CatEye{
public void see() {
// TODO Auto-generated method stub
}
public void bilibili() {
// TODO Auto-generated method stub
}
}
一个门上可以打无数的洞,也就是可以实现多个接口!
有人会问,门铃,猫眼,这些东西不也是类吗,为啥不做成类,做成接口呢?
对的,当然可以做成一个正常的类,有他的属性什么的,这样猫眼,门铃和门的关系就变了,变成聚合关系了,不是组合,因为门没了门铃和猫眼还是门,这些基本的概念有机会再延伸吧
所以,对于那种功能单一(响铃,看人),又需要拿来作为一个附件附加到基本类上的类,我们就把它定义成接口
ok!