Java - passing shared lists to a class through a constructor

I tried to play with generics and polymorphism. I ran into a problem that I canโ€™t lower my head.

Say I have

public abstract class Animal {
    private age;
    private weight;

    public Animal(){}

    public void Move(){
        //stuff
    }

    public void Eat(){
        //stuff
    }

    //Getters and setters
}

And then

public Cat extends Animal {
    //Constructors
}

public Snake extends Animal {
    //Constructors
    public void ShedSkin(){
        //stuff
    }
}

I also have my own class "MyAbstractClass". Here I seem to be unable to figure it out.

public abstract class MyAbstractClass {
    private List<Animal> myAnimalList;

    public MyAbstractClass(){}

    public MyAbstractClass(List<? extends Animal> animalList) {
        this.myAnimalList = animalList;
    }

    public List<Animal> getAnimalList() {
        return myAnimalList;
    }

    //Stuff which DOES NOT add to the list
}

I want to be able to do:

public class MyCatClass extends MyAbstractClass {
    public MyCatClass(List<Cat> catList) {
        super(catList);
    }
}

public class MySnakeClass extends MyAbstractClass {
    public MySnakeClass(List<Snake> snakeList) {
        super(snakeList);
    }

    public ShedSkin(){
        (Snake)getAnimalList().get(0).ShedSkin(); //Dont worry about indexing
    }
}

Then

public static void main(string[] args) {
    //Make list of cats
    //Make list of snakes

    MyCatClass cats = new MyCatClass(catList);
    MySnakeClass snakes = new MySnakeClass(snakeList);

    snakes.ShedSkin();
}

This does not work for me. It cannot compile to public MyAbstractClass(List<? extends Animal> animalList). This is a little compared to my experience in Java, and I would really appreciate some recommendations. I hope the class examples are clear enough to understand my intent.

The compiler tells me: java.util.List<Animal> in MyAbstractClass cannot be applied to java.util.List<capture<? extends Animal>> Thank you.

: , , . , , , . , , , . , . , , , , . . , .

EDIT2: !

public abstract class MyAbstractClass {
        private List<? extends Animal> myAnimalList;

        public MyAbstractClass(){}

        public MyAbstractClass(List<? extends Animal> animalList) {
            this.myAnimalList = animalList;
        }

        public List<Animal> getAnimalList() {
            return myAnimalList;
        }

        //Stuff which DOES NOT add to the list
    }

, List<? extends Animal> foobar. !

EDIT3: .

+4
6

, List<? extends Animal> List<Animal>, : .

( getAnimalList()) List<? extends Animal>. , MyCatClass, , , ( List<Animal>, List<? extends Animal>).

: (Snake)getAnimalList().get(0).ShedSkin(), , , . -, : ((Snake) getAnimalList().get(0)).ShedSkin(), -, List<Animal> List<Snake>, , getAnimalList() List<? extends Animal>, .

, , :

public abstract class MyAbstractClass<T extends Animal> {
    private List<T> myAnimalList;
    public MyAbstractClass(List<T> animals) { myAnimalList = animals; }
    public List<T> getAnimalList() { return myAnimalList; }
    //etc.
}

public class MyCatClass extends MyAbstractClass<Cat> {
     public MyCatClass(List<Cat> cats) { super(cats); }
}
public class MySnakeClass extends MyAbstractClass<Snake> {
     public MySnakeClass(List<Snake> snakes) { super(snakes); }
     public ShedSkin() { getAnimalList().get(0).ShedSkin(); }
}

... , , .

+5

:   List<Animal> myAnimalList to private List<? extedns Animal> myAnimalList

public List<Animal> getAnimalList() {
        return myAnimalList;
    } to
 public List<?extends Animal> getAnimalList() {
            return myAnimalList;
        }

: Cat Animal, List<Cat> List<Animal>. java generics List<Cat> List<Animal>. : : List<Animal> animalList= new ArrayList<Cat>(); java . โ€‹โ€‹animalList, . : List<? extends Animal> animalList= new ArrayList<Cat>(); Animal. .

+1

, MyAbstractClass

private List<Animal> myAnimalList;

private List<? extends Animal> myAnimalList;

public MyAbstractClass(List<Animal> animalList){
    // stuff
}
0

MyAbstractClass, .

0

MyAbstractClass, . : () .

, , , MyAbstractClass. , . , , MyAbstractClass, . . , , , ( List<Cat>, List<BigCat>) - , . , , , . , :

public MyAbstractClass(List<? extends Animal> animalList) {
    this.myAnimalList = (List)animalList;
}

MyAbstractClass Animal s, . , , MyAbstractClass. , , , ( Cat Snake Animal, List<Animal - promises, Animal, , ):

public MyAbstractClass(Collection<? extends Animal> animalList) {
    this.myAnimalList = new ArrayList<>(animalList);
}

, , :

public List<Animal> getAnimalList() 
    return Collections.unmodifiableList(myAnimalList);
}

, , ImmutableList Google guava:

public abstract class MyAbstractClass {
   private List<Animal> myAnimalList;

    public MyAbstractClass(){
        this(ImmutableList.of());
    }

    public MyAbstractClass(Collection<? extends Animal> animalList) {
        this.myAnimalList = ImmutableList.copyOf(animalList);
    }

    public List<Animal> getAnimalList() {
        return myAnimalList;
    }

    //Stuff which DOES NOT add to the list
}

, , (a) ( Collections.unmodifiableList, ) (b) ImmutableList.copyOf() , , , , a ImmutableList . - (a), getAnimalList() .

BTW: Java , , shedSkin(), ShedSkin() - #.

0

. .

1) Import the java.util.List package.

2)  another error I find is this.. How don't know your requirement Cannot suggest the solution.

public MyAbstractClass(List<? extends Animal> animalList) {
        this.myAnimalList = animalList; <==== problem you cannot assign List<? extends Animal> to List<Animal> .. Subtyping is not allowed in generic class.
    }

:

public MyAbstractClass(List<? extends Animal> animalList) {

   myAnimalList= new ArrayList<Animal>();   

   for(Animal c: animalList){
        this.myAnimalList.add(c);
   }
}
-1

Source: https://habr.com/ru/post/1568842/


All Articles