抽象类不能实例化,用于定义必须由子类实现的抽象成员,同时可包含具体实现,强制契约并共享代码,适用于“is-a”关系和需部分实现的场景。

C#中的
abstract
定义抽象类很简单,你只需要在
class
abstract
abstract
abstract
抽象类的核心特性:
new
override
如何定义一个抽象类和抽象成员:
// 定义一个抽象类
public abstract class Vehicle
{
// 抽象属性:所有车辆都有一个抽象的马力,具体数值由子类决定
public abstract int Horsepower { get; set; }
// 抽象方法:所有车辆都有一个启动引擎的方法,但具体启动方式不同
public abstract void StartEngine();
// 非抽象方法:所有车辆都有一个通用的显示信息方法
public void DisplayInfo()
{
Console.WriteLine("This is a vehicle.");
}
// 抽象类可以有构造函数,供子类调用
public Vehicle()
{
Console.WriteLine("Vehicle constructor called.");
}
}
// 继承抽象类并实现抽象成员
public class Car : Vehicle
{
private int _horsepower;
// 实现抽象属性
public override int Horsepower
{
get { return _horsepower; }
set { _horsepower = value; }
}
// 实现抽象方法
public override void StartEngine()
{
Console.WriteLine("Car engine started with a roar!");
}
public Car(int hp)
{
Horsepower = hp;
}
}
// 另一个子类
public class Motorcycle : Vehicle
{
private int _horsepower;
public override int Horsepower
{
get { return _horsepower; }
set { _horsepower = value; }
}
public override void StartEngine()
{
Console.WriteLine("Motorcycle engine sputtered to life.");
}
public Motorcycle(int hp)
{
Horsepower = hp;
}
}在实际应用中,当我需要定义一组紧密相关的类,它们共享一些公共特性和行为,但某些特定行为又必须由每个具体子类自行实现时,我通常会考虑使用抽象类。它提供了一个很好的平衡点:既能共享代码,又能强制实现特定接口。
我们之所以需要抽象类,很大程度上是因为它帮助我们更好地进行面向对象设计,尤其是在构建复杂系统时。在我看来,抽象类就像是设计蓝图中的“半成品”——它规定了框架,但把一些关键的、多变的细节留给具体的实现者。
核心原因:
Logger
LogInfo()
LogError()
FileLogger
DatabaseLogger
Shape
Circle
Rectangle
Shape
Shape
BaseController
实际应用场景:
Stream
Read
Write
FileStream
NetworkStream
BuildReport
GenerateHeader()
GenerateBody()
GenerateFooter()
CreateFullReport()
BaseRepository
Add()
GetById()
Update()
UserRepository
ProductRepository
Employee
FullTimeEmployee
PartTimeEmployee
EventHandler
HandleEvent()
LoginEventHandler
OrderCreatedEventHandler
总的来说,抽象类是我在设计软件架构时一个非常趁手的工具。它让我能在高层次上定义行为规范,同时又能在低层次上提供具体的实现,从而在灵活性和强制性之间取得一个恰到好处的平衡。
抽象类和接口都是实现多态和面向对象设计的重要工具,但它们的设计哲学和使用场景有着明显的区别。我常常把它们比作两种不同类型的“合同”。
核心区别:
public
protected
public
我的选择策略:
在实际开发中,选择抽象类还是接口,往往取决于你想要表达的设计意图和具体的需求。
选择抽象类:
Car
Motorcycle
Vehicle
protected
private
选择接口:
Dog
Robot
IMovable
Student
IComparable
IDisposable
我的经验是:
很多时候,抽象类和接口并非互斥,它们可以协同工作。一个抽象类可以实现一个或多个接口,从而既能提供部分共享实现,又能遵守多个行为契约。例如,一个抽象的
BaseRepository
IRepository<T>
override
抽象方法和虚方法都是C#中实现多态性的重要机制,它们都允许子类修改或定义基类的行为。然而,它们在定义、目的和强制性上存在显著差异。
抽象方法(Abstract Method):
abstract
override
virtual
abstract
virtual
虚方法(Virtual Method):
virtual
override
什么时候用override
override
实现抽象方法时: 当你的类继承了一个抽象类,并且这个抽象类中定义了抽象方法时,你必须在你的子类中使用
override
public abstract class Printer
{
public abstract void PrintDocument(string document); // 抽象方法,无实现
}
public class LaserPrinter : Printer
{
public override void PrintDocument(string document) // 必须使用 override 实现
{
Console.WriteLine($"Laser Printer printing: {document}");
}
}重写虚方法时: 当你的类继承了一个包含虚方法的基类时,如果你想改变基类提供的默认行为,那么你必须使用
override
以上就是C#的abstract关键字是什么意思?怎么定义抽象类?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号