【问题标题】:Is there a way to assign methods dynamically at runtime to a Java class?有没有办法在运行时动态地将方法分配给 Java 类?
【发布时间】:2018-07-20 14:20:31
【问题描述】:

考虑这个基类:

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 类的实例以从Cat 类继承meow 方法?

伪代码可能是:

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

我有办法做到这一点吗?

更新:构图不是我想要的。对于组合,我需要在我的所有Cat1 到CatN 类中都有一个Cat 类的实例。我必须在每个类中创建一个包装器方法,以便我可以调用它meow。这是大量的样板代码。这就是为什么我说动态增强。

【问题讨论】:

  • 组合是一种解决方案,而不是唯一的解决方案。我们需要一个更好的示例来说明您需要实现什么才能提供更准确的解决方案。
  • 那你使用了错误的语言。简单明了。
  • Java 8 支持接口中的默认方法。如果您将Cat 类更改为接口,并将meow() 方法更改为接口中的默认方法,则每个CatN 类都可以实现Cat 接口。这近似于 Java 中的多重继承。参考:dzone.com/articles/interface-default-methods-java
  • 从您上次的评论来看,我认为这不是问题所在。我要求您提供有关您的问题的更多信息,而您唯一要做的就是等待更多答案。说真的:如果您提供更多数据或者您想要实现的目标的示例,我们可以提供更多信息并更好地帮助您。考虑到我们不知道你有什么,你维护什么样的代码,也不知道这样的事情......
  • 随便你说什么,但请添加一个你需要的例子,就这样:)

标签: java


【解决方案1】:

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

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

另一个答案是查看AOP,它在某些框架(例如 Spring AOP)中的 Java 中受支持。这里的想法是识别“横切”关注点,并让框架以某种方式添加相应的代码。一个典型的例子是“注释”方法来做“日志”,然后 AOP 框架只是添加了做一些标准化日志所需的代码。

【讨论】:

  • 你能指导我AOP的方式吗?
  • @mohammadrostamisiahgeli 这不是这个网站的运作方式。我们不训练你。这是一个广泛而广泛的话题。说真的:这是你的项目,所以你必须做繁重的工作。首先,您必须研究 AOP,然后确定它是否符合您的需求(也许,只是也许),Faysal 关于默认方法的答案可以为您做。
  • @GhostCat 你是故意“说”ASOP 吗?或者你的意思是说“AOP”?什么是“ASOP”? (试图教育自己)。
  • @StvnBrkdll 你是对的,愚蠢的(心理)错字。感谢您的编辑!
  • 如前所述,这首先并不“简单”。我们在这里谈论的是一件严肃的、先进的事情。给你足够的信息来做你想做的所有事情……相当于培训/教你一个小时或更长时间。
【解决方案2】:

使用 Cat 类的 interface 代替 class 并使您的方法默认。仅适用于 Java 8 及更高版本。

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

你可以调用你的子类的方法如下:

Cat cat= new Cat1();
cat.meow();

【讨论】:

  • 我总是忘记默认方法。他们并没有解决所有问题,但也许他们在这里工作。取决于上下文。
  • 默认方法的问题是它们可能需要参数或依赖于接口的其他抽象方法。使用它们时要小心。
  • @Faysal Mehmood 我不认为您的示例使用组合,它看起来像继承。见:stackoverflow.com/questions/2399544/…
  • 请注意此方法的局限性。接口不能有属性,因此在您的默认方法中,您将无法访问属性。您只能调用接口的其他方法(可能会在层次结构中被覆盖),并使用该方法的参数。
【解决方案3】:

你不能这样做,但你有两个选择可供探索

  1. 使用接口,使用继承来分配行为总是比使用继承好。

  2. 第二种选择是使用函数式编程从方法中返回消费者实例,该方法可以根据一些逻辑条件进行更改。

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

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 2015-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-14
      • 2012-04-24
      • 2015-04-04
      • 2012-08-08
      相关资源
      最近更新 更多