熟悉抽象类、接口等。
我不清楚为什么有人会创建一个没有抽象成员的 C# 抽象类?(C# 编译器允许这样做)。
例子:
public abstract class House
{
public void OpenDoor()
{
Console.WriteLine("Door opens");
}
}
熟悉抽象类、接口等。
我不清楚为什么有人会创建一个没有抽象成员的 C# 抽象类?(C# 编译器允许这样做)。
例子:
public abstract class House
{
public void OpenDoor()
{
Console.WriteLine("Door opens");
}
}
您可能需要一个共同的基础来访问以引用,以便您可以处理许多不同类型的房屋的列表。你可以有一个List<House>
,其中一些可能是BrickHouse
其他WoodenHouse
的,但打开门的功能对于所有房子都是一样的,所以把这个方法放在基础上是有意义的。如果实例化该类没有意义,则声明基本抽象。
仅仅因为:你期望子类化吗?
也许在这种情况下,House
根本不够具体;当然,这种关系中的所有事物都是house,但它期望具体类型,例如Bungalow
, Mansion
,Apartment
等...因此House
可以作为有用的分类(例如,在 aList<House>
或 type 的属性中House
)-但您永远不会期望具有该公共基本类型的实际实例。
我可以想象某些平台(可能在公司中)可能会定义一个抽象类,程序员应该子类化以便可以在以后的版本中添加方法?
只是为了自动为他们实现一些东西,例如提供一个默认实现GetHashCode
,或者也许ToString
. 此外,它允许您将方法添加到抽象类实现的接口,提供默认实现,然后什么都不会中断,而不是每个类都中断并且您必须手动修复所有这些的其他选项。
有趣的是,static classes
在 C# 中实际上是sealed
和abstract
一个。这种情况的目的很明确:只允许声明静态方法。
概括
抽象类可以是概念上的“接口”。这与 .NET 接口不同。一个通用的接口示例是:
// List that accepts the conceptual interface
List<Car> cars = new List<Car>();
// Specialized instance that will be added to the list
Car myCar = new Toyota();
cars.Add(myCar);
遗产
您可以实现多个接口,但只能从一个抽象类继承。这可以是类库的开发人员做出的设计决定。
用法
Dhananjay写了一篇关于用法的好文章。他指出抽象类用于对类层次结构进行建模。然而,接口用于通信。该对象实际上是无关紧要的。
这样基类就定义了实现。如果实现在所有派生类中都是通用的,那么将其保留在抽象类中而不复制派生类中的代码是有意义的。
看到这个链接,有一些关于这个http://www.codeproject.com/Articles/6118/All-about-abstract-classes的有用信息
通常,基类仅用于提供通用功能。根据您的设计,可以在不依赖成员的情况下实现此通用功能。在这种情况下,子类通常不需要任何公共成员。在您的示例中House
,对象类用于简单的操作,我假设您不需要房屋的任何常见状态,例如楼层数、墙壁类型(木头、砖块等)。看到这样一个类让我想“好吧,这个类没有保存对象的任何状态。它只是执行一些动作”
抽象类,根本上更像是一个逻辑类来继承而不是把它作为继承的基础,你可以用抽象类告诉所有从它继承的人有一个特定的属性或特定的方法去做,接口可以正是这样做。
假设我有一个哺乳动物类,但哺乳动物类只是一个抽象类,没有真正的动物属于哺乳动物,尽管有许多动物(包括人类)继承了它的“属性”。
同样,抽象使用绝对取决于开发人员的选择。
具有抽象成员的抽象类旨在以多态方式使用。如果您想与子类共享公共方法,甚至可能是特定的构造序列(例如让抽象类的构造函数进行“家务管理”的设置),则将使用仅具有具体成员的抽象类。
它是一种比多态子类更弱的耦合形式,我想不出我自己曾经遇到过它。
抽象类用作模板(可能会或可能不会提供默认实现),而孩子可以覆盖他不喜欢的任何内容,或其他方法/属性/等。
一个非常有趣的场景是类型约束继承:
public abstract class MyClass
{
public void DoSomething()
{
Console.WriteLine("blah blah");
}
}
public class MyClass<T>: MyClass
{
public T GetSomething()
{
// return null as T;
}
}
您可能会看到默认实现位于基类中。