c#接口_抽象类_多态学习
c#接口_抽象类_多态学习
学习日志
关于:c#接口_抽象类_多态的学习记录。
一、概念
1. 多态(Polymorphism)
- 定义:同一操作作用于不同对象时,表现出不同的行为。
- 实现方式:
- 继承 + 方法重写(
override
)。 - 接口实现。
- 父类引用指向子类对象。
- 继承 + 方法重写(
internal abstract class Animal{}
internal class Dog : Animal{}
Animal myDog = new Dog(); // 多态:父类引用指向子类对象
2. 抽象类(Abstract Class)
- 定义:不能被实例化的类,用于定义部分实现并强制子类完成特定行为。
Animal animal = new Animal(); ❌ 错误 CS0144: 无法创建抽象类的实例
- 核心语法:
- 抽象方法没有实现,子类必须重写。
- 可以包含具体方法(用
virtual
允许子类重写)。
- 适用场景:
- 需要共享公共代码逻辑。
- 强制子类实现某些方法。
internal abstract class Animal
{// 抽象方法:没有实现,子类必须重写public abstract void MakeSound(); // 具体方法:子类可直接继承或重写public virtual void Move(){Console.WriteLine("Animal is moving.");}
}// 子类 Dog 必须实现 MakeSound()
internal class Dog : Animal
{public override void MakeSound() //必须重写抽象方法{Console.WriteLine("Dog says: Woof!");}
}#### 抽象方法 internal abstract class Animal
{// 抽象方法:没有实现,子类必须重写public abstract void MakeSound(); protected virtual void DoSomeThing(){MakeSound();}protected void HearSomeThing(){MakeSound();}// 具体方法:子类可直接继承或重写public virtual void Move(){Console.WriteLine("Animal is moving.");}
}// 子类 Dog 必须实现 MakeSound()
internal class Dog : Animal
{protected override void DoSomeThing(){base.DoSomeThing();}public override void MakeSound() //必须重写抽象方法{Console.WriteLine("Dog says: Woof!");}
}
Dog mydog=new Dog();
mydog.DoSomeThing();
> Dog says: Woof!mydog.HearSomeThing();
> Dog says: Woof!
3. 接口(Interface)
- 定义:纯行为契约,定义类必须实现的方法和属性(C# 8.0 前不包含实现)。
- 核心语法:
- 默认成员为
public
。 - C# 8.0+ 支持默认实现和访问修饰符。
- 默认成员为
- 适用场景:
- 定义跨类别的能力(如
IFlyable
接口可被Bird
和Plane
实现)。 - 解决单继承限制(一个类可实现多个接口)。
- 定义跨类别的能力(如
public interface Animal {void makeSound();
}// ❌ 错误:接口不能直接实例化
Animal animal = new Animal(); // 编译错误!
二、抽象类_接口_多态对比
特性 | 抽象类 | 接口 | 多态 |
---|---|---|---|
核心目标 | 代码复用 + 强制子类实现 | 定义行为契约 | 统一调用不同对象的行为 |
默认实现 | 支持 | C# 8.0+ 支持默认实现 | 不直接相关 |
继承/实现 | 单继承(一个子类只能继承一个) | 多实现(一个类可实现多个接口) | 依赖继承或接口实现 |
方法修饰符 | abstract (必须重写)、virtual (可选重写) | 隐式 public (C# 8.0 前) | override (重写父类/接口方法) |
典型场景 | 定义“是什么”(is-a)关系 | 定义“能做什么”(can-do)关系 | 动态调用不同子类/实现类的行为 |
三、代码示例
1. 抽象类与多态(三层继承)
// 抽象基类
internal abstract class Vehicle {public abstract void Start(); // 必须实现public virtual void Stop() => Console.WriteLine("Stopping..."); // 可选重写
}// 子类 Car
internal class Car : Vehicle {public override void Start() => Console.WriteLine("Key start"); // 必须实现public override void Stop() => Console.WriteLine("Brake stop"); // 重写
}// 孙子类 ElectricCar
internal class ElectricCar : Car {public override void Start() => Console.WriteLine("Button start"); // 重写// 不重写 Stop(),使用 Car 的版本
}
2. 接口与多态
// 接口定义
internal interface IPayment {void Pay(decimal amount);
}// 实现类
internal class Alipay : IPayment {public void Pay(decimal amount) => Console.WriteLine($"Alipay: {amount}");
}internal class WeChatPay : IPayment {public void Pay(decimal amount) => Console.WriteLine($"WeChat: {amount}");
}// 多态调用
List<IPayment> payments = new List<IPayment> { new Alipay(), new WeChatPay() };
foreach (var payment in payments) {payment.Pay(100); // 同一方法,不同实现
}
四、其他
1. 什么是否使用 抽象类 或者 接口
-
用抽象类:
- 需要共享公共代码或字段。
- 强制子类实现某些方法,同时提供部分默认实现。
- 典型场景:
Vehicle
→Car
→ElectricCar
。
-
用接口:
- 定义无关类的共同能力(如
IFlyable
),但是方法名称相同。 - 需要多继承(如一个类实现
IRunnable
和ISwimmable
)。 - 典型场景:支付系统(
IPayment
)。
- 定义无关类的共同能力(如
2. 多态的最佳实践
- 通过父类或接口引用操作对象:
Animal animal = new Dog(); animal.MakeSound(); // 调用 Dog 的实现
- 利用集合统一管理不同对象:
List<Vehicle> vehicles = new List<Vehicle> { new Car(), new ElectricCar() }; foreach (var vehicle in vehicles) vehicle.Start(); // 不同子类不同行为
3. 多层继承中的方法重写规则
- 子类必须实现父类的抽象方法(除非子类也是
abstract
)。 - 子类可以重写
virtual
方法,或选择不重写(沿用父类实现)。 - 孙子类可重写父类已实现的方法(需父类方法标记为
virtual
)。
4. 注意事项
- 接口的默认实现(C# 8.0+)应谨慎使用,避免破坏接口的契约性。
- 避免过度继承:三层以上继承可能导致代码复杂,优先考虑组合或接口。
- 命名规范:接口名称以
I
开头(如IEnumerable
),抽象类以Base
或Abstract
结尾(可选)。