本文以个人对抽象类和接口的理解为阐述重点,不妥之处拍砖之余请给予指正,共同学习共同进步。
1. 什么是抽象类和接口
· 抽象类是由abstract修饰的在实现内容上没有完全定义的类class,可以包含方法的声明而没有实现,当然也可以定义实现。关键在于“抽象”意义。
public abstract class General
{
// 抽象类可以有自己的数据成员
private const string Name = "Abstract General";
public string MyName
{
get
{
return Name;
}
}
// 抽象方法
public abstract void Fun();
// 虚方法,含有默认行为
public virtual void FunSecond()
{
Console.WriteLine("This is a abstract general class");
}
// 共有方法
public void FunThird()
{
Console.WriteLine("This is a common function");
}
}
· 接口interface则是一种完全没有实现的类,可以说它是一种契约,更是一种规范,用于约束类的行为,实现它的类必须实现接口的所有成员。关键在于“约束”意义。
interface IGeneral
{
// 没有实现
int Fun();
void FunSecond();
void FunThird();
}
2. 抽象类和接口究竟有什么区别
二者都不能被实例化创建自己的实例。
· 一个类只能继承自一个抽象类。但可以继承多个接口,接口不受类的单重继承的限制。
· 抽象类有自已的数据成员还可以赋予方法默认行为。接口则不能含有成员变量和实体方法,所有的方法均是隐式的被public和abstract修饰。
3. 什么时候用抽象类,什么时候用接口
接口是为了满足外部调用而定义的一个功能约定,反映的是事物的外部特性;抽象类是从一系列相关对象中抽象出来的概念,反映的是事物的内部共性。从这句话我们只要掌握一点就够了,抽象类多用于一组相似相关的事物的抽象,而接口多用于不相关的事物间的功能约束。请看下面这个例子:
我们知道奔驰、宝马、保时捷都有轮子,颜色之类的属性,都有启动和停止的功能操作。因此我们可以抽象一个车的类,可以将轮子的个数,颜色作为这个类的成员变量,启动和停止作为它的两个方法。由于抽象类不能被实例化,你要一个车我给不了,但是你要一个具体的车比如大奔、宝马我能给你。如果有一个“发出声音”的动作,宝马、麻雀、人都可以,这些东东够不相干的了吧,这个时候我们就可以将“发出声音”放在接口里定义了,无论你是麻雀还是小汽车,只要是继承了这个接口,就必须实现“发出声音”。
public abstract class Car
{
// 车轮数目
public int numOfCar;
// 车身颜色
public Color ColorBody;
// 启动
public abstract void Start();
// 停止
public abstract void Stop();
// 共有方法
public void CommonFun()
{
Console.WriteLine("This is a abstract car");
}
}
interface IGeneral
{
// 发出声音
void Call();
}
4. 为什么需要抽象类和接口,二者能互代替
· 接口是抽象类的变体,是一个特殊的抽象类。一般可以代替特殊,在不考虑多继承的情况下单从语法上来说,抽象类是可以代替接口的。但是由于抽象类可以定义成员变量和部分实现方法,接口通常不能代替抽象类。
· 通过接口,可以指定组件必须实现的方法,但不实际指定如何实现方法,更多地起到约束的作用。抽象类使您可以创建行为的定义,同时提供用于继承类的一些公共实现,可以认为抽象类是对类的抽象就像类是对对象的抽象一样,是更高一级的抽象,更多的起到抽象意义。
· 利用接口编程能够降低代码的藕合度,带来诸多好处,同时也是官方倡导的一种编程方式。可参阅相关资料。
补充:
接口中只可以包含方法、属性、索引指示器和事件,不能包含常量、字段、构造函数、静态成员等(接口成员默认访问方式是public,不能包含任何修饰符,比如不能加abstract,public,protected,internal,private,virtual,override 或static等)。