C# 没有任何抽象方法的抽象类

C# 没有任何抽象方法的抽象类,c#,C#,我很惊讶地知道,C#中的抽象类在没有抽象方法的情况下也是可能的 abstract class AbstractDemo { public void show() { Console.WriteLine("In Show Method"); } } class MainDemo:AbstractDemo { public static void Main() { Console.WriteLine("In Main Method"); } } 有什么解释吗?如

我很惊讶地知道,C#中的抽象类在没有抽象方法的情况下也是可能的

abstract class AbstractDemo
{
 public void show()
  {
    Console.WriteLine("In Show Method"); 
   }
}
class MainDemo:AbstractDemo
{
 public static void Main()
 {
    Console.WriteLine("In Main Method");
 }
}

有什么解释吗?

如果您的类只是其他类的基础,并且没有完全的可用性——换句话说,作为基础,它本身根本不可用,那么您希望阻止创建它的实例。在这种情况下,您可以创建没有抽象成员的抽象类。

我认为您将抽象类与接口混淆了。接口不能有带主体的方法,抽象类可以。有时,您希望阻止用户实例化特定类的对象;但仍然为派生自它的类提供一些基本功能;这就是抽象类的用途。

有时,您不希望提供实例化类的可能性,但需要将该类作为其他类的基类


选择抽象类而不是接口的原因是您可以提供一些基本的实现。

抽象类是一个必须先扩展才能使用的类。这并不意味着函数本身必须是抽象的

以动物类为例

public abstract class Animal
{
    void Move()
    {
        //whatever
    }
}

public class Fish : Animal
{
    void Swim()
    {

    }
}

public class Dog : Animal
{
    void Bark()
    {

    }
}
所有动物都会动,但只有鱼会游泳,狗会吠叫


或者是一个真实的例子。我在应用程序中使用了一个Asp.net MVC基本控制器。它有一些我经常需要的基本方法,比如GetCurrentUser()和一个我编写的帮助本地化的函数。它还负责跟踪,所以我不必在所有控制器中重写代码。该类大约有200行代码,但没有一个抽象方法。

这是完全有效的,如果您想提供类似事件的行为,偶尔也会有用:提供一个抽象类,其中包含所有作为虚拟方法实现的“事件处理程序”,默认行为为不做任何事情

然后,派生类可以重写某些方法,但不必重写任何特定的方法,因为没有任何方法是抽象的。类仍然是抽象的,因为基类的一个实例将是无意义的(因为所有内容都是无操作的)


然而,这种模式在Java中比C#更为常见——就像在C#中一样,您通常只使用“适当的”事件。

您可以在类上使用抽象关键字,只是向编译器发出信号,它只能从类继承,而不能直接使用;在这种情况下,您没有义务在类上放置抽象成员


这相当于只在类中放置一个受保护的构造函数,但使用抽象更清晰易懂。

没有比MSDN it self更好的解释了

  • 抽象类不能直接实例化,它是 使用新的 抽象类上的运算符。虽然 可以有变量和 编译时类型为的值 抽象地说,这些变量和值 必须为null或 包含对的实例的引用 从 抽象类型
  • 允许(但不是必需)抽象类包含抽象类 成员们
  • 抽象类不能被密封

我们听说在抽象类中,必须有一个abstract成员。但是当我在没有抽象方法的情况下编译abstract类时,它会编译。这让我很惊讶。现在我找不到解释Abstract类确切行为的文章。

事实上,我想你会发现大多数狗都会游泳;)好的,这意味着我们可以使用这样一个抽象类,就像其他类的标记类一样。是的,的确如此-但是如果你不需要实现,你可以使用接口。那么一个绝对没有方法的抽象类呢。甚至不是定义。@Nadeem在这种情况下,它几乎与“marker”接口相同(即没有任何东西,只是标记一个类;请注意,FxCop建议使用属性)。不同之处在于,您只能有一个基类(例如“标记抽象类”),但可以实现许多接口。所以在这种情况下,接口通常更好。是的,但假设我们想要类的一些属性,如果我们使用接口,那么默认情况下它们将是公共的,这将违反OOPS的基本数据隐藏原则。