区别在于抽象类支持状态存储、访问修饰符和多重继承的替代,而接口仅定义契约且支持多实现。具体做法是:若需共享代码或维护内部状态,使用抽象类;若需实现多态组合或跨层级契约,使用接口。

抽象类如何管理内部状态
抽象类可以包含字段、属性和构造函数,从而在实例化前初始化数据。例如,定义一个 Animal 抽象类,其中包含 Name 字段,子类通过构造函数传入值并赋值给该字段,确保所有派生对象都拥有唯一标识。

public abstract class Animal
{
public string Name { get; set; }
protected Animal(string name)
{
Name = name;
}
public abstract void Speak();
}
public class Dog : Animal
{
public Dog(string name) : base(name) { }
public override void Speak() => Console.WriteLine($"{Name} says: Woof!");
}
运行上述代码时,创建 Dog 实例会调用基类构造函数,Name 被正确赋值为 "Buddy",输出结果为 "Buddy says: Woof!"。这证明抽象类能封装状态。
接口如何实现多态组合
接口不能包含实现细节(C# 8.0 默认方法除外),但允许一个类实现多个接口,从而打破单继承限制。例如,定义 IDrinkable 和 IEatable 接口,让 Human 类同时实现两者,展示灵活的行为组合。

public interface IDrinkable
{
void Drink();
}
public interface IEatable
{
void Eat();
}
public class Human : IDrinkable, IEatable
{
public void Drink() => Console.WriteLine("Drinking water.");
public void Eat() => Console.WriteLine("Eating food.");
}
执行 human.Drink() 和 human.Eat() 分别输出对应文本。由于 Human 未继承任何类,它可自由扩展其他功能,体现接口的解耦优势。
当接口方法无实现时如何处理
若接口方法未在实现类中提供逻辑,编译器将报错。例如,移除 Human 中的 Drink 方法体,会导致编译错误,提示必须实现所有接口成员。这强制开发者明确行为,避免空壳类。











