Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么定义没有抽象成员的C#抽象类_C#_Oop_Design Patterns - Fatal编程技术网

为什么定义没有抽象成员的C#抽象类

为什么定义没有抽象成员的C#抽象类,c#,oop,design-patterns,C#,Oop,Design Patterns,我熟悉抽象类、接口等 我不清楚的是,为什么有人会创建一个没有抽象成员的C#抽象类? (C#编译器允许这样做) 例如: public abstract class House { public void OpenDoor() { Console.WriteLine("Door opens"); } } 概括 抽象类可以是概念上的“接口”。这与.NET接口不同。 通用接口示例如下: // List that accepts the conceptual in

我熟悉抽象类、接口等

我不清楚的是,为什么有人会创建一个没有抽象成员的C#抽象类? (C#编译器允许这样做)

例如:

public abstract class House
{
    public void OpenDoor()
    {
        Console.WriteLine("Door opens");
    }
}
概括

抽象类可以是概念上的“接口”。这与.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);
//接受概念接口的列表
列出车辆=新列表();
//将添加到列表中的专用实例
Car myCar=新丰田();
cars.Add(myCar);
继承权

您可以实现多个接口,但只能从一个抽象类继承。这可以是类库开发人员做出的设计决策

用法


写了一篇关于用法的好文章。他指出抽象类用于建模类层次结构。然而,接口用于通信。对象是否实际是无关紧要的。

原因很简单:您需要将其子类化吗


也许在这种情况下,
House
就是不够具体;当然,这种关系中的所有东西都是房子,但它需要具体的类型,如
平房
豪宅
公寓
,等等。。。因此,
House
可以作为一种有用的分类(例如,在
列表中,或者在
House
类型的属性中)-但是你永远不会期望有一个实际的公共基类型的实例。

我可以想象某个平台(可能在公司中)是否可以定义一个抽象类程序员应该创建子类,以便在以后的版本中添加方法?

您可能需要一个公共基础来访问以引用,这样您就可以处理许多不同类型房屋的列表。你可以有一个
列表
,其中一些可以是
砖房
其他的
木屋
,但是打开门对所有的房子都有相同的功能,所以把方法放在底部是有意义的。如果实例化该类没有意义,则可以声明基抽象。

以便基类定义实现。如果实现在所有派生类中都是通用的,那么将其保留在抽象类中而不是复制派生类中的代码是有意义的

请参阅此链接,了解一些关于此的有用信息

只是为了为他们自动实现一些东西,因此,例如,提供
GetHashCode
的默认实现,或者可能提供
ToString
。此外,它还允许您向抽象类实现的接口添加一个方法,提供一个默认实现,然后什么都不中断,而不是使用另一个选项,在该选项中,每个类都中断,您必须手动修复所有这些类。

抽象类,更多的是要继承的逻辑类,而不是将其用作继承的基本类,您可以使用抽象类来告诉所有从中继承的人要执行特定的属性或方法, 接口可以做到这一点

假设我有一个哺乳动物类,但哺乳动物类只是一个抽象类,没有真正的哺乳动物,尽管有许多动物(包括人类)从中继承“属性”


同样,抽象的使用完全取决于开发人员的选择。

带有抽象成员的抽象类意味着要以多态方式使用。如果您想与子类共享公共方法,甚至可能是特定的构造序列(比如让抽象类的构造函数进行“内务管理”设置),则可以使用只包含具体成员的抽象类


它是一种比多态子类更弱的耦合形式,我想不出有哪一次我自己遇到过它。

抽象类充当模板(可能提供也可能不提供默认实现),而child可以覆盖他不喜欢的任何内容,或其他方法/属性等

一个非常有趣的场景是类型约束继承:

public abstract class MyClass
{
    public void DoSomething()
    {
        Console.WriteLine("blah blah");
    }
}

public class MyClass<T>: MyClass
{
    public T GetSomething()
    {
        // return null as T;
    }
}
公共抽象类MyClass
{
公共无效剂量测定法()
{
控制台。写线(“诸如此类”);
}
}
公共类MyClass:MyClass
{
公共的东西
{
//返回null作为T;
}
}

您可能会看到默认实现在基类上。

有趣的是,C#中的
静态类实际上是
密封的
抽象的
类。这种情况的目的很明确:只允许声明静态方法。

基类通常用于提供普通功能。根据您的设计,可以在不依赖于成员的情况下实现此通用功能。在这种情况下,子类通常不需要任何公共成员。在您的示例中,
房屋
对象类用于简单操作,我假设您不需要房屋的任何常见状态,例如楼层数、墙类型(木材、砖块等)。看到这样一个类,我想“好吧,这个类没有保存对象的任何状态。它只是执行一些操作”

我想编译器中需要更多的代码来发现这个“问题”并防止它。所以这个问题可以颠倒过来-为什么编译器应该被专门设计来阻止它?这确实是一个有效的问题。在我看来,这是糟糕设计的标志。通常我在过去做过,最后我需要将
OpenDoor
标记为虚拟,因为我的衍生房屋需要特定的方法。一种替代方法是添加另一个受虚拟保护的方法
OnOpenDoor
,允许子对象具有特定的实现,同时从基类控制
绝对
实现。Hmmm。。。我不认为这是真的。虽然这是真的,但这并不适用于(非
静态的
)问题,为什么没有接口呢?@It'sNotALie。你能在接口中实现方法吗?@Heuster不,你不能,就像我一样