user6837118
user6837118

Reputation:

One array containing different Object classes

So I've got an Object class Item and an Object class Trap. These two share variables called name and icon. I want to be able to put both of these classes into one array called special and be able to access the components of Item and Trap by using special. Here's my code that I need to work.

if (special[x][y] == null)
    return 0;
System.out.print(special[x][y].icon);    /* here's where the issue is */
return 1;

What should special be an array of? Should I use an interface? And if so, how? I've been reading everywhere but I don't know how to describe my problem.

Upvotes: 0

Views: 56

Answers (6)

Raman Sahasi
Raman Sahasi

Reputation: 31901

public class Entity {
    String name;
    Icon icon;
}

public class Item extends Entity {
    ...
    ...
}

public class Trap extends Entity {
    ...
    ...
}


Entity[][] special = new Entity[5][10];

and now you can insert either of the two classes in special 2D array and you can use the exact same code that you've supplied in your question.

if (special[x][y] == null)
    return 0;
System.out.print(special[x][y].icon);    /* here's where the issue is */
return 1;

Upvotes: 0

Mike Nakis
Mike Nakis

Reputation: 62159

Give this a try:

class Base 
{
    String name;
    Icon icon;
}

class Item extends Base { }

class Trap extends Base { }

List<Base> special = new ArrayList<>();

alternatively, you can make Base an interface, and use the implements keyword instead of extends for Item and Trap.

Upvotes: 3

John Bollinger
John Bollinger

Reputation: 181849

What should special be an array of? Should I use an interface? And if so, how?

If you want an array that can accommodate elements of two different types, then its element type must be a supertype of both. That could be an interface that both types implement, or a superclass of both.

I'd encourage you to access the members via accessor methods (e.g. getIcon()). If you insist on accessing them directly, as in your example, then the interface option is not possible, and the members you want to access must belong to the superclass (or one of its superclasses).

For example,

public interface GameObject {
    String getName();
    Icon getIcon();
}

public class Trap implements GameObject {

    private final String name;
    private final Icon icon;

    public Trap(String name, Icon icon) {
        this.name = name;
        this.icon = icon;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public Icon getIcon() {
        return icon;
    }
}

(... and similar for Item ...)

    GameObject[][] special = /* ... */;

    // ...

    if (special[x][y] == null) {
        return 0;
    }
    System.out.print(special[x][y].getName());
    return 1;

Upvotes: 0

Pedro Pinto
Pedro Pinto

Reputation: 179

You should use an Interface

public interface SpecialInterface{
   //you actually do not need any code, usually interfaces are called something+able 
   String getIcon();//this method will be filled in all the objects implementing this interface
}

So now you implement the interface in both your classes, for example:

public class Trap implements SpecialInterface{
   //...
}

Now that you want to iterate your items and traps, you can do something like:

System.out.println(special[x][y].getIcon());

or..

if(special[x][y] instanceof Trap){
   Trap oneTrap = (Trap) special[x][y]; //here you transform your    SpecialInterface object in a Trap object
   System.out.println(special[x][y].icon);
}else{
   Item oneItem = (Item) special[x][y];
   System.out.println(special[x][y].icon);
}

Note: Your Trap and Item objects should be declared like:

SpecialInterface trap = new Trap();

or

SpecialInterface item = new Item();

Otherwise you can't insert this objects in your matrix.

Upvotes: 0

flakes
flakes

Reputation: 23684

Make an interface for Item and Trap which contains the methods they should share.

public interface GameObject {
    String getName();
    Image getIcon();
}

You can then create the Item and Trap classes by implementing this interface. For example

public class Trap implements GameObject {
    private String name;
    private Image icon;
    public GameObject(String name, Image icon) {
        this.name = name;
        this.icon = icon;
    } ...

By declaring this class implements GameObject it means we have to create the getName and getIcon methods. You do this by using an @Override annotation.

public class Trap implements GameObject {
    private String name;
    private Image icon;
    public GameObject(String name, Image icon) {
        this.name = name;
        this.icon = icon;
    } 

    @Override
    public String getName() {
        return name;
    }
    @Override
    public Image getIcon() {
        return icon;
    }
}

Now that it implements GameObject we can add it to a list that holds GameObject types

List<GameObject> special = new ArrayList<>();
myList.add(new Trap(myTrapName, myTrapImage));
myList.add(new Item(myItemName, myItemImage));

We can then call the methods without worrying if that particular GameObject is an Item or a Trap

for (GameObject obj : special) {
    System.out.println(obj.getName());
}

Upvotes: 0

Brydenr
Brydenr

Reputation: 798

One way that may work is to use a superclass (class, abstract class, interface all work). This is a bad name for the superclass, but I'm sure that you will get the idea:

public class Thing {
    String icon; // Every class that extends Thing has an icon
    String name; // Every class that extends Thing has a name

    public Thing(String newIcon, String newName) {
        icon = newIcon;
        name = newName;
    }

    public String getIcon() {
        return this.icon;
    }

    public String getName() {
        return this.name;
    }
}

public class Trap extends Thing {
    public Trap() {
        super("newIcon", "newName"); // Sets this Traps's name and icon values
    }
}

public class Item extends Thing {
    public Item() {
        super("newIcon", "newName"); // Sets this Item's name and icon values
    }
}

You can add whatever methods/variables that you want to Trap and Item, and, as long as they are legal in and of themselves, they will work.

Upvotes: 1

Related Questions