有没有一种方法可以在运行时动态地将方法分配给Java类?

时间:2018-07-20 14:20:31

标签: java

请考虑以下基类:

public class Cat {
  public void meow() {
    // meowing
  }
}

由于某种原因,cats子类不能从此Cat类继承,因为它们必须从另一个基类继承,并且Java不支持多重继承。因此:

public class Cat1 extends BaseClass1 {

}

public class Cat2 extends BaseClass2 {

}

public class Cat3 extends BaseClass3 {

}

如何动态扩展CatX类的实例以从meow类继承该Cat方法?

伪代码可能是:

public cat1Instance = new Cat1();
Cat.augmentWithCatBehavior(cat1Instance);

我有办法实现这一目标吗?

更新:合成不是我想要的。为了进行合成,我需要在我的所有CatCat1类中都拥有CatN类的实例。我必须在每个类中创建一个包装器方法,以便可以将其称为meow。这是大量的样板代码。这就是为什么我说动态增强

4 个答案:

答案 0 :(得分:4)

否,Java类的结构在编译时已固定,并且只能进行检查(使用反射),而不能在运行时动态更改。

尽管可以在运行时动态 generate 整个类。尽管这大大挫败了使用静态编译语言(例如Java)的目的。

另一个答案是查看AOP,它在某些框架中(例如在Spring AOP中)在Java中受支持。这里的想法是确定“横切”问题,并让框架以某些方式添加相应的代码。一个典型的例子是对方法进行“注释”以进行“日志记录”,然后AOP框架仅添加执行一些标准化日志记录所需的代码。

答案 1 :(得分:3)

使用Cat类的 val list = listOf("a", "A ", "A", "B") .distinctBy { it.toLowerCase() } .distinctBy { it.trim() } println("list = ${list}") 代替interface,并将您的方法设置为默认方法。仅适用于 Java 8 和更高版本。

class

您可以按如下所示调用子类的方法:

interface Cat {
   default void meow() {
    // meowing
   }
}
public class Cat1 extends BaseClass1 implements Cat {
    @Override public void meow() {}
}

答案 2 :(得分:0)

您不能在运行时将方法添加到类中。您有两种可能的解决方案:

  1. 使用接口来解决多重继承的需求。
  2. 使用实例字段和实例而不是继承。

答案 3 :(得分:0)

您不能这样做,但是有两个可供选择的探索方式

  1. 使用接口,使用继承分配行为而不是使用继承总是很好。

  2. 第二个选项是使用函数式编程从方法中返回Consumer实例,该实例可以根据某些逻辑条件进行更改。

注意:函数式编程使我们能够返回函数/行为,这对我们有很大帮助。