Java 使用反射向自身声明对象

Java 使用反射向自身声明对象,java,jakarta-ee,Java,Jakarta Ee,不确定标题,但下面是: 我有一门课要扩展,比如: public class A{ public void methodThatDoesStuff(){ //Uses AA here } protected class AA{ //does most of the stuff here } } public class B extends A{ public class BB extends AA{ } } 如

不确定标题,但下面是:

我有一门课要扩展,比如:

public class A{

    public void methodThatDoesStuff(){
        //Uses AA here
    }

    protected class AA{
        //does most of the stuff here
    }
}

public class B extends A{
    public class BB extends AA{
    }
}
如你所见。方法that doestuff使用AA,但当调用B时,我希望它使用BB

这样做的原因是AA有一些对所有类都通用的变量。但也有一些不同。内部类是具有@Expose变量、setter和getter的JSONObject


如何在超类中指定要使用的类?

您不能指定要在超类中使用的类,因为超类没有继承自超类的类的信息。在超类中定义
AA
类型的变量,并使用构造函数或setter在运行时设置适当的实例。演示:

public class A {
    protected AA serviceVar;

    public A() {
        this.serviceVar = new AA();
    }

    public void methodThatDoesStuff() {
        System.out.println(serviceVar);
    }

    protected class AA {
        protected String message;

        public AA() {
            message = "AA";
        }

        public String toString() {
            return message;
        }
    }
}

public class B extends A {
    public B() {
        this.serviceVar = new BB();
    }

    public class BB extends AA {
        public BB() {
            this.message = "BB";
        }
    }
}

public class Test {
    public static void main(String[] args) {
        A a = new A();
        A b = new B();
        a.methodThatDoesStuff();
        b.methodThatDoesStuff();
    }
}

如您所见,当您实例化
A
时,根据
AA
的不同,方法
methodthattestuff
打印出消息,而当您实例化
B
时,它使用
BB
。您可以使用
serviceVar
来分别从
AA
或它的一些子类中获取功能。这意味着您在
方法中使用此变量,该方法不需要设置

通常的方法是定义一个函数来创建AA对象,子类可以覆盖这些对象。这允许子类创建对象,如果需要,这些对象是AA的子类

public class A{

    public void methodThatDoesStuff(){
        AA aa = getAA();
        // use aa
    }

    protected class AA{
        //does most of the stuff here
    }

    // Function to create AA instances. Subclasses
    // can override this.
    protected AA getAA() {
        return new AA();
    }
}

public class B extends A{
    public class BB extends AA{
    }

    @Override
    protected AA getAA() {
       return new BB();
    }
}

这感觉像是一场灾难。你到底想干什么?定义一个
AA
接口,并在
a
中放置一个arg构造函数以获取它?你是对的,我将改变这个问题,什么实际替换
在这里使用AA
?我仍然不明白你在这里想要什么。为什么不
public-void-methods-that-that-sstuff(AA-AA)
那么您的调用者可以将
BB
传递给它。也可以阅读更多关于多态性的内容;)我不确定是否有足够的信息来明确回答这个问题,因为提问者还没有充分说明他真正想要什么。至少先解释一下你认为他想要什么,然后再说“你不能在超类中指定它”,这可能不是真的,这取决于问题的解释方式。当你说“你不能在超类中指定它”时,确切的“那”是什么你指的是什么?我想很清楚他到底想要什么。他在MethodThatThatsTuff中使用了AA的功能,但他想用BB替换子类实例B中AA的行为。因为没有静态继承,你需要有一个变量来实现这一点,这是一种解决问题的方法。不清楚——请阅读我上面的评论。此外,取决于它是内部类还是嵌套类,将从根本上影响“正确”的体系结构,因为嵌套类可能通过泛型完成。