在OOP中向现有类添加功能
Adding functionality to an existing class in OOP
在面向对象编程中,我们经常使用多态性来使几种不同类型的对象在同一个"接口"下表现。面包和黄油的例子是这样的:
public abstract class Animal {
public abstract void makeSound();
}
public class Dog extends Animal {
public void makeSound() {
System.out.println("Woof woof");
}
}
public class Cat extends Animal {
public void makeSound() {
System.out.println("Meow");
}
}
我们不关心实际的动物是什么,只关心它会发出声音。
然而,当我们想要向现有类添加新特性时,问题就出现了。在我的情况下,我试图使几个类实现UniformProvider
接口(它将类转换为OpenGL着色器程序的原始统一值)。
到目前为止,我已经使用了一个简单的instanceof
检查,处理了许多可能的类型,但是我不想依赖instanceof
,因为它不容易扩展而不修改源文件。
UniformProvider
接口的问题是它不能实现内置类型,如float
(或Float
), int
(或Integer
)和对象数组(例如:Matrix4f[]
)。此外,我认为将统一变量转换的功能放入数学类违反了单一职责原则。
在Rust语言中,结构体有一个有用的特性,我现在才意识到它的潜力。在传统的OOP中,类/结构实现接口/trait,如果不修改原文件,就无法实现更多的接口。然而,在Rust中,为结构提供并实现了trait ,从而逆转了依赖关系。它使用类似impl Add for Vector4f
的语法而不是Vector4f implements Add
。
我正在考虑在传统的面向对象语言(如Java或c++)中存在哪些选项来实现这种模式。我考虑创建一个转换器的注册表,它被分配给一个类:例如float
的FloatConverter
,然后使用HashMap或等效的方法访问相关的转换器,但我认为这可能是相当低效的。
我问这个困境有什么解决方案(或者我是否应该切换到Rust:)[我正在考虑])。
一个优雅的解决方案是访问者模式
// Base object hierarchy
abstract class Animal {
abstract void Accept(AnimalVisitor visitor);
}
class Dog extends Animal {
void Accept(AnimalVisitor visitor) { visitor.Visit(this); }
}
class Cat extends Animal {
void Accept(AnimalVisitor visitor) { visitor.Visit(this); }
}
interface AnimalVisitor {
Visit(Dog dog);
Visit(Cat cat);
}
// Here is a concrete visitor ...
class AnimalNoiseMaker implements AnimalVisitor {
Visit(Dog dog) { System.out.println("Woof woof"); }
Visit(Cat cat) { System.out.println("Meow"); }
}
// .. and how you use it
Animal a = ...;
a.Accept(new AnimalNoiseMaker()); // Woof or Meow !
当我无法修改现有类时,我经常使用decorator模式向现有类添加行为:
public final class EmpoweredAnimal extends Animal
{
private final Animal animal;
public EmpoweredAnimal(Animal animal)
{
this.animal = animal;
}
@Override
public final void makeSound()
{
this.animal.makeSound();
}
public final void jump()
{
// TODO
}
}
用法:
Animal myDog = new Dog();
//Drawback: you must base your polymorphism on the EmpoweredAnimal now
EmpoweredAnimal myEmpoweredDog = new EmpoweredAnimal(myDog);
myEmpoweredDog.makeSound(); //prints "woof woof"
myEmpoweredDog.jump(); //do something new
这个缺点是可以接受的,如果你所有的动物都必须被授权,否则你被迫继续使用instanceof,因为不是所有的Animal
都会被包装在一个EmpoweredAnimal
中。
- 设计模式,以避免不必要地添加抽象函数以适应新功能
- 在大括号内添加语句会更改代码功能?
- 在 C++ 中向多态树添加功能
- Trie 查找/添加功能无法正常工作
- 简单的二进制搜索树非递归添加功能
- Omnet 在我的班级中添加功能
- 如何正确覆盖虚拟方法以添加功能
- Qthread,为qthread添加功能
- 如何打印添加功能的结果.
- 如果我希望子类向父类添加功能,我是否应该保护我的属性
- 在没有继承的情况下向c++类添加功能
- 向类及其所有子类添加功能
- 用于添加功能的继承
- 如何向派生类添加功能
- 如何强制重新运行cmake,或通过CMakeLists.txt添加功能到makefile
- 为已经存在的函数添加功能(c#, c++)
- 如何修复错误并向源文件添加功能,同时保证不会破坏某些应用程序
- 使用继承添加功能
- 链表需要帮助无法打印我的数据.想要添加功能.在 C - C++ 中
- 在OOP中向现有类添加功能