4

I'm a beginner in Java trying to write a system of party quests for a game that I'm currently writing and I have a few questions I'd like to be answered. I've already gone around and asked other people, but they're not familiar in Java.

In the past I'd tried making a bunch of classes and accessing them with multiple get methods. I found that incredibly tedious to write and thought I could unify them under an abstract class/implemented class. Thus, the code looked more like this ...

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

Of course, this presented difficulties such as being only able to use implemented methods. It didn't allow me to access the class' exclusive methods that I might want to use later on.

Ultimately, what I want to do is to be able to use a single get method to return any of these derived classes, but still retain the ability to just universally use the get method to call methods that they have in common, such as execute, create, end, while simultaneously allowing me to reach out to their exclusive methods specifically. Is there a way to do that, or is it impossible?

If it's still not clear ...

The code I have write now is a base class that is extended to the other classes in the manner ...

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())

I want to write a get method so to rid myself of multiple. What I have right now is ...

DynastyPQ dynastyPQ;    

DynastyPQ getPQ() {
    return dynastyPQ;
}

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

Doing this ...

DynastyPQ pq = new CarnivalPQ();

I can only access DynastyPQ's methods rather than Carnival's methods.

Is there a way to access the exclusive methods while universally being able to execute the four base functions without regard to the type of class, or did I miss something earlier?

tl;dr -> I want one get method that universally returns all classes that inherit from class X; however, I want to be able to access each class's exclusive methods.

user1803551
  • 12,965
  • 5
  • 47
  • 74
Jacob Macallan
  • 959
  • 2
  • 8
  • 29
  • `CarnivalPQ pq = new CarnivalPQ();`? Is that what you're looking for? – JB Nizet Dec 25 '15 at 22:28
  • Unfortunately, no, because then my getPQ() method would have to return specifically a CarnivalPQ; however, the problem I'm having is if I create a bunch of other classes that inherit from the base or abstract class, I want to be able to access them all universally instead of having a getMethod for each and every single one of them. – Jacob Macallan Dec 25 '15 at 22:29
  • What is this getPQ() method for? What does it do? What feature does it have that new CarnivalPQ() doesn't have? Post the code. – JB Nizet Dec 25 '15 at 22:32
  • The issue is that I want to use my getMethod() to return any type of class that implemented my abstract class so that I can have a unifying get method. The problem I have is that this only gives me availability to the implemented methods, and not any exclusive methods the class may have. By doing CarnivalPQ = new CarnivalPQ(), I'm taking away my ability to have a getMethod that returns the derived classes. I want it to be able to return XPQ or YPQ or even ZPQ. So long as they inherit from the original PQ. – Jacob Macallan Dec 25 '15 at 22:34
  • For you to use the exact type of subclass you want when it is returned from a method call, the compiler must know during compile time what it is. However, since a method can only return 1 type then there is no way for you to use it as multiple subclasses. Does that makes sense to you? – user1803551 Dec 25 '15 at 22:38
  • 1
    I understand what you want. But why don't you answer my questions, and post the code? – JB Nizet Dec 25 '15 at 22:45
  • Its feature is that it's able to return different types of classes that inherit from a base class; its problem is that it lacks the exclusive accessibility that new CarnivalPQ() gives. – Jacob Macallan Dec 25 '15 at 23:14

2 Answers2

0

You can probably just cast the object to the derived class:

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

If you don't know what is the dynamic type (the type you used after the new operator), you can use the instanceof keyword:

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.
}

If you don't want to do that, you can use polymorphism:

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.
    }
}

Now, you can do:

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

The called method will be CustomAPQ::specific1(). If specific1() was not declared in CustomAPQ, then, it will just do nothing.

Celine NOEL
  • 155
  • 9
  • This does allow me to use a one method to return the PQs; however, in the end it's not much different from using a bunch of getMethods in the end. – Jacob Macallan Dec 25 '15 at 22:55
  • If the static type of your object is DynastyPQ, you can only call methods that are declared in DynastyPQ. If you don't want to implement it, you can make it abstract and set your class as abstract too. I can write an example if you want. – Celine NOEL Dec 25 '15 at 23:02
  • Yes, please. I would like to see an example. – Jacob Macallan Dec 25 '15 at 23:09
  • Is there a way for me to retrieve the type of a variable's value so that I can use it in a cast? For an example ... DynastyPQ pq = new CarnivalPQ(); Is there a way for me to get CarnivalPQ's type so that I can cast pq? – Jacob Macallan Dec 25 '15 at 23:19
  • No, because the dynamic type is only known at runtime, and your casts are inside your code (no magic here). However, if you perfectly know that the DynastyPQ you will get is a CarnivalPQ, you can cast it directly. – Celine NOEL Dec 25 '15 at 23:34
0

Other than @CelineNOEL suggested it is not possible. Because you declared a class of type DynastyPQ, you can call only methods defined inside that class. In the moment you want to call specific method, not shared one, you know from which class it is and you can use casting to call that specific method.

((CustomAPQ)pq).customAPQmethod()

Shared methods you are using in code, when you don't know which class should execute same peace of code(or you want it to execute it different if you override share methods in every sub-class), and you delegate it to be resolved in runtime. So reconsider your design and in base class put methods that needs to be called dynamically. All other methods you are sure are specific for one class put only in that class. On that way your code will be cleaner and you will not mess thing that should be separated.

mommcilo
  • 956
  • 11
  • 28