Sahil
Sahil

Reputation: 9496

Explanation behind the compile time error wrt java generic?

I am working on the design problem, where I have to design a deck of cards. Here is how my classes look like

public interface ISuit {
    String getLogo();
    String getName();
}

public interface Icard<T extends ISuit> {
    T getSuit();
    String getNumber();
}

Now, I want to write a class for each of the 13 cards, something along the lines of this

public  class Queen<E extends ISuit> implements Icard<E> {
    @Override
    public String getNumber() {
        return "12";
    }

    @Override
    public E getSuit() {
        return new E;
    }

}

I intend to create object of Queen like this
1: Queen<Hearts> queenOfhearts = new Queen<Hearts>();

However, for my queen class, I have a compile time error for getSuit. I don't know what is supposed to be the definition of getSuit. Is this function supposed to be made abstract?

Upvotes: 0

Views: 71

Answers (3)

Tomek
Tomek

Reputation: 543

Make Queen an abstract class that implements getNumber(). Implement getSuit() in derived classes like QueenHearts.

Upvotes: 0

Konstantin Yovkov
Konstantin Yovkov

Reputation: 62874

At runtime, if you want to instantiate a generic type T, you have to have the Class<T> object.

You can change the signature of the getSuit(..) method to:

public E getSuit(Class<E> clazz);

Then, the implementation would be:

public E getSuit(Class<E> clazz) {
    try {
        return clazz.newInstance();
    } catch (InstantiationException | IllegalAccessException e) {
    // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

Even better, in order to get rid of the Class<T> parameter of the method, you can pass it to the class's constructor and persist it to a private member. For example:

public  class Queen<E extends ISuit> implements Icard<E> {
    private Class<E> clazz;

    public Queen(Class<E> clazz) {
        this.clazz = clazz;
    }

    public String getNumber() {
        return "12";
    }

    public E getSuit() {
        try {
            return clazz.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

Upvotes: 1

NoseKnowsAll
NoseKnowsAll

Reputation: 4624

First off, I believe that your idea of how to go about the problem is incorrect from an object oriented approach. You want to have Card be a class with two instance variables: number and suit.

Then, in order to have each of the 13 cards, you create 13 objects and give them the correct card number/suit. For instance,

Suit hearts = new Suit("Hearts");
Card queenHearts = new Card(12,hearts);

As to the actual reason behind your compile time error, take a look at Instantiating object of type parameter .

Upvotes: 0

Related Questions