java array of objects and inheritance
I have 3 classes, MainClass with main method, one abstract class named AbstractClass and Subclass which is to be extended with AbstractClass.
The array of objects is created in main method from type AbstractClass containing 1 member. Then I initialize that 1 element of array as type Subclass( is this ok?). The problem is I can't get to the getDataToExport() method of created object ( array[0] ) . I suspect the problem occurs because the array is the AbstractClass type... And the question: is this even possible to accomplish? What I'm trying to do is use an array of type AbstractClass and fill it with objects made from different subclasses( in this code is just one->Subclass ) extended with AbstractClass but i can't get to the methods of that subclasses.
main class with main method
public class MainClass {
publ开发者_如何学Goic static void main() {
AbstractClass array[]=new AbstractClass[1];
array[0]= new Subclass(); // is this even allowed?
System.out.println(array[0].getDataToExport()); // Problem!
}
}
abstract class
public abstract class AbstractClass {
}
Subclass which extends AbstractClass
public class Subclass extends AbstractClass {
private int dataToExport;
public Subclass(){
this.dataToExport=2;
}
public int getDataToExport() {
return dataToExport;
}
}
AbstractClass array[]=new AbstractClass[1]; array[0]= new Subclass(); // is this even allowed?
Yes, that's fine, but it means that when you later go to use it, you only have access to what's defined in AbstractClass
(barring using a cast, but you want to avoid using casts wherever you can, and there's no need for one here).
The only real reason for making the array entries of type AbstractClass
would be if you only want to interact with the members defined in that class. So for instance, in this case, you'd probably want to have the getDataToExport
defined as an abstract method in the abstract class:
public abstract class AbstractClass {
public abstract int getDataToExport();
}
You might also consider looking at having an interface rather than an abstract class. Since a class can only derive from one base class, but can implement as many interfaces as it likes, unless there's a large body of common implementation that you'd be putting in the abstract base class, you're better off with an interface — because it doesn't put unnecessary constraints on the implementations of that interface. In fact, you're almost always better off with an interface; you can always also have an abstract base if you want.
So for instance:
public class MainClass {
public static void main() {
NiftyThingy array[]=new NiftyThingy[1];
array[0]= new NiftyThingyImplementation();
System.out.println(array[0].getDataToExport());
}
}
where
public interface NiftyThingy {
public int getDataToExport();
}
and
public class NiftyThingyImplementation implements NiftyThingy {
public int getDataToExport() {
return /* ... the data ... */;
}
}
You must declare getDataToExport() as an abstract method in AbstractClass.
You won't be able to get it because you are declaring an array of AbstractClass in order to see them you have two choices
Declare the common methods that you will use on the abstract class and declare them abstract. Override those methods in the subclasses. For example:
public abstract class AbstractClass { public abstract int getDataToExport(); }
And every subclass will have to override that method or should be declared abstract too.
Create an array of Sublclass:
Subclass array[] = new Sublcass[1]; array[0] = new Subclass(); System.out.println(array[0].getDataToExport());
Yes, all this is perfectly fine. The only step you have missed is that you need to cast the instance of the object to the type that has the method you want. The usual way to do this is:
AbstractClass ac = array[0];
if (ac instanceof Subclass) {
System.out.println(((Subclass)ac).getDataToExport()); // No problem!
}
However you might want to think about doing this another way. For example, implement a default version of getDataToExport in the abstract class that returns null. That way you don't have to do the cast or the instanceof test.
AbstractClass array[]=new AbstractClass[1];
array[0]= new Subclass(); // is this even allowed?
Indeed is valid as SubClass
is a derived class of AbstractClass
. The reason why
System.out.println(array[0].getDataToExport());
fails is because the compiler cannot find AbstractClass.getDataToExport()
method. It's only SubClass
that has the method and not its parent.
There are couple of ways to solve this:
Add an abstract method getDataToExport
to the AbstractClass
like so:
public abstract class AbstractClass {
public abstract int getDataToExport();
}
OR, Typecast your variable to its derived (concrete) class that has the getDataToExport()
method, like so:
if (array[0] instanceof SubClass) {
System.out.println(((SubClass)array[0]).getDataToExport());
}
the instanceof
operator simply states that the attribute is of a class X (where X is SubClass
).
精彩评论