I have a class that extends another class. Depending on a user's input, if the input "A" then the class needs to be a subclassA, but if they input "B" it will be a subclassB. I have a variable that needs to be the main class. I can't access the subclass' methods because the variable I defined is from the main class. How can I get this to work?
Here is a broken down example. The myClass variable is used elswhere, so I need it to be available as the subclass everywhere.
public class Programm
{
private static MainClass myClass;
public static void main(String args[])
{
if (input == 'A') {
myClass = new SubClassA();
myClass.subClassAMethod(); // Can't do this becuse subClassAMethod isn't in MainClass
} else {
myClass = new SubClassB();
myClass.subClassBMethod(); // Can't do this becuse subClassBMethod isn't in MainClass
}
}
}
I know i could put the subClassAMethod and subClassBMethod in the main class, but I don't want to be able to call those methods if it's not part of the subclass.
Is there anyway to make the myClass be declared to accept both SubClassA and SubClassB?
This says: The variable
myClassexists and is constrainted to either point atnull, or point at an instance of a class such that this class is eitherMainClass, or some subtype thereof.The way java is set up, is that java will therefore straight up refuse to compile any interaction with this variable unless it makes sense in all possible scenarios.
In other words, even if you can prove beyond all doubt that at some point in your code's flow, this variable must necessarily be pointing at an instance of
MySubClassB, the compiler doesn't care about that.Your code style is suspect. This isn't how you java.
Note that
myClassas a variable name is just screaming 'I do not understand how any of this works'. It's highly misleading: A variable can only reference an instance, not a class.As a sidenote,
staticis being abused in your snippet. Static is usually not necessary for most java projects and a relatively advanced concept. If you don't want to learn its specific implications, that's fine. But then you must not use it.main, for now, has to be static (soon it won't have to be, starting in JDK22+), so the solution is to get away fromstaticimmediately.Here's an example of how you could do it. These snippets use better names for the types and variables in an attempt to make things more clear:
If the code
new SubClassA()and the codemyObject.subClassAMethod()aren't close together then this won't work. You'll have to useinstanceofto check ifmyClass(again, really bad name, that) is the right type. That would look like:This checks if
animalis pointing at an object that is an instance ofDog, or some subtype of the typeDog. If it is NOT, the if does nothing as you'd expect (animal is NOT an instanceof Dog, hence the if does not execute its content). If it IS, a new variableDog dogis created pointing at it, typedDog, so you can invoke dog-only methods on it.Note that usually using
instanceofmeans your code is badly set up. The whole point of having a variableAnimal animalis that it can contain any animal - if your code actually kinda needs that to be a dog, then, it should beDog dog. Or you should have a subclass of whatever this code is, one version that is specifically catering to Dogs with a field defined asDog dogin it. And if it's a method that encodes specifics for many kinds of objects (a big list ofif (animal instanceof Cat cat) doCatThing(); else if (animal instanceof Dog dog) doDogThing();and so on), then that should really be an abstract method in classAnimal, with each implementation ofAnimalproviding an implementation: The file withclass Dogwould contain the dog-specific code, because that's the place where dog specific code is meant to go.Either way, you don't need
instanceof, hence, if you do useinstanceof, that's, especially if beginning coders are doing it, 95%+ a code-style wise very bad way to do it. 'bad' in the sense of: Hard to understand, inflexible (future changes in code requirements, which all non-academic projects always go through, require more effort than you'd think), hard to integrate into existing libraries, generally un-java-like, i.e. - not the way most java coders on the planet would do it, hence needlessly complicating the learning and understanding curve of that code.