C# interface和abstract class

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(); // 正确
        }
}          

最后介绍一个关键字sealedsealed的本意是密封的意思,C#中的sealed可以用来修饰类和方法,sealed修饰的类不允许被继承sealed修饰的方法不允许被overridesealed关键字不可以修饰抽象类,因为抽象类本来就是虚基类,以供继承用的,如下图所示,抽象类不可能是staticsealed属性:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/alexhu2010q/article/details/105519353