什么是接口和抽象类
- 接口和抽象类都是“软件工程产物”
- 具体类→抽象类→接口:越来越抽象,内部实现的东西越来越少
- 抽象类是未完全实现逻辑的类(可以有字段和非public成员,它们代表了“具体逻辑”)
- 抽象类为复用而生:专门作为基类来使用,也具有解耦功能
- 封装确定的,开放不确定的,推迟到合适的子类中去实现
- 接口是完全未实现逻辑的“类”(“纯虚类”;只要函数成员;成员全部public)
- 接口为解耦而生:“高内聚,低耦合”,方便单元测试
- 接口是一个“协约”,早已为工业生产所熟知(有分工必有协作,有协作必有协约)
- 它们都不能实例化,只能用来声明变量、引用具体类(concrete class)的实例
例子:
/*
* 为做基类而生的“抽象类”与“开放/关闭原则”
*/
class Program
{
static void Main(string[] args)
{
Vehicle v = new Truck();
v.Stop();
v.Run();
//如果Vehicle中没有定义Run(),则此处不能调用Run()
/*
* Vehicle v2 = new Vehicle();
* 程序会报错,抽象类没有方法体的实现
*/
}
}
abstract class Vehicle //改为抽象类
{
public void Stop()
{
Console.WriteLine("Stoded!");
}
public void Fill()
{
Console.WriteLine("Pay and fill...");
}
public abstract void Run();
//此处的Run()没有方法体,所以要把virtual改为abstract,同时类也要改为抽象类
}
class Car : Vehicle
{
public override void Run()
{
Console.WriteLine("Car is runing...");
}
}
class Truck : Vehicle
{
public override void Run()
{
Console.WriteLine("Truck is runing...");
}
}
使用纯抽象类:
class Program
{
static void Main(string[] args)
{
Vehicle v = new Truck();
v.Stop();
v.Run();
}
}
//纯抽象类
abstract class VehicleBase
{
abstract public void Stop();
abstract public void Fill();
abstract public void Run();
}
abstract class Vehicle : VehicleBase
{
public override void Stop()
{
Console.WriteLine("Stoded!");
}
public override void Fill()
{
Console.WriteLine("Pay and fill...");
}
}
class Car : Vehicle
{
public override void Run()
{
Console.WriteLine("Car is runing...");
}
}
class Truck : Vehicle
{
public override void Run()
{
Console.WriteLine("Truck is runing...");
}
}
用接口代替纯抽象类:
class Program
{
static void Main(string[] args)
{
Vehicle v = new Truck();
v.Stop();
v.Run();
}
}
//接口
interface IVehicle
{
void Stop();
void Fill();
void Run();
//接口本身就包含了它是纯抽象类的含义,所有的成员一定都是抽象的
//所以abstract public都要求去掉,避免重复
}
abstract class Vehicle : IVehicle
//接口下推一级,抽象类作为一个不完全的实现,拿不完全的实现的抽象类作为基类,去创建具体类
{
public void Stop()
//因为接口中去掉了所以abstract,所以在实现的过程中override也要去掉
//这里就变成了类去实现接口
{
Console.WriteLine("Stoded!");
}
public void Fill()
{
Console.WriteLine("Pay and fill...");
}
abstract public void Run();
//Run()没有实现,需要保留Run(),下推给后面去实现
}
class Car : Vehicle
{
public override void Run()
{
Console.WriteLine("Car is runing...");
}
}
class Truck : Vehicle
{
public override void Run()
{
Console.WriteLine("Truck is runing...");
}
}