Abstract Class
在C++中,有纯虚函数的类是抽象类,抽象类不能被实例化,只能作为基类使用,里面的纯虚函数就是其子类必须实现的接口,所以虚基类也叫做接口类。也就是说,抽象类只能通过接口和作为其它类的基类使用,写法如下所示:
class ExampleCPlusPlus
{
public:
virtual void fun1() = 0; //纯虚函数
virtual void fun2(int) = 0; //纯虚函数
}
在C#中,抽象类与C++的抽象类基本相同,不可被实例化,只能作为接口和其它类的基类使用。只是写法略有不同:
C#的抽象类需要添加关键字abstract,写法如下所示:
abstract class Geometry
{
public abstract int Area(); // 两个abstract 都不能少
}
class Square : Geometry
{
int x, y;
public override int Area() // 继承抽象类的函数,需要用overide表明这是复写的函数
{
return x * y;
}
}
C#中除了抽象类,还提供了一项功能,叫做接口,对应关键字为interface
,C++中没有相应的功能,C++的”接口“都是通过虚基类或者基于虚基类的宏实现的。
C#中的接口类似一个Class,相当于是一种协议,里面声明了一些函数,继承该接口的所有类都要遵守这个协议,简单理解,就是每一个类都要定义这个协议里面提到的函数。
举个例子:
// 定义一个接口协议,Interface的名字前面一般以I开头
interface IProtocol
{
void Function1();
void Function2();
}
// 类A是一个必须遵循协议的类
class A : IProtocol
{
// Function1 必须为public,否则会报错
public void Function1()
{
System.Console.WriteLine("I have to define this function1");
}
// Function2 必须为public,否则会报错
public void Function2()
{
System.Console.WriteLine("I have to define this function2");
}
}
值得注意的是,这里具体在子类定义协议函数的时候,必须指定函数类型为public,否则会报错,“提示该类无法实现接口成员,因为它不是公共的”,为什么会有这种设定呢,可以看下面这个例子。
interface ISomeWork
{
void doYourWork();
}
public class A : ISomeWork
{
public void doYourWork()
{
//...
}
}
public class B : ISomeWork
{
private void doYourWork()
{
//...
}
}
void Main()
{
List<someI> workers = getWorkers();
foreach(var worker in workers)
worker.doYourWork();
}
最后会发现Class B的成员虽然继承了接口,但是由于是private的函数,导致无法调用。
如果不想使用public类型,只允许通过ISomeWork接口来进行访问,可以这么写:
public class B : ISomeWork
{
//直接定义该接口在此类中的函数
void ISomeWork.doYourWork()
{
//...
}
}
// 可以通过这种方式调用
static void Main(string[] args)
{
List<someI> workers = getWorkers();
foreach(var worker in workers)
{
worker.doYourWork(); // 错误,无法获取该函数
((ISomeWorkd)worker).doYourWork(); // 正确
}
}
最后介绍一个关键字sealed
,sealed
的本意是密封的意思,C#中的sealed
可以用来修饰类和方法,sealed
修饰的类不允许被继承,sealed
修饰的方法不允许被override,sealed
关键字不可以修饰抽象类,因为抽象类本来就是虚基类,以供继承用的,如下图所示,抽象类不可能是static
或sealed
属性: