我有以下(第三方)类结构。我们将调用第三方项目ProjectSeriously
,并注意我使用System.out.println
代替其他复杂功能(100行代码)。
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
。看到这些是公共方法,我觉得这应该是可能的。
答案 0 :(得分:3)
您可以使用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
答案 1 :(得分:0)
除非您明确公开方法,哪种方式违背设计模式,否则还有很多其他方法:
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.
答案 2 :(得分:0)
这将以一种可怕的方式打破封装(你实际上是禁用了类B
逻辑的某些部分),而且它在Java中是不可能的。我很确定这是不可能的。
答案 3 :(得分:0)
是的,它并不是真的可以用于标准" java方式,也是一个糟糕的设计决定,但OP可能无法访问原始类。我曾多次用不同的罐子面对这个问题。
如果你想在其中一个超类中跳过例如一个私有方法调用,但仍然需要构造函数代码的其他部分或超类的功能,那么唯一的" easy"这样做的方法是基本上将代码的那部分复制粘贴到你自己的类中。例如,如果您有这些类:
public class Foo {
public Foo() {
importantFunctionality();
}
private void importantFunctionality() {
System.out.println("DOING IMPORTANT STUFF");
}
}
public class Bar extends Foo {
public Bar() {
super(); //constructor gets called
killAllBabies(); //I dont want this to get called, but its a private method meaning no overriding
solveWorldHunger(); //I want to call this, but this is a private method, so no calling this from child classes
}
private void killAllBabies() {
System.out.println("KILLING ALL BABIES");
}
private void solveWorldHunger() {
System.out.println("SOLVING WORLD HUNGER");
}
}
public class MyClass extends Bar {
public MyClass() {
super(); //Not good, because stuff I dont want gets called here
}
}
解决这个问题的唯一方法是跳过"跳过"上一个类并扩展原始类并实现跳过的类的功能。不幸的是,由于可扩展性差,这对我们来说是个问题:
public class MyClass extends Foo {
public MyClass() {
super();
solveWorldHunger();
}
private void solveWorldHunger() {
System.out.println("SOLVING WORLD HUNGER");
}
}