Hacker News new | past | comments | ask | show | jobs | submit login

class Penguin : Bird{ override void Fly(){ throw new InvalidOperationException("can't fly"); } }



But now you can't assume that Birds can Fly. You have to catch InvalidOperationException on every invocation. And what's special about Fly? What above other Bird methods, surely the same can be done to all of them? Now you can't assume anything about a Bird. So what good is the Bird abstraction then, if you can't make any assumptions about it?

This is breaking the Liskov Substitution Principle[1]. By saying that Penguin is a subclass of Bird, you're implying that I should be able to stick a Penguin into any code that expects a Bird, that code will just work, without it having to care about the particularity of that Bird actually being a Penguin.

[1] http://en.wikipedia.org/wiki/Liskov_substitution_principle

[edit: grammar]


Nit picking here, but birds as a biological class are defined as having wings as opposed to being able to fly. So the bird abstraction allows you to assume a bird has wings, and if it has wings it is likely able to fly (but not guaranteed).

Overall agreed, though. This ties into timr's point that if there are errors in your classifications, then your class hierarchy is incorrect.


Well, yes, indeed. It depends on the purpose of the abstraction. It may well be that Fly() should not be a method of Bird (maybe we need a FlyingBird subclass, or, even better, a Flying mix-in). My objection was to the "solution" of throwing InvalidOperation, not in support of the assumption that birds can necessarily fly (note the capitalization in may initial remark).


Throw that InvalidOperationException again and I'll make your life exceptional once more. extremely. XD




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

Search: