抽象类
C++
为了让一个类成为抽象类,至少必须有一个纯虚函数。包含至少一个纯虚函数的类视为抽象类。
纯虚函数形式如下:
virtualreturntypefunction()=0;
例如,类A有两个纯虚函数lock()、unlock()和一个
虚析构函数
:
classA
public:
virtualvoidlock(void)=0;
virtualvoidunlock(void)=0;
virtual~A(void);
将函数lock()和unlock()初始化为0使它们成为纯虚函数,没有0这个初使化器,它们仅仅是虚函数。
classB:publicA
protected:
pthread_mutex_tx;
public:
B(void);
~B(void);
virtualvoidlock(void)
ead_mutex_lock(x);
virtualvoidunlock(void)
ead_mutex_unlock(x);
抽象类对于提供模式、蓝图和后代类遵循的原则有用,如果遵循了蓝图的语义,后代类的行为可能按抽象类提供者和使用者所期望的那样。
通过使用抽象类,C++程序员可以提供C++组件的规范,在它的构建中指导组件的实现者。
抽象类
C#
抽象类提供多个派生类共享基类的公共定义,它既可以提供抽象方法,也可以提供非抽象方法。如果派生类没有实现所有的抽象方法,则该派生类也必须声明为抽象类。另外,实现抽象方法由overriding方法来实现。
定义方法为:
///
///定义抽象类
abstractpublicclassAnimal
//定义静态字段
staticprotectedint_id;
//定义属性
publicabstractstaticintId//在抽象方法声明中不能使用static或virtual修饰符
//定义方法
publicabstractvoidEat();
//定义索引器
publicstringthis[inti]
get;//必须声明主体,因为它未标记为abstract、extern或partial
///实现抽象类
publicclassDog:Animal
publicstaticoverrideintId
get{return_id;}
set{_id=value;}
publicoverridevoidEat()
Console.Write("DogEats.")
抽象类Java
假设在问题领域中有一个关于Door的抽象概念,该Door具有执行两个动作open和close,此时可以通过abstract class或者interface来定义一个表示该抽象概念的类型,定义方式分别如下所示:
使用abstract class方式定义Door:
abstractclassDoor{
abstractvoidopen();
abstractvoidclose();
使用interface方式定义Door:
interfaceDoor{
voidopen();
voidclose();
其他具体的Door类型可以extends使用abstract class方式定义的Door或者implements使用interface方式定义的Door。就此看来,使用abstract class和interface没有大的区别。
但如果需求要求Door还要具有报警的功能,就能得出差别。既然open、close和alarm属于两个不同的概念,根据
ISP
原则应该把它们分别定义在代表这两个概念的抽象类中。
对于问题领域的理解是:AlarmDoor在概念本质上是Door,同时它有具有报警的功能。说明它又能够完成报警概念中定义的行为,所以报警概念可以通过interface方式定义。如下所示:
abstractclassDoor{
abstractvoidopen();
abstractvoidclose();
interfaceAlarm{
voidalarm();
class Alarm Door ext ends Doorimp lements Alarm{
voidopen(){…}
voidclose(){…}
voidalarm(){…}
这种实现方式基本上能够明确的反映出对于问题领域的理解,正确的揭示设计意图。
在面向对象方法中,抽象类主要用来进行类型隐藏。构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类。模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允许修改的;同时,通过从这个抽象体派生,也可扩展此模块的行为功能。为了能够实现面向对象设计的一个最核心的原则
OCP
(Open-Closed Principle),抽象类是其中的关键所在。