有没有办法在运行时将方法动态分配给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我不认为您的示例使用合成,它看起来像继承。请参阅:请注意此方法的局限性。接口不能有属性,因此在默认方法中,您将无法访问属性。您只能调用接口的其他方法(可能在层次结构中被重写),并使用该方法的参数。