1

I'd like to implement the following classes with the following hierarchy:

public class DwellingPropertySetter
    extends AbstractPropertySetter<Dwelling>

public class HousePropertySetter
    extends DwellingPropertySetter<House>

public class SkyscrapperPropertySetter
    extends HousePropertySetter<Skyscrapper>

Unfortunately this code won't compile. A way to do it would be this:

public class DwellingPropertySetter<T extends Dwelling>
    extends AbstractPropertySetter<T>

public class HousePropertySetter<T extends House>
    extends DwellingPropertySetter<T>

public class SkyscrapperPropertySetter<T extends Skyscrapper>
    extends HousePropertySetter<T>

But for me those extends keywords are unnecessary. Whenever I want to use a SkyscrapperPropertySetter I'd have to specify a type parameter. This is useless and would then look like SkyscrapperPropertySetter<Skyscraper>.

Do you know a way out for me? The only other way I know to realise my first hierarchy would be using interfaces and delegate methods.

  • 1
    Why do you want to use generics (like in your second example) when your first example seems to do what you need? – assylias May 11 '12 at 12:03
  • Because my first example won't compile. :-) –  May 11 '12 at 12:04
  • @NewTalk, here's a potentially stupid question: Why doesn't it compile? – aioobe May 11 '12 at 12:07
  • @aioobe Because of _The type DwellingPropertySetter is not generic; it cannot be parameterized with arguments _ –  May 11 '12 at 12:08

2 Answers2

2

I think you have correctly recognized it is pointless to have something like ChickenArrayList<Chicken>, so you can either create something like

class ChickenArrayList extends ArrayList<Chicken>

OR, if you want to reuse some functionality in ChickenArrayList, you may have to make it abstract (and generic) and put another concrete, non-generic class on top of it:

class AbsChickenArrayList<T extends Chicken> extends ArrayList<T>
// and
class ChickenArrayList extends AbsChickenArrayList<Chicken>
class HenArrayList extends AbsChickenArrayList<Hen>

I know this is quite verbose, but this is the best you can do with this ~18 year old language.

billc.cn
  • 7,187
  • 3
  • 39
  • 79
1

I think you can achieve what is reasonable. If you have

public class DwellingPropertySetter
extends AbstractPropertySetter<Dwelling>

That means you have already made DwellingPropertySetter non-generic, all the method signatures will use Dwelling. If you say

public class DwellingPropertySetter<T extends Dwelling>
extends AbstractPropertySetter<T>

that means there can be various DwellingPropertySetters -- and you really would like to have different ones, so I think this is what you really want to keep. Or is it your complaint that you want both a DwellingPropertySetter with no args, where Dwelling is assumed, AND a subclass extending DwellingPropertySetter<T> with a different T? That cannot be had with Java Generics.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • Yes. I want to have a `DwellingPropertySetter` with no arguments and and a subclass extending `DwellingPropertySetter` with a different `T`. Why isn't that technically possible? :-( –  May 11 '12 at 12:11
  • In Java Generics, but also in every other implementation of the same concept in other languages, a type either does or doesn't take type parameters. I've never seen a case where a type param would be optional with a default value. EDIT I googled a bit, C++ actually [does support](http://stackoverflow.com/questions/707780/is-there-a-reasonable-approach-to-default-type-parameters-in-c-sharp-generics) such a feature. – Marko Topolnik May 11 '12 at 12:13
  • @NewTalk Nothing prevents you from writing `SkyscrapperPropertySetter sps = new SkyscrapperPropertySetter()` without the generics. – assylias May 11 '12 at 12:16
  • 2
    @assylias Only if he disables compiler warnings, otherwise the screen is going to crawl with yellow squiggles :) – Marko Topolnik May 11 '12 at 12:19