曾经对这两个概念的理解止于abstract class里可以有成员变量,可以有非抽象的方法,而interface中的成员变量必须是static,final的,而且没有非抽象的方法。
其实,他们还有更深层次的含义。
有这样一个需求,要实现一个门的实例,可以有两种方法定义这个抽象概念:
abstract class Door{
abstract void open();
abstract void close();
}
interface Door{
void open();
void close();
}
完工。可老板看着不满意,又要再加个需求,说我要能报警的门,可以这样实现:
abstract class Door{
abstract void open();
abstract void close();
abstract void alarm();
}
interface Door{
void open();
void close();
void alarm();
}
似乎有点不对,是报警是门特有的属性吗,答案当然是否定的,这就违反了ISP(Interface Segregation Principle)接口隔离原则。我们可以将报警功能抽象为另外一个抽象类或者接口,不过由于Java不支持多继承的机制,只能用接口定义了:
abstract class Door{
abstract void open();
abstract void close();
}
interface Door{
void open();
void close();
}
interface Alarm{
void alarm();
}
这样,具有报警功能的门就有两种方法实现了:
class AlarmDoor extends Door implements Alarm{
void open(){..};
void close(){..};
void alarm(){..};
}
class AlarmDoor implements Door ,Alarm{
void open(){..};
void close(){..};
void alarm(){..};
}
Java中继承表示“is a”的关系,接口表示“like a”的关系,弄清楚这两个关系,在我们定义抽象概念的时候就有所选择了。第一种方法表示,这是一个门,且有报警功能;第二种方法表示,这个对象既有门的特点,又有报警功能。
引用
这种实现方式基本上能够明确的反映出我们对于问题领域的理解,正确的揭示我们的设计意图。
引用
abstract class和interface是Java语言中的两种定义抽象概念的方式,它们之间有很大的相似性。但是对于它们的选择却又往往反映出对于问题领域中的概念本质的理解、对于设计意图的反映是否正确、合理,因为它们表现了概念间的不同的关系(虽然都能够实现需求的功能)。
PS:abstract method 不能是static,native,synchronized的