我有以下(第三方)类结构。我们将第三方项目命名为ProjectSeriously,并注意到我使用System.out.println代替了其他复杂的功能(数百行代码)。
class A {
public void hi() {
// Do an important thing
System.out.println("Important thing A");
}
}
class B extends A {
public void hi() {
// Do some terrible, terrible things
System.out.println("TERRIBLE THING B");
// Do that important thing
super.hi();
}
}现在我想写这段代码(这不是有效的java):
class C extends B {
public void hi() {
// Do some not-so-terrible things
System.out.println("Ok thing C");
// Do that important thing
super.super.hi();
}
}我必须将instanceof B传递给这个奇妙项目的其他部分,ProjectSeriously。考虑到这些都是公共方法,我觉得这应该是可能的。
发布于 2015-04-29 04:51:42
在对类的任何使用进行之前,您可以使用javassist来修改它。
但这是一个非常丑陋的黑客,请尝试在A和/或B中重构代码以暴露重要部分。
package test;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
class A {
public void hi() {
// Do an important thing
System.out.println("Important thing A");
}
}
class B extends A {
public void hi() {
// Do some terrible, terrible things
System.out.println("TERRIBLE THING B");
// Do that important thing
super.hi();
}
}
class C extends B {
public void hi() {
// Do some not-so-terrible things
System.out.println("Ok thing C");
// Do that important thing
super.hi();
}
}
public class Main {
public static void main(String[] args) throws Exception {
CtClass cc = ClassPool.getDefault().get("test.B"); // don't use test.B.class.getName() as this force the class loader to load the class
CtMethod m1 = cc.getDeclaredMethod("hi");
cc.removeMethod(m1);
CtMethod m2 = CtNewMethod.copy(m1, cc, null);
m2.setBody("{ /* override method B.hi() body */ return super.hi();}", "this", m1.getName());
cc.addMethod(m2);
cc.toClass();
C obj = new C();
obj.hi();
}
}结果:
Ok thing C
Important thing A发布于 2015-04-29 04:20:20
除非显式地公开方法,否则就没有太多的其他选择:
public class GrandParent {
public void hi() {
hiGrandParent();
}
protected final void hiGrandParent() {
System.out.println("Hi from grandparent.");
}
public static class Parent extends GrandParent {
@Override
public void hi() {
hiParent();
}
protected final void hiParent() {
System.out.println("Hi from parent.");
}
}
public static class Child extends Parent {
@Override
public void hi() {
hiChild();
super.hi();
hiParent();
hiGrandParent();
}
protected final void hiChild() {
System.out.println("Hi from child.");
}
}
}运行时使用:
public final class RunIt {
public static void main(final String[] args) {
new GrandParent.Child().hi();
}
}预期输出:
Hi from child.
Hi from parent.
Hi from parent.
Hi from grandparent.发布于 2015-04-29 04:33:17
这将以一种可怕的方式破坏封装(您实际上会禁用类B逻辑的某些部分),这在Java语言中应该是不可能的,我非常确定这是不可能的。
https://stackoverflow.com/questions/29928606
复制相似问题