java - 向 OOP 中的现有类添加功能

标签 java c++ oop opengl

在面向对象编程中,我们经常使用多态性来使几种不同类型的对象在同一个“接口(interface)”下运行。面包和黄油的例子是这样的:

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 接口(interface)(它将类转换为 OpenGL 着色器程序的原始统一值)。

到目前为止,我使用了一个简单的 instanceof 检查来处理许多可能的类型,但是我不想依赖 instanceof 因为它不容易无需修改源文件即可扩展。

UniformProvider 接口(interface)的问题在于它无法为内置类型实现,例如 float(或 Float)、 int(或 Integer)和对象数组(例如:Matrix4f[])。此外,我认为将统一变量转换的功能放入数学类违反了单一职责原则。

在 Rust 语言中,结构有一个有用的特性,我现在才意识到它的潜力。在传统的OOP中,类/结构实现了接口(interface)/特征,如果不修改原始文件就无法实现更多的接口(interface)。然而,在 Rust 中, 结构提供并实现了一个特征,从而扭转了依赖关系。这使用类似 impl Add for Vector4f 的语法,而不是 Vector4f implements Add

我正在考虑在传统的 OOP 语言(例如 Java 或 C++)中对于这种模式存在哪些选项。我考虑创建一个 converters 注册表,它们被分配给一个类:例如 FloatConverter for float,然后使用 HashMap 访问相关转换器或等价物,但我认为这可能效率很低。

我问有什么解决这个难题的方法(或者我是否应该改用 Rust :) [我正在考虑])。

最佳答案

一个优雅的解决方案是 Visitor Pattern

// 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 !

关于java - 向 OOP 中的现有类添加功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30320716/

相关文章:

java - Java 计时器领域的现状如何?

java - 使用求和聚合时出现空指针异常

OOP:实现具有更广泛签名的接口(interface)方法

exception - 编写自定义异常类时应该考虑哪些因素?

c++ - fatal error LNK1169 : one or more multiply defined symbols found in game programming

java - 在JAVA Eclipse中添加背景到JPANEL

java - 注意:未定义的属性:http://localhost:8080/JavaBridge/java/Java.inc 第 1994 行中的 java_Client::$cancelProxyCreationTag

c++ - gdb 如何打印 vector<bool> 值

C++ 和无符号类型

c++ - 请求这个 'for-loop' 的 Action