Kjara
Kjara

Reputation: 2912

Java: declare attribute as either Java-given or self-written type (maybe with interfaces?)

I have a beginners question concerning Java.

I have a class Thing<T> that has an attribute "attribute". I want the attribute to be either a LinkedList<T> (as given by Java) or a self-defined type named My_Type<T>, depending on the boolean that is given to the constructor of Thing. Like this:

public class Thing<T> {
    private ??? attribute;  // Type is not given yet. How do I do this?

    public Thing(boolean which) {
        if (which)
            attribute = new LinkedList<T>();
        else
            attribute = new My_Type<T>();
    }

   ...
}

Thing has some more methods that use add and remove, which are both implemented for LinkedList and My_Type.

How do I declare my attribute? Declaring it as Object is no option because Object does not know the methods add and remove. I thought about using interfaces, but I don't know how.

If both LinkedList and My_Type were written by me, I could let them both implement the interface LinkedListOrMy_Type<T> which has add and remove as methods. Then, instead of

    private ??? attribute;

I would write

    private LinkedListOrMy_Type<T> attribute;

And everything would be okay. But because I cannot modify the code of LinkedList, I don't know how to work around this. Any suggestions?

Making My_Type implement the List interface (given by Java) is not an option either, because there are so many methods that I would need to implement into My_Type. But I only want add and remove. I know it's a possible workaround - I could let My_Type throw an UnsupportedOperationException in every method of List except add and remove. But I believe I could learn more about good programming if you give me a suggestions that is not as dirty as this!

Upvotes: 0

Views: 169

Answers (3)

khelwood
khelwood

Reputation: 59146

You can't have one field that can be of two different types in Java; the closest you can do is have a field that is some common base type. So you have a few options.

  1. Use a common base type that provides add and remove. The obvious candidate for this is Collection, which is implemented by LinkedList.

  2. Use a common base type that does not provide the methods you want, but cast the object when you need to. In this case you could simply have a field of type Object, and each time you want to make use of your field, you have to cast it to either of the actual types.

  3. Use two fields. This would seem to make more sense - having one variable of two different types is not really how variables work.

  4. Wrap LinkedList and MyType in classes that have a common base type that provides the methods you need.

For instance:

interface WrapperThing<T> {
    void add(T item);
    void remove(T item);
}
class ListWrapperThing<T> implements WrapperThing<T> {
    private List<T> list;
    public ListWrapperThing() {
        list = new LinkedList<T>();
    }
    public void add(T item) {
        list.add(item);
    }
    public void remove(T item) {
        list.remove(item);
    }
}
class MyTypeWrapperThing<T> implements WrapperThing<T> {
    private MyType<T> my;
    public ListWrapperThing() {
        my = new MyType<T>();
    }
    public void add(T item) {
        my.add(item);
    }
    public void remove(T item) {
        my.remove(item);
    }
}

Then you can use a WrapperThing<T> variable much as if it were a variable that could (inside it) contain either a List or a MyType object.

Upvotes: 1

Ray
Ray

Reputation: 3201

Going the interface route seems a good idea. Define your own interface MyInterface and let MyType implement it:

class MyType implements MyInterface

Now here's the trick: LinkedList isn't final! Use OOP to your advantage by extending the JDK class and letting it implement your interface:

class MyLinkedList extends LinkedList implements MyInterface

Let us know if this will do the trick for you...

Upvotes: 1

spa
spa

Reputation: 5195

Well, you could implement the interface List in your type. It is implemented by all list like classes in Java. Of course it offers more methods than you probably need, but you could implement only those you need and throw for example an not implemented exception in others.

Upvotes: 0

Related Questions