4 ms·
I didn't expect this: "This is a key rule: function return values can changed to subtypes, moving down the hierarchy, whereas function parameters can be change
by foolfoolz 11y ago
I didn't expect this:
"This is a key rule: function return values can changed to subtypes, moving down the hierarchy, whereas function parameters can be changed to supertypes, moving up the hierarchy."
The part allowing a super type in an overridden methods parameters stood out. I tried this out in scala and it did not compile. Intuitively it doesn't make sense to me to allow wider types.
- deleted 11y ago[deleted]
- mbrameld 11y agoI guess it depends on whether the methods are virtual or not? If they're virtual it makes sense that you couldn't override with a wider parameter type, but if they're not it makes sense that you could.
- Moto7451 11y agoIf 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.
- foolfoolz 11y agoI 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.