Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

If you think about it it's intuitive. Take these type chains:

Thing -> Animal -> Dog Thing -> Animal -> Cat Thing -> Instrument -> Tuba

Lets say Thing has the following properties: - IsVisible - Mass - CanMove

Lets say Tube has the following properties: - PlayNote

And lets say that Cat has: - Meow

Lets take the following contrived example for overriding:

  Class Debugger {
   void debug(Cat cat); 
  }

  Class ThingDebugger : Debugger {
   void debug(Thing thing);
  }
Going "wider" to Thing works because Cats, Dogs, and Tuba all have the properties that a Thing has, because they are instances of Thing. Going "narrower" works for the same reason:

  Class Wrangler {
   Animal wrangle(); 
  }

  Class DogWrangler : Wrangler {
   Dog wrangle();
  }
A Dog can do anything an Animal can do because it is an Animal.

The type system is doing its best to save you from the following:

  Class Janky {
    void ThisIsOK();
    Animal PrepareForCrash();
  }

  Class AlsoJanky : Janky {
    void ThisIsOK();
    Instrument PrepareForCrash();
  }

  Class StillJanky : Janky {
    void ThisIsOK();
    Thing PrepareForCrash();
  }
In this case any mixing of PrepareForCrash will leave you with returned types that don't completely share an interface. If the compiler let you do that, you'd probably do this at some point start mixing the subtypes of Janky and calls to PrepareForCrash would return Tubas when you expect Cats and then all hell would break loose. Anyone who's used scripting languages should be familiar with something like this happening at one point or another.


I still don't get ThingDebugger.debug()

first you can't call super() in that method without a downcast. how does that count as overriding the method?

it's a big problem if you have another subclass of Debugger that does not change the parameter type. you now have 2 subclassed of Debugger, one has a method debug(cat: Cat). the other has a method debug(cat: Thing). that accepts cats, dogs, and tubas. these subtypes of Debugger are not safely interchangeable.

this does not compile in scala, I'm surprised swift would allow it.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: