继承自基类的类的问题 (Java)

4

我是一个Java初学者,正在尝试为我正在编写的游戏编写一套副本任务系统,我有几个问题需要解答。我已经询问了其他人,但他们对Java并不熟悉。

过去,我曾尝试创建一堆类,并使用多个get方法访问它们。我发现这样写非常乏味,认为可以将它们统一在一个抽象类/实现类下。因此,代码看起来更像是这样的...

DynastyPQInterface pq = new CustomPQ // or ....
DynastyPQInterface pq = new OtherCustomPQ

当然,这样做也带来了一些困难,例如只能使用已实现的方法。它不允许我访问类的专有方法,而我可能在以后想要使用它们。
最终,我想做的是能够使用单个获取方法返回任何这些派生类,但仍然保留通用使用获取方法调用它们共有的方法(如执行、创建、结束),同时允许我专门访问它们的专有方法。是否有办法做到这一点,或者说这是不可能的?
如果仍然不清楚...
我现在编写的代码是一个基类,按照以下方式扩展到其他类中...
DynastyPQ (base) -> methods include (run(), execute(), end())
CustomAPQ (inherited from DynastyPQ) -> (has exclusive methods like getPoints())
CustomBPQ (inherited from DynastyPQ) -> (has exclusive methods like revivePlayer())

我想编写一个“get”方法来解决我的多次重复问题。我现在拥有的是...
DynastyPQ dynastyPQ;    

DynastyPQ getPQ() {
    return dynastyPQ;
}

void setPQ(DynastyPQ pq) {
    dynastyPQ = pq;
}

Doing this ...

DynastyPQ pq = new CarnivalPQ();

我只能访问DynastyPQ的方法,而不能访问Carnival的方法。

有没有一种方法可以在普遍执行四个基本函数的情况下访问专属方法,而不考虑类的类型,或者我之前错过了什么?

简而言之,我想要一个获取方法,它能普遍返回所有继承自类X的类;但是,我也想要能够访问每个类的专属方法。


"CarnivalPQ pq = new CarnivalPQ();"?这是您要找的吗? - JB Nizet
很遗憾,不行。因为这样我的getPQ()方法必须专门返回CarnivalPQ;然而,我遇到的问题是如果我创建了许多其他从基类或抽象类继承的类,我希望能够普遍地访问它们,而不是为每一个类都创建一个getMethod。 - Jacob Macallan
这个getPQ()方法是做什么的?它有什么作用?它有哪些新CarnivalPQ()没有的功能?发布代码。 - JB Nizet
为了在方法调用返回子类时使用您想要的确切类型,编译器必须在编译时知道它是什么。然而,由于一个方法只能返回1个类型,因此无法将其用作多个子类。这对您有意义吗? - user1803551
1
我理解您想要什么。但是为什么您不回答我的问题并且发布代码呢? - JB Nizet
显示剩余2条评论
2个回答

0

你可以直接将对象转换为派生类:

DynastyPQ pq = new CustomAPQ();
((CustomAPQ)pq).customAPQmethod();

如果您不知道什么是动态类型(即在new操作符后使用的类型),您可以使用instanceof关键字:
DynastyPQ pq = getPQ();
if (pq instanceof CustomAPQ) {
    CustomAPQ a = (CustomAPQ)pq;
    a.customAPQmethod();
} else if (pq instanceof CustomBPQ) {
    CustomBPQ b = (CustomBPQ)pq;
    b.customBPQmethod();
} else {
    // Neither a CustomAPQ nor a CustomBPQ.
}

如果你不想这样做,你可以使用多态:

class DynastyPQ {
    final void run() {
        // code.
    }
    final void execute() {
        // code.
    }
    final void create() {
        // code.
    }

    void specific1() {}
    void specific2() {}
}

class CustomAPQ extends DynastyPQ {
    @Override
    void specific1() {
        // do stuff specific to CustomAPQ.
    }
    @Override
    void specific2() {
        // do stuff specific to CustomAPQ.
    }
}

class CustomBPQ extends DynastyPQ {
    @Override
    void specific1() {
        // do stuff specific to CustomBPQ.
    }
    @Override
    void specific2() {
        // do stuff specific to CustomBPQ.
    }
}

现在,你可以做:

DynastyPQ pq = new CustomAPQ();
pq.specific1();

调用的方法将是CustomAPQ::specific1()。如果CustomAPQ中没有声明specific1(),那么它将什么也不做。

这确实允许我使用一个方法来返回PQs;然而,最终与最终使用一堆getMethods并没有太大区别。 - Jacob Macallan
如果您的对象的静态类型为DynastyPQ,则只能调用在DynastyPQ中声明的方法。如果您不想实现它,可以将其设置为抽象,并将您的类也设置为抽象。如果需要,我可以提供一个示例。 - Celine NOEL
是的,请。我想看一个例子。 - Jacob Macallan
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Jacob Macallan
不行,因为动态类型只有在运行时才能确定,而你的强制转换是在代码内部进行的(这里没有魔法)。但是,如果你完全知道你将得到的DynastyPQ是CarnivalPQ,那么你可以直接进行强制转换。 - Celine NOEL

0

除了@CelineNOEL提出的建议外,这是不可能的。因为您声明了一个类型为DynastyPQ的类,您只能调用在该类内定义的方法。当您想要调用特定方法而不是共享方法时,您知道它来自哪个类,并且可以使用强制转换来调用该特定方法。

((CustomAPQ)pq).customAPQmethod()

在编程中,当您不知道哪个类应该执行相同的代码段(或者如果您想要在每个子类中覆盖共享方法,则希望它执行不同的操作),您可以使用共享方法。然后将其委托以在运行时解决。因此,请重新考虑您的设计,并在基类中放置需要动态调用的方法。您确定是特定于一个类的所有其他方法仅放在该类中。通过这种方式,您的代码将更加清晰,而且不会混淆应该分开的事物。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接