0

I created a little example. Imagine I have two classes:

public class Neuron {
    ArrayList<Neuron> neighbours = new ArrayList<>();
    int value = 1;

    public Neuron() {

    }

    public void connect(ArrayList<Neuron> directNeighbours) {
        for (Neuron node : directNeighbours) {
            this.neighbours.add(node);
        }
    }

}

and a class that inherits from Neuron:

public class SpecialNeuron extends Neuron {

    int value = 2;

    public SpecialNeuron() {

    }
}

In my case, I want the inheritance in order to avoid a lot of "if object is special do something" stuff. However, when I am calling:

public static void main(String[] args) {
    ArrayList<Neuron> neurons = new ArrayList<>();

    Neuron a = new Neuron();
    Neuron b = new Neuron();
    Neuron c = new Neuron();
    neurons.add(b);
    neurons.add(c);

    a.connect(neurons);

    ArrayList<SpecialNeuron> special = new ArrayList<>();
    SpecialNeuron d = new SpecialNeuron();
    SpecialNeuron e = new SpecialNeuron();
    special.add(d);
    special.add(e);

    a.connect(special); //Error
}

it is not possible to use a List(SpecialNeuron) for a List(Neuron) parameter. What is wrong with this call, and is there a proper way to solve that issue? Furthermore, I could do

ArrayList<Neuron> special = new ArrayList<>();
Neuron d = new SpecialNeuron();
Neuron e = new SpecialNeuron();
special.add(d);
special.add(e);

a.connect(special); //works fine

Which works, but denies any usage of functions from the SpecialNeuron class.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Ollowain
  • 55
  • 6
  • Does this answer your question? [How to cast a list of inheriting objects to a collection of objects in Java?](https://stackoverflow.com/questions/2754756/how-to-cast-a-list-of-inheriting-objects-to-a-collection-of-objects-in-java) – Umair Mubeen Jan 28 '21 at 17:33
  • You have to either cast the particular SpecialNeurons from Neuron to that class, or you use a method common to all Neurons that you override in class SpecialNeuron. Polymorphism will then call the correct version for you. – Jems Jan 28 '21 at 17:35
  • @Jems I implemented empty methods in the Neuron class which will be overwritten in the Special Neuron class. It enables me to call the methods due to Polymorphism. Thanks for the idea :) – Ollowain Jan 29 '21 at 12:33
  • Should I delete the question because it seems that I cant determine a concrete solution rather a workaround? – Ollowain Jan 29 '21 at 12:34

2 Answers2

1

You can make use of WildCards in Generic <? extends T>.You can read more about it here.

Change your method param to this.

  public void connect(ArrayList<? extends Neuron> directNeighbours) {
        for (Neuron node : directNeighbours) {
            this.neighbours.add(node);
        }
    }
Nawnit Sen
  • 973
  • 2
  • 7
  • 14
  • Very interesting feature. It worked for the given example but not for my own project. My fault due to the lack of explaination. – Ollowain Jan 30 '21 at 20:49
0

First of all, you're extending Neuron class, but you're not really using inheritance. You should make value variable protected and set its value in constructor.

public class Neuron {
    protected int value;

    public Neuron() {
        this.value = 1;
    }
}

public class SpecialNeuron extends Neuron {
    public SpecialNeuron() {
        this.value = 2;
    }
}

Now, your problem is on the line 17 - ArrayList<SpecialNeuron> special = new ArrayList<>(); - you have List of SpecialNeuron objects, that are children of Neuron class, so Java knows it contains only objects of class SpecialNeuron

In your connect() function, you accept only Neuron class objects, so in order to make it work, you have to change your special list to:

ArrayList<Neuron> special = new ArrayList<>();

In this List, you can add Neuron and SpecialNeuron objects and use it as a List of Neuron objects.

AP11
  • 617
  • 4
  • 11
  • You are right but then I can not address methods of the Special Neuron which are unique for that class. – Ollowain Jan 29 '21 at 00:06