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
}
但是,D1
和D2
不能使用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
}
由于 NewD1
和 NewD2
中的 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
(一个接口)并使 D1
和 D2
从它继承。然后,在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.
我有一个基础 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
}
但是,D1
和D2
不能使用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
}
由于 NewD1
和 NewD2
中的 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
(一个接口)并使 D1
和 D2
从它继承。然后,在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.