为什么 C# 允许没有抽象成员的抽象类?

发布于 2024-09-04 14:31:18 字数 728 浏览 4 评论 0原文

C# 规范 第 10.1.1.1 节 规定:

允许使用抽象类(但是 不需要)包含摘要 成员。

这允许我创建这样的类:

public abstract class A
{
    public void Main() 
    {
        // it's full of logic!
    }
}

或者甚至更好:

public abstract class A
{
    public virtual void Main() { }
}

public abstract class B : A
{
    public override sealed void Main()
    {
        // it's full of logic!
    }
}

这确实是一个具体的类;它只是抽象的,因为人们无法实例化它。例如,如果我想执行 B.Main() 中的逻辑,我必须首先获取 B 的实例,这是不可能的。

如果继承者实际上不必提供实现,那么为什么称其为抽象呢?

换句话说,为什么 C# 允许只有具体成员的抽象类?

我应该提到的是,我已经熟悉抽象类型和成员的预期功能。

The C# spec, section 10.1.1.1, states:

An abstract class is permitted (but
not required) to contain abstract
members.

This allows me to create classes like this:

public abstract class A
{
    public void Main() 
    {
        // it's full of logic!
    }
}

Or even better:

public abstract class A
{
    public virtual void Main() { }
}

public abstract class B : A
{
    public override sealed void Main()
    {
        // it's full of logic!
    }
}

This is really a concrete class; it's only abstract in so far as one can't instantiate it. For example, if I wanted to execute the logic in B.Main() I would have to first get an instance of B, which is impossible.

If inheritors don't actually have to provide implementation, then why call it abstract?

Put another way, why does C# allow an abstract class with only concrete members?

I should mention that I am already familiar with the intended functionality of abstract types and members.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

眼泪都笑了 2024-09-11 14:31:18

也许一个很好的例子是公共基类,它为派生类提供共享属性和其他成员,但不表示具体对象。例如:

public abstract class Pet
{
    public string Name{get;set;}
}

public class Dog : Pet
{
    public void Bark(){ ... }
}

所有的宠物都有名字,但宠物本身是一个抽象的概念。宠物的实例必须是狗或其他某种动物。

此处的区别在于,基类声明所有宠物至少由一个 Name 属性组成,而不是提供应由实现者重写的方法。

Perhaps a good example is a common base class that provides shared properties and perhaps other members for derived classes, but does not represent a concrete object. For example:

public abstract class Pet
{
    public string Name{get;set;}
}

public class Dog : Pet
{
    public void Bark(){ ... }
}

All pets have names, but a pet itself is an abstract concept. An instance of a pet must be a dog or some other kind of animal.

The difference here is that instead of providing a method that should be overridden by implementors, the base class declares that all pets are composed of at least a Name property.

三生路 2024-09-11 14:31:18

这个想法是强制实现者从类派生,因为它的目的只是为可能更专业的实现提供基础。因此,基类虽然没有任何抽象成员,但可能只包含核心方法和可用作扩展基础的属性。

例如:

public abstract class FourLeggedAnimal
{

    public void Walk()
    {
        // most 4 legged animals walk the same (silly example, but it works)
    }

    public void Chew()
    {

    }
}

public class Dog : FourLeggedAnimal
{
    public void Bark()
    {
    }
}

public class Cat : FourLeggedAnimal
{
    public void Purr()
    {
    }
}

The idea is to force the implementor to derive from the class as it is intended to provide only a basis for a presumably more specialized implementation. So the base class, while not having any abstract members may only contain core methods an properties that can be used as a basis for extension.

For example:

public abstract class FourLeggedAnimal
{

    public void Walk()
    {
        // most 4 legged animals walk the same (silly example, but it works)
    }

    public void Chew()
    {

    }
}

public class Dog : FourLeggedAnimal
{
    public void Bark()
    {
    }
}

public class Cat : FourLeggedAnimal
{
    public void Purr()
    {
    }
}
并安 2024-09-11 14:31:18

我认为对你的问题的更准确的表述是:为什么 C# 允许一个只有具体成员的抽象类?

答案是:没有充分的理由不这样做。也许有人有某种组织结构,他们喜欢在顶部有一个不可实例化的类,即使它下面的类只是继承并且不添加任何内容。没有充分的理由支持这一点。

I think a slightly more accurate representation of your question would be: Why does C# allow an abstract class with only concrete members?

The answer: There's no good reason not to. Perhaps someone out there has some organizational structure where they like to have a noninstantiatable class at the top, even if a class below it just inherits and adds nothing. There's no good reason not to support that.

无尽的现实 2024-09-11 14:31:18

你这么说——因为你无法实例化它;它只是一个模板。

如果您将其声明为抽象类,那么它就不是“真正的具体类”。您可以将其作为设计选择。

这种设计选择可能与创建实体有关,这些实体是现实世界对象的抽象(存在术语混合的风险),并且具有可读性。您可能想要声明 Car 类型的参数,但不希望将对象声明为 Car ——您希望每个对象都是 Car 类型> 实例化为 TruckSedanCoupeRoadster。事实上,Car要求继承者添加实现,这一事实并不会降低其作为其继承者的抽象版本(本身无法实例化)的价值。

You said it -- because you can't instantiate it; it is meant to be a template only.

It is not "really a concrete class" if you declare it as abstract. That is available to you as a design choice.

That design choice may have to do with creating entities that are (at risk of mixing the terminology) abstractions of real-world objects, and with readability. You may want to declare parameters of type Car, but don't want objects to be declarable as Car -- you want every object of type Car to be instantiated as a Truck, Sedan, Coupe, or Roadster. The fact that Car doesn't require inheritors to add implementation does not detract from its value as an abstract version of its inheritors that cannot itself be instantiated.

过度放纵 2024-09-11 14:31:18

抽象意味着提供行为的抽象。例如,Vehicle 是一种抽象形式。它没有任何现实世界的实例,但我们可以说车辆具有加速行为。更具体地说,福特 Ikon 是一种车辆,雅马哈 FZ 是一种车辆。这两者都有加速行为。

如果你现在在课堂上做这个。 Vehicle 是具有 Acceleration 方法的抽象类。虽然您可能/可能不提供任何抽象方法。但业务需求是Vehicle不应该被实例化。因此你把它变得抽象。另外两个类 - Ikon 和 FZ 是从 Vehicle 类派生的具体类。这两者将有自己的属性和行为。

Abstract means providing an abstraction of behaviour. For example Vehicle is an abstract form. It doesn't have any real world instance, but we can say that Vehicle has accelerating behaviour. More specifically Ford Ikon is a vehicle, and Yamaha FZ is a vehicle. Both these have accelerating behaviour.

If you now make this in the class form. Vehicle is abstract class with Acceleration method. While you may/ may not provide any abstract method. But the business need is that Vehicle should not be instantiated. Hence you make it abstract. The other two classes - Ikon and FZ are concrete classes deriving from Vehicle class. These two will have their own properties and behaviours.

只为一人 2024-09-11 14:31:18

关于用法,在类声明上使用 abstract 但没有抽象成员与使用 public 类但在其类上使用 protected 是一样的构造函数。两者都强制派生类以便实例化它。

然而,就自记录代码而言,通过标记类abstract,它会告诉其他人该类永远不会自行实例化,即使它没有virtual code> 或 abstract 成员。而保护构造函数则没有做出这样的断言。

With regards to usage, using abstract on a class declaration but having no abstract members is the same as having the class public but using protected on its constructors. Both force the class to be derived in order for it to be instantiated.

However, as far as self-documenting code goes, by marking the class abstract it informs others that this class is never meant to be instantiated on its own, even if it has no virtual or abstract members. Whereas protecting the constructors makes no such assertion.

追我者格杀勿论 2024-09-11 14:31:18

编译器不会阻止实现逻辑,但在你的情况下我会简单地省略 abstract ?!顺便说一句,一些方法可以用 { throw Exception("must继承"); 来实现} 并且编译器无法区分完全实现的类和函数,仅包括抛出

The compiler does not prevent implementation-logic, but in your case I would simply omit abstract ?! BTW some methods could be implemented with { throw Exception("must inherit"); } and the compiler could not distinguish fully implemented classes and functions including only throw.

只为守护你 2024-09-11 14:31:18

这是一个潜在的原因:

图层超类型

对于所有对象来说这并不罕见
在一个层中拥有你没有的方法
想要在整个过程中重复
系统。你可以移动这一切
行为到公共层
超级类型。

-- 马丁·福勒

没有理由阻止抽象类中只包含具体方法 - 只是不太常见。 Layer Supertype 是一种可能有意义的情况。

Here's a potential reason:

Layer Supertype

It's not uncommon for all the objects
in a layer to have methods you don't
want to have duplicated throughout the
system. You can move all of this
behavior into a common Layer
Supertype.

-- Martin Fowler

There's no reason to prevent having only concrete methods in an abstract class - it's just less common. The Layer Supertype is a case where this might make sense.

阿楠 2024-09-11 14:31:18

我认为抽象类有两个主要用途:

I see abstract classes serving two main purposes:

  • An incomplete class that must be specialized to provide some concrete service. Here, abstract members would be optional. The class would provide some services that the child classes can use and could define abstract members that it uses to provide its service, like in the Template Method Pattern. This type of abstract class is meant to create an inheritance hierarchy.

  • A class that only provides static utility methods. In this case, abstract members don't make sense at all. C# supports this notion with static classes, they are implicitly abstract and sealed. This can also be achieved with a sealed class with a private constructor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文