有没有办法在运行时将方法动态分配给Java类?

有没有办法在运行时将方法动态分配给Java类?,java,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 BaseClas

考虑这个基类:

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类的结构在编译时是固定的,只能检查(使用反射),但不能在运行时动态更改

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


另一个答案是深入研究,Java在某些框架(例如SpringAOP)中支持这一点。这里的想法是确定“横切”关注点,并让框架以某种方式添加相应的代码。一个典型的例子是对方法进行“注释”以进行“日志记录”,然后AOP框架只添加进行一些标准化日志记录所需的代码

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

  • 使用接口解决多重继承的需要
  • 使用实例字段和组合而不是继承

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

  • 使用接口时,最好使用继承来指定行为,而不是使用继承

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


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

    使用Cat类的
    接口
    ,而不是
    ,并将您的方法设为默认值。仅适用于Java8及更高版本

    interface Cat {
       default void meow() {
        // meowing
       }
    }
    public class Cat1 extends BaseClass1 implements Cat {
        @Override public void meow() {}
    }
    
    您可以按如下方式调用子类的方法:

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

    合成是一种解决方案,而不是唯一的解决方案。我们需要一个更好的例子来说明您需要实现什么,以提供更准确的解决方案。那么您使用的语言是错误的。Java 8支持接口中的默认方法。如果将
    Cat
    类更改为接口,并将接口中的
    meow()
    方法更改为默认方法,则每个
    CatN
    类都可以实现
    Cat
    接口。这近似于Java中的多重继承。参考:从你最后的评论来看,我不认为这是一个问题。我要求你提供更多关于你的问题的信息,你唯一要做的就是等待更多的答案。严肃地说:如果你提供更多的数据或者你想要实现的一个例子,我们可以提供更多的信息,更好地帮助你。考虑到我们不知道你有什么,你维护什么样的代码,或者诸如此类的东西…不管你说什么,请添加一个你需要的例子,就是:)你能指导我AOP的方式吗?@mohammadrostamisiahgeli这不是这个网站的工作方式。我们不训练你。这是一个广泛的话题。严肃地说:这是你的项目,所以你必须做繁重的工作。首先,你必须研究AOP,然后确定它是否符合你的需要(也许,只是也许),Faysal关于默认方法的回答可以帮助你。@GhostCat你是故意“说”ASOP吗?还是说“AOP”?什么是“ASOP”?(试图教育自己)。@stvnbrkdell你是对的,愚蠢的(精神)打字错误。谢谢你的编辑!如前所述,这一点一开始并不“简单”。我们在谈论一件严肃的、先进的事情。给你足够的信息去做所有你想做的事情。。。相当于训练/教你一个小时或更长时间。我总是忘记默认方法。他们并没有解决所有的问题,但也许他们在这里工作。依赖于上下文。默认方法的问题是它们可能需要参数或依赖于接口的其他抽象方法。使用它们时要小心。@Faysal Mehmood我不认为您的示例使用合成,它看起来像继承。请参阅:请注意此方法的局限性。接口不能有属性,因此在默认方法中,您将无法访问属性。您只能调用接口的其他方法(可能在层次结构中被重写),并使用该方法的参数。