OOP:如何在超类中动态扩展函数

OOP: How to dynamically extend functions in superclass

我有一个基础 class B 和 2 个衍生 classes D1, D2

class B {
    int commonFunc();
    virtual int specifyFunc();
}
class D1 : public B {
    int specifyFunc();
}
class D2 : public B {
    int specifyFunc();
}

现在我满足了一个要求,我需要扩展我的基础 class 函数 commonFunc()。因为我不想修改基础 class 中的现有代码,所以我派生了另一个 class,例如:

class B {
    virtual int commonFunc();    // Change to virtual
    virtual int specifyFunc();
}
class B2 : public B {
    int commonFunc();    // A new commonFunc() to meet new requirement
}

但是,D1D2不能使用B2中的新commonFunc()除非我修改继承层次。

这是我想到的一个可能的解决方案

class B {
    virtual int commonFunc();
    virtual int specifyFunc();
}
class D1 : public B {
    int specifyFunc();
}
class D2 : public B {
    int specifyFunc();
}
class NewD1 : public D1 {
    int commonFunc();   // Overrided commonFunc() in base class
}
class NewD2 : public D2 { 
    int commonFunc();   // Overrided commonFunc() in base class
}

由于 NewD1NewD2 中的 commonFunc() 完全相同,此解决方案涉及较差的代码复制

我正在寻找任何可以动态扩展基础 class 而无需对现有 class.

做太多修改的设计模式或解决方案

您有多种解决方案。继承只能用于分解具有相同职责的 classes 的代码。这意味着您的 class Car 不应继承自 class Logger,因为您需要一些日志记录功能。这将决定选择哪种解决方案。

1. D1和D2的职责与B

相同

那么拥有更模块化继承的一个好方法就是模式 decorator。这将允许你做你想做的事。只需一点代码就可以有一个想法:

class B {
    virtual int commonFunc();
    virtual int specifyFunc();
}

class BDecorator: public B {
    B parent;
    B(B&);
    virtual int commonFunc(); // Implementation forward to parent.
    virtual int specifyFunc(); // Implementation forward to parent.
}
class B2: public BDecorator {
    int commonFunc();
    int specifyFunc();
}
class D1 : public BDecorator {
    int specifyFunc();
}
class D2 : public BDecorator {
    int specifyFunc();
}

// Use:
B b();
B2 b2(b);
D1 d1(b2);

2。 D1 和 D2 的职责与 B

不同

那么你应该使用组合而不是继承。这意味着您应该定义一个纯抽象 class D (一个接口)并使 D1D2 从它继承。然后,在B的构造函数中,可以注入一个D。 (是的,在这个解决方案中,你必须稍微改变 B,告诉我这是否真的是一个问题。)

class B {
    D d;
    int commonFunc();
    virtual int specifyFunc(); // Do something with d.
    B(D);
}

class D {
    virtual int func();
}
class D1 : public D {
    int func();
}
class D2 : public D {
    int func();
}

// Use with B, but you can use B2 (inheriting from B) instead:
D1 d1();
B b1(d1);

D2 d2();
B b2(d2);

我为我的旧 C++ 道歉。

Interface Design (Program to an interface, not an implementation)

您可以通过使用通用接口(纯抽象 class)来避免此类实现依赖性 IB。 你可以改变行为 (commonFunc()) 通过添加新的 classes (NewB) 而不更改现有的 classes.
客户端引用公共接口并独立于实现。

Decorator Design

如果您不能这样做或确实想要动态扩展对象的行为 在 运行-时间,Decorator 可能会有所帮助。 但是装饰器只能在执行旧行为后and/or之前添加行为。

请参阅以下 UML 图(如果您不确定如何实现,请告诉我)。

进一步的讨论参见GoF Design Patterns Memory 学习 面向对象设计与编程/装饰器/设计原则(界面设计) 在 http://w3sdesign.com.