Question

I have these class

  • Concept
  • Link, Relation (which extends Concept)
  • Concepts
  • Links, Relations (which should extends Concepts)

The class Concepts should have a

private List<? extends Concept> list; //or something similar
addConcept(Concept c); // that should work with a (Link) for the class Links

But this doesn't work the way I tried it... And from searching the Internet, it doesn't look like it can work. How can I make a super class for Links and Relations that include the insertion of a Concept into some sort of memory holder.

This ... doesn't work

public class Concepts{
    protected List<? extends Concept> list = null;
    Concepts(String text) {
    }
    public void add(Concept test) {
        list.add(test);
    }
}
public class Links extends Concepts{
    Links() {
        list = new List<Link>();
    }
    public void add(Link test) {
        list.add(test);
    }
}

.... I want (if possible) to make it impossible to add Relation into Links or Link into Relations

Was it helpful?

Solution 2

My proposition with Generics:

public class AbstractConcepts<T extends Concept> {
    private List<T> list = new ArrayList<>();

    public void add(T test) {
        list.add(test);
    }
}

public class Concepts extends AbstractConcepts<Concept> {
    Concepts(String text) {
    }
}

public class Links extends AbstractConcepts<Link> {
}

In this case, code bellow doesn't compile, so you can't add Relation to Links:

new Links().add(new Relation());

OTHER TIPS

You cannot accomplish what you're trying to do. You must wonder why you can't add things of type Concept to your List<? extends Concept>. Here is why:

Consider this case:

List<? extends Concept> list = new List<Link>();

And that you have another class that also extends Concept besides Link, let's call it Link2:

public class Link2 extends Concept { ... }

Then here comes the problem. What if you do:

Link2 myLink2 = new Link2();
list.add(myLink2);// Big problem, remember that your list was instantiated as a list of Links not Link2s.

So that's why you cannot add items to a list of wildcard types like that, because you might try to add something to it that will simply not work with the list type it was instantiated as.

Now, my suggestion for what you're trying to do. Make your base class generic and then your extending classes only have to specify the concrete type it will handle. Something like this:

public class Concepts<T extends Concept> {
     private List<T> list = new List<T>();

     public void add(T test) {
         list.add(test);
     }
}

public class Links extends Concepts<Link> {
}

If I have understood you correctly, a Link is also a Concept (extends Concept), so you can use a List to store both Link and Concept objects, like in this code:

public class Concept{
    Concept(String text) {
    }
}

public class Link extends Concept{

    Link(String text) {
        super(text);
    }
}

import java.util.List;
public class Concepts{
    protected List<Concept> list = null;

    Concepts(String text) {
    }
    public void add(Concept test) {
        list.add(test);
    }
}

public class Links extends Concepts{
    Links(String text) {
        super(text);
    }
    public void add(Link test) {
        list.add(test);
    }
}

Hope it helps

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top