Java-重写外部方法
我正在尝试为我的应用程序制作一个特殊的附加组件。我需要在不编辑类文件的情况下重写类的某些方法 以下是一个方案:Java-重写外部方法,java,overriding,Java,Overriding,我正在尝试为我的应用程序制作一个特殊的附加组件。我需要在不编辑类文件的情况下重写类的某些方法 以下是一个方案: class A { public void method1() { // Do something here } public int method2() { // Do something } } 现在,在我的类B中,我想重写类A中的method1 func,并强制类A使用我的新方法 class B
class A
{
public void method1()
{
// Do something here
}
public int method2()
{
// Do something
}
}
现在,在我的类B中,我想重写类A中的method1 func,并强制类A使用我的新方法
class B
{
public void method1()
{
Do something
}
}
我想在不编辑A类的情况下更新我的A类代码。可能吗
谢谢。通过继承,是的。只需更改类B定义:
类B扩展A
使用类B扩展A
和要更改的ovverride方法。您必须如何使用类B
而不是A
的实例。像
class B extends A
{
public void method1(){
Do something
}
}
A a = new B();
a.method1();
这是没有道理的。重写意味着精确地重新定义从超类继承的方法。以下是一些解决方案:
- B必须扩展A,然后您可以重写A的一个方法。为其指定与A中相同的签名,请使用@override注释以确保
- A有一些被注入的依赖项:method1和method2使用一些tierce对象(C)来完成工作,依赖项被注入A。然后B可以使用A和自定义C对象来满足其需要。A的大多数代码不会以这种方式更改
构造函数创建对象,则不会。
您可以使用B
扩展A
,但必须将对象实例化为new B()
(即使您可以将它们声明为A
,如A obj=new B()
)。不,在Java等语言中,这是不可能直接实现的<代码>新A
将始终在运行时创建A
的实例,而不是派生B
的实例
如果可能(也就是说,如果您控制实例化A
的所有代码),您可以使用一些引入某种间接寻址的笨拙变通方法。例如,您可以使用一个可配置的工厂来生产a
s(在封面下按需切换到生产B
s)——这似乎是Java的方式。(您将需要所有的代码构造A
s,不是直接使用,而是通过工厂使用。)
如果我没有弄错的话,您正在寻找的特性在Objective C开箱即用中可用,但在Java中不可用。实现这一点的一种方法是使用某种类型的方法来创建A类型的对象,而不是在代码中直接调用A()构造函数。然后,您的加载项将需要提供并注册它自己的工厂实现,该工厂将创建类B的实例。这仅在加载项在创建任何实例A之前加载并初始化时有效
另一种方法是实现您自己的类加载器,并使用它在加载时修改类A的字节码。您可以搜索用于实现此功能的工具。这只有在您可以控制类A的类加载过程时才可能。不,您不能这样做,在不实际修改类的情况下修改类的行为是不可能的,但是,有一个解决方法:
听起来代理可以解决你的问题。看看 下面是MyCallback类的示例impl
class MyCallback implements MethodInterceptor{
public Object intercept(Object obj,
Method method,
Object[] args,
MethodProxy proxy){
Object stuffToReturn = null;
if ("method1".equals(method.getName()) {
//Class B's method1 impl
} else {
//call the original method in class A
stuffToReturn = method.invoke(proxy, args);
}
return stuffToReturn;
}
}
我不太明白。你是说你现在想要
A=newa();a、 method1()
调用B.method1
?您不能更改类a
中已定义的行为,最好是从类a
扩展并更改类B
中的行为。然后调用类B
对象上的所有方法。在Java中,你不能“替换”原始类,类似于目标C中可能的情况——你需要覆盖并确保其他人使用新类。“我想在不编辑A类的情况下更新我的A类代码”嗯,这不是矛盾吗?@Alvin:在某些语言中,这实际上是可能的。不,新的A().method1()
仍将调用原始的。您将B类
而不是A类
的行为修改为requested@amit如果你读了这篇文章,OP说他不想修改A类。@HunterMcMillen:他想修改A
的行为而不修改它,而不是B
@amit的行为而不编辑源文件,无法更改现有的行为。继承给了他一个解决办法。@HunterMcMillen:那么答案应该是“不,但是…”而不是“是”,这是在改变B
,而不是a
。这是一种并非总是可行的解决方法newa().method1()
将具有与以前相同的行为。但是-至少这个答案明确提到它只影响B
。谢谢你的回答。有什么方法可以在方法启动时捕获事件吗?我不知道有什么方法,抱歉:(+1.另外,旁注/问题:我不是C#专家,但我知道你可以使用反射在那里动态添加字段-也许也可以[在C#中]这样做?[如果有人知道答案,我会很高兴].但是-在java中,反射无法实现,AFAIK也无法实现。@amit:哇,我不知道这个C#功能!你能分享一些关于它的更多信息吗?(或者这是关于ExpandoObject
?)@Vlad:正如我所说,我不是C#专家,我只记得一年前读过它[可靠来源]…我不是解决这些问题的地方:)好吧,这不会影响simplenew A
实例化的对象的行为。好吧,海报只要求不要修改A类,所以听起来他可以将new A()更改为e.create()?如果海报甚至不能改变
class MyCallback implements MethodInterceptor{
public Object intercept(Object obj,
Method method,
Object[] args,
MethodProxy proxy){
Object stuffToReturn = null;
if ("method1".equals(method.getName()) {
//Class B's method1 impl
} else {
//call the original method in class A
stuffToReturn = method.invoke(proxy, args);
}
return stuffToReturn;
}
}