抽象基类什么时候可以拥有(非静态)数据成员?
我想问题标题已经概括了这一点。 是否有某个时候,ABC 拥有数据成员会被认为是良好的设计? 我一直想知道是否有一种情况可以这样做。 我唯一能想到的都是静态的,即使这样也有点牵强。
I guess the question title sums it up. Is there a time when it would be considered good design for an ABC to have data members? I have been wondering if there is a situation where this is OK. The only ones I can come up with all are static, and even then it's kind of a stretch.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
我不明白为什么 ABC 不能正确地拥有每个实例(也称为非静态)数据成员,因为需要支持它提供给子类的方法。 以常见的情况为例,其中存在 ABC 来提供模板方法 DP(钩子方法是抽象的)——如果组织方法的功能的一部分是更新某些实例变量(例如,计算方法被调用),那么显然这些变量也应该由 ABC 提供。 你能更好地解释一下为什么你认为这是糟糕的设计吗?!
I don't see why an ABC couldn't properly have per-instance (aka non-static) data members, as needed to support the methods it supplies to subclasses. Take the common case in which an ABC exists to supply a Template Method DP (the hook methods being abstract) -- if part of the function of the organizing method is to update some instance variables (for example, a count of how many times the method was called), then obviously those variables should also be supplied by the ABC. Can you explain better why you think that's bad design?!
抽象类可以具有支持其向继承自它的类提供的功能所需的任何成员。 这并不是说子类可以直接访问它们:它们只能通过子类或其客户端进行的方法调用来读取和更改。
An abstract class can have whatever members it needs to support the functionality it supplies to the classes that inherit from it. That's not to say these would be directly accessible to the subclasses: they might be read and changed only through method calls made by the subclasses or their clients.
我在插件架构中看到了这一点,比如 Paint.NET。
I see this in plugin architectures, like Paint.NET's.
控制反转可能需要这样做。 例如,您有一堆采用 Logger 实例的类,它们所基于的抽象类可能有一个构造函数将其存储在成员变量或私有属性中(当然假设您记得调用基本构造函数咧嘴笑)
Inversion of Control might require this. For example you have a bunch of classes that take an instance of Logger, the abstract class they're based off might have a constructor store it in an member variable or private property (assuming of course you remember to call the base constructor grin)
这是好的,当你的抽象类中的数据成员包含继承类的基本代码时,
我会考虑使用接口,当数据成员只是为了描述你的类时
It is OK, when your data member in your abstract class contains base code for inheriting classes
I would think about using an interface, when the data member is just to describe your class
是的,可以在抽象基类中提供成员变量,以便其子类将使用这些成员来进行具体实现。
这是一个具体的例子,用我们都喜欢的汽车来比喻。
假设我们将
Car
设为一个抽象基类,其中包含车轮、底盘和引擎的占位符,供其子类使用:现在,对于扩展
Car
的类,成员已经在那里可以使用,因此子类的责任是填充这些成员变量:可以看出,抽象基类可以作为应该填充哪些组件(成员变量)以获得一个蓝图。一个类的全部功能。 在本例中,
Car
提供了在具体实现中使用的汽车的基本部分。NiceCar
使用这些成员字段并为其自己的功能添加一些字段,例如装饰性油漆作业。Yes, its possible to provide member variables in an abstract base class with the intention that its subclasses will use those members to make a concrete implementation.
Here's a concrete example, using a car analogy that we've all come to love.
Let's say we make
Car
an abstract base class, which has placeholders for wheels, chassis, and an engine for its its subclasses to use:Now, for a class that extends
Car
, the members are already there to use, so the responsibility of a subclass is to populate those member variables:As can be seen, the abstract base class can work as a blueprint for which components (member variables) should be filled in to get a full functionality of a class. In this case, the
Car
provides basic parts of a car to be used in a concrete implementation.NiceCar
uses those member fields and adds some for its own features, such as a decorative paint job.我怀疑您对抽象基类的概念画得太紧了。
抽象基类(与纯接口相对)是一个旨在让子类使用其某些功能的类。 因此,它将具有一些功能以及旨在被覆盖的方法(接口部分)。 这个功能没有理由不应该有与之关联的成员变量。
许多框架都是基于继承的。 这些几乎不可避免地会有带有成员变量的抽象类。 例如,DirectShow 是 Windows 中的多媒体流框架。 源、编码器、解码器等都是在所谓的“过滤器”中实现的。 各种类型的过滤器都有基类。 它们每个都有上游和下游过滤器的成员变量、协商的媒体类型等。
I suspect that you are drawing too tight a circle around your concept of an abstract base class.
An abstract base class (as opposed to a pure interface) is a class that intends for some of its functionality to be used by child classes. It will thus have some functionality along with methods that are intended to be over-ridden (the interface part). There is no reason why this functionality should not have member variables associated with it.
Many frameworks are based off of inheritance. These will almost inevitably have abstract classes with member variables. For instance, DirectShow is the multimedia streaming framework in Windows. The sources, encoders, decoders, etc. are all implemented in what are called "filters". There are base classes for various types of filters. Each of them will have member variables for the upstream and downstream filters, the negotiated media types, etc.
正如其他人提到的,当需要存储状态时,可以将实例字段添加到任何类型的类中。 这对于抽象类或具体类都适用——没有区别。
为什么它会有所作为? 毕竟,抽象类就像任何类一样,只是它不能被实例化,需要子类化等来完成该类。
As others have mentioned one adds instance fields to any sort of class when one needs to store state. This holds true of abstract or concrete classes - there is no difference.
Why should it make difference ? After all an abstract class is just like anyclass except it can't be instsntiated, requiring subclassing etc to complete the class.
如果它是所有继承类都使用的状态,我认为将其移动到基类是强制的。 尽管基础是抽象的。 我认为大多数参与重构的人都会同意我的观点。
某些州应该位于基地可能有多种原因。 减少代码重复是一个足够好的理由。
If it's a state used by all inherited classes, I think it's mandatory to move it to the base class. Even though the base is abstract. I think most people that are into refactoring would agree with me on this.
There might be several reasons why some state should be in the base. Reducing code duplication is a good reason enough.