什么时候抽象基类可以拥有(非静态)数据成员?

时间:2009-05-24 04:11:55

标签: language-agnostic oop abstract-class

我想问题标题总结了一下。是否有时间将ABC视为拥有数据成员的优秀设计?我一直想知道是否存在这样的情况。我能想出的唯一一个是静态的,即便如此,它也是一种延伸。

9 个答案:

答案 0 :(得分:4)

我不明白为什么ABC不能正确地拥有每个实例(也就是非静态)数据成员,以支持它提供给子类的方法。以ABC存在的常见情况为例,提供模板方法DP(钩子方法是抽象的) - 如果组织方法的一部分功能是更新一些实例变量(例如,计算多少次的计数)方法被调用),那么显然那些变量也应该由ABC提供。你能更好地解释为什么你认为这是糟糕的设计吗?!

答案 1 :(得分:1)

抽象类可以拥有所需的任何成员来支持它为从中继承的类提供的功能。这并不是说子类可以直接访问它们:它们只能通过子类或其客户端进行的方法调用来读取和更改。

答案 2 :(得分:0)

我在插件体系结构中看到了这一点,比如Paint.NET的。

答案 3 :(得分:0)

控制倒置可能需要这样做。例如,你有一堆带有Logger实例的类,它们所基于的抽象类可能有一个构造函数将它存储在成员变量或私有属性中(当然你假设你记得调用基础构造函数笑容

答案 4 :(得分:0)

确定,当抽象类中的数据成员包含继承类的基本代码时

我想考虑使用接口,当数据成员只是用来描述你的类

答案 5 :(得分:0)

是的,它可以在抽象基类中提供成员变量,意图是它的子类将使用这些成员来进行具体的实现。

这是一个具体的例子,使用我们都喜欢的汽车类比。

假设我们使Car成为一个抽象基类,它有轮子,底盘和引擎的占位符,供其子类使用:

abstract class Car {
    Wheels wheels
    Chassis chassis
    Engine engine

    abstract void accelerate();
    abstract void decelerate();
}

现在,对于扩展Car的类,成员已经在那里使用,因此子类的职责是填充这些成员变量:

class NiceCar extends Car {
    Decoration decoration;

    public NiceCar() {
        wheels = new ChromeWheels();
        chassis = new LightweightCompositeChassis();
        engine = new LotsOfHorsepowerEngine();
        decoration = new CoolRacingStripes();
    }

    void accelerate() {
        engine.feedFuel();
    }

    void decelerate() {
        wheels.applyBrakes();
    }
}

可以看出,抽象基类可以作为蓝图,应该填充组件(成员变量)以获得类的完整功能。在这种情况下,Car提供了在具体实现中使用的汽车的基本部分。 NiceCar使用这些成员字段并添加一些用于其自身的功能,例如装饰性绘画作业。

答案 6 :(得分:0)

我怀疑你在抽象基类的概念上画得太紧了。

抽象基类(与纯接口相对)是一个类,它打算让子类使用它的某些功能。因此,它将具有一些功能以及旨在被覆盖的方法(接口部分)。没有理由为什么这个功能不应该有与之关联的成员变量。

许多框架都基于继承。这几乎不可避免地会有成员变量的抽象类。例如,DirectShow是Windows中的多媒体流框架。源,编码器,解码器等都在所谓的“过滤器”中实现。有各种类型的过滤器的基类。它们中的每一个都有上游和下游过滤器的成员变量,协商的媒体类型等。

答案 7 :(得分:0)

如果它是所有继承类使用的状态,我认为将强制移动到基类。即使基础是抽象的。我认为大多数进入重构的人会同意我的意见。

为什么某些州应该在基地,可能有几个原因。减少代码重复是一个很好的理由。

干杯!

编辑:请告诉我为什么你投票,所以我可以改进。谢谢!

答案 8 :(得分:0)

正如其他人所提到的,当需要存储状态时,会将实例字段添加到任何类的类中。这适用于抽象或具体的类 - 没有区别。

为什么要有所作为?毕竟一个抽象类就像任何类一样,除了它不能被实现,需要子类化等来完成类。

相关问题