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

Posted

技术标签:

【中文标题】OOP:如何动态扩展超类中的函数【英文标题】:OOP: How to dynamically extend functions in superclass 【发布时间】:2015-02-12 03:50:42 【问题描述】:

我有一个基类B 和两个派生类D1D2

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

class D1 : public B 
    int specifyFunc();

class D2 : public B 
    int specifyFunc();

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

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() 完全相同,因此该解决方案涉及到糟糕的代码复制

我正在寻找任何可以动态扩展基类而无需对现有类进行太多修改的设计模式或解决方案。

【问题讨论】:

收容怎么样? B2 包含在 NewD1 和 NewD2 中。解决方案保留在 B2 中。 "我不想修改基类中的现有代码" -- "对现有类没有太多修改" -- 所以,是哪一个?没有任何修改?还是没有很多修改?请量化“很多”。 您需要澄清您的问题或使用一些占位符伪代码来帮助我们了解您想要什么。 使用virtual继承怎么样? 我不懂 C++,但这听起来像是装饰器模式。 【参考方案1】:

您有几种解决方案。继承只能用于分解具有相同责任的类的代码。这意味着您的类Car 不应继承自类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 不同

那么你应该使用组合而不是继承。这意味着您应该定义一个纯抽象类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++ 道歉。

【讨论】:

感谢详细解答!!这正是我所需要的! 很高兴能帮到你!【参考方案2】:

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

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

Decorator Design

如果你不能这样做或真的想动态扩展对象的行为 在运行时,装饰器可能会有所帮助。 但是装饰器只能在执行旧行为之前和/或之后添加行为。

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

如需进一步讨论,请参阅 GoF 设计模式记忆学习 面向对象设计与编程 / 装饰器 / 设计原则(界面设计) 在http://w3sdesign.com。

【讨论】:

感谢您的详细解答!我将使用装饰器来解决我的问题。再次感谢!

以上是关于OOP:如何动态扩展超类中的函数的主要内容,如果未能解决你的问题,请参考以下文章

python学习手册:第二十五章——oop

方法没有覆盖超类中的任何函数(覆盖 func collectionView)[重复]

超类构造函数中的虚拟化

将函数的结果分配给 PHP 类中的变量? OOP 怪异

如何在 C++ 中的类中递归调用函数方法?

如何从超类中检测对象