What I would like is to be able to create a variable with the superclass and then 'turn' it into the subclass later & be able to access the subClasses methods. It will always be defined to a subclass I just don't know which when defining.
class SuperClass {
//superclass methods
}
class SubClass1 extends SuperClass {
void subClass1method() {
//do something
}
}
class SubClass2 extends SuperClass {
void subClass2method() {
//do something different
}
}
class Main {
public static void main ( String [] args ) {
SuperClass a;
if (*some reson to be SubClass1*) {
a = new SubClass1();
a.subClass1Method(); //this is undefined it says
//a instanceof SubClass1 returns true which is what confused me
} else {
a = new SubClass2();
a.subClass2Method(); //this is undefined it says
}
}
}
I am not asking why it does this but the correct way to work around it & get the results I want.
I have looked for duplicates but could have easily missed one so please let me know.
When you don't have control of the source then there's not too much you can do besides casting (or possibly using adapters). If instanceof
and casting sound familiar from your lessons then that's probably what your prof is expecting.
Here are some of your options:
// to execute those subclass specific methods without casting..
public static void main ( String [] args ) {
SuperClass superClass;
if (true /*some reson to be SubClass1*/) {
SubClass1 subClass1 = new SubClass1();
subClass1.subClass1Method();
superClass = subClass1;
} else {
SubClass2 subClass2 = new SubClass2();
subClass2.subClass2Method();
superClass = subClass2;
}
// ... ...
}
// using instanceof and casting
public static void main ( String [] args ) {
SuperClass superClass;
if (true /*some reson to be SubClass1*/) {
superClass = new SubClass1();
} else {
superClass = new SubClass2();
}
// ... ... ...
if(superClass instanceof SubClass1) {
((SubClass1) superClass).subClass1Method();
} else if(superClass instanceof SubClass2) {
((SubClass2) superClass).subClass2Method();
}
}
Below is my recommendation to achieve this goal when you have control of the source..
Rather than a new class for different behaviors you could just use composition to provide different behaviors to the one class. Note that this is especially convenient if you understand Functional Interfaces and Method References.
public class SuperClass {
private MyBehavior behavior;
public void setBehavior(MyBehavior behavior) { this.behavior = behavior; }
public void doBehavior() { this.behavior.doBehavior(); }
}
public interface MyBehavior { public void doBehavior(); }
public class MyGoodBehavior implements MyBehavior {
@Override public void doBehavior() { System.out.print("good behavior"); }
}
public class MyBadBehavior implements MyBehavior {
@Override public void doBehavior() { System.out.print("bad behavior"); }
}
public static void main(String[] args) {
SuperClass a = new SuperClass();
a.setBehavior(new MyBadBehavior());
a.doBehavior();
}