????????抽象类和接口是C#“封装、继承、多态”三大特性中比较重要的组成部分。抽象类和接口这两种类型用于完全不同的目的。抽象类主要用作对象的基类,贡献某些主要的特性,例如共同的目的和结构。接口则主要是用于类,为这些类去添加不同的方法(行为)。下面分别对它们的概念,代码定义,特点区别,应用场景进行说明。
????????抽象类是一种不能被实例化的类,用于作为其他类的基类。它可以包含抽象方法、非抽象方法、字段、属性等成员,用于定义一种通用的类结构和行为,而具体的实现则留给其派生类来完成。
????????接口是从抽象类演变而来的,接口是一种定义了一组方法、属性、事件或索引器的规范,用于描述类应该具有的行为和功能。类可以实现一个或多个接口,从而遵循接口定义的规范。
????????抽象类在C#中通过abstract关键字来声明。
internal abstract class Animal
{
//抽象属性声明不提供属性访问器的实现,它声明该类支持属性,而将访问器实现留给派生类
public abstract double height { get; }
//普通属性
public double weidth { get; set; }
//普通字段
public double age;
//抽象方法
public abstract void Run();
//普通方法
public void Eat()
{
Console.WriteLine("Animal can eat.");
}
//虚方法,子类继承重写
public virtual void Move()
{
Console.WriteLine("Animal can move.");
}
}
internal class Dog : Animal
{
private double _height;
public override double height
{
get => _height;
}
public Dog()
{
_height = 200;
}
//抽象方法子类必须重写
public override void Run()
{
Console.WriteLine("Dog can run.");
}
//虚方法子类可以重写也可单继承
public override void Move()
{
Console.WriteLine("Animal move by leg.");
}
}
void Main()
{
Dog dog = new Dog();
Animal animal = dog;
animal.weidth = 50;
animal.age = 10;
animal.Run();
Console.WriteLine($"Dog's age->{dog.age},width->{dog.weidth},height->{dog.height}");
Console.ReadLine();
}
? ?运行结果为:
Dog can run.
Dog's age->10,width->50,height->200
????????接口在C#中通过interface
关键字来声明。
public interface FlyInterface
{
//属性
string Name { get; }
//委托和事件
event EventHandler Clicked;
void Fly();
void Move();
}
public interface RunInterface
{
void Run();
void Move();
}
//可以继承多个接口
internal class Plane : FlyInterface, RunInterface
{
public string Name => "Play";
public event EventHandler Clicked;
/*如果类实现两个接口且两个接口包含具有相同签名的成员,
显示接口实现是通过使用接口名称和一个句点命名该类成员来进行实现*/
void FlyInterface.Move()
{
Console.WriteLine("Plane move by fly.");
}
void RunInterface.Move()
{
Console.WriteLine("Plane move by run.");
}
public void Fly()
{
Console.WriteLine("Plane can Fly.");
}
public void Run()
{
Console.WriteLine("Plane can Run.");
}
}
void Main()
{
Plane plane = new Plane();
FlyInterface fly = plane;
fly.Fly();
fly.Move();
RunInterface run = plane;
run.Run();
run.Move();
Console.ReadLine();
}
? ?运行结果为:
Plane can Fly.
Plane move by fly.
Plane can Run.
Plane move by run.
在选择使用抽象类还是接口时,需要根据具体的情况选择:
1、接口可以用于定义事件和委托的契约,使不同类能够统一实现事件和委托的处理
2、C#虚方法和抽象方法的区别
参考: