0

In:

// services
public interface Mother { public Collection<? extends Father> getMamaStuff() {}} 
public interface Daughter extends Mother {}

// data
public interface Father { public String getPapaStuff() }
public interface Son extends Father { public String playLoudMusic() }

why is this not allowed:

public class Clazz {

    Clazz(Daughter daughter) {//boilerplate}

    public Collection<Son> idk = doughter.getMamaStuff();
}
  1. Is it because there is no way to know which implementation of Father will Clazz get?
  2. What is the good way to work around this?
  3. Is instanceof good practice in this case?

It seems to me there is no way around type checking.

  • 1
    there is no such thing as 'doughter', sho how do you expect that to work? Mother contains a collection of Fathers who are called 'mamaStuff'? Daughter extends Mother???? You seem to have quite an odd view of the world. The reason it doesn't work, is because it is being called before you set the value of daughter in your constructor. – Stultuske May 08 '20 at 05:42
  • *FYI:* How do you know if `Daughter` should extend `Mother` and not the other way around? – akuzminykh May 08 '20 at 05:43
  • After fixing the spelling mistakes, my IDE, which is Eclipse, shows the following compile error: `Type mismatch: cannot convert from Collection to Collection` Do you get the same? – Abra May 08 '20 at 05:50
  • Yeah somebody will pass something in the Class which is an actual implementation of some of these interfaces. I konw that the inheritance chain is correct as this is the situation Im in, im extending framework functionality also, to address some of the constructor complaint, it doesn't matter which way Clazz is instantiated as that doesn't affect the problem at hand. – poppycockears May 08 '20 at 05:51
  • Does this answer your question? [Difference between super T> and extends T> in Java](https://stackoverflow.com/questions/4343202/difference-between-super-t-and-extends-t-in-java) – Abra May 08 '20 at 06:01

2 Answers2

1

after fixing your broken supplied code.

All the compiler knows is that what we are getting from the mother is that it is something that extends father. It's doesn't know it is a son specifically.

The compiler vill not cast for ju.

So what we can have in the collection is something that extends father

// services
public interface Mother { public Collection<? extends Father> getMamaStuff(); {}}
public interface Daughter extends Mother {}

// data
public interface Father { public String getPapaStuff(); }
public interface Son extends Father { public String playLoudMusic(); }

public class Clazz {

    Clazz(Daughter daughter) {//boilerplate}

        Collection<? extends Father> idk = daughter.getMamaStuff();
    }
}
Toerktumlare
  • 12,548
  • 3
  • 35
  • 54
  • hmmm, interesting solution, i like it, but now I can't use son specific stuff. Any ideas on that? – poppycockears May 08 '20 at 05:59
  • 1
    if you want to use `son` specific things you need to cast it, that why if you look into say the `List` implementation, everything inherits from `Collection>` everything inherits a behaviour, they don't extend a behaviour. – Toerktumlare May 08 '20 at 06:00
  • OK, so in other words, there is no way around instanceof? – poppycockears May 08 '20 at 06:01
  • 1
    in this case i don't think so. But im no pro at generics, it all depends on what your goal is. One thing to know is that the compiler will not check "oh so this extends this, or this extends that" – Toerktumlare May 08 '20 at 06:03
1

The reason it's not allowed:

interface Feline { }
interface Kitten extends Feline {}
interface Tiger extends Feline {}

...

Cage<? extends Feline> makeCage();

// at this point, it's actually really important that 
// the right kind of cage was created...
makeCage().put(new Tiger());

Parameterizing Mother may work in your situation:

public interface Mother<T extends Father> { 
  public Collection<T> getMamaStuff(); {}
}
iluxa
  • 6,941
  • 18
  • 36
  • tnx! I cant touch mother it's framework stuff. Can you please explain a bit more how Parameterizing fixes this? I'm not sure I get it – poppycockears May 08 '20 at 06:13
  • If Mother is parameterized (like I'm showing in the example), it can accept a type of Father class to use, then getMamaStuff() will return a collection of the right type. But if it comes from the framework, can't be helped – iluxa May 08 '20 at 21:25