开发者

java array of objects and inheritance

开发者 https://www.devze.com 2023-01-24 18:31 出处:网络
I have 3 classes, MainClass with main method, one abstract class named AbstractClass and Subclass which is to be extended with AbstractClass.

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

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号