3 ms·
class Penguin : Bird{ override void Fly(){ throw new InvalidOperationException("can't fly"); } }
by deviltreh 13y ago
class Penguin : Bird{
override void Fly(){
throw new InvalidOperationException("can't fly");
}
}
- setrofim_ 13y agoBut 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 http://en.wikipedia.org/wiki/Liskov_substitution_principle [edit: grammar]
- nslamberth 13y agoNit 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.
- setrofim_ 13y agoWell, 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).
- deleted 13y ago[deleted]
- enterx 13y agoThrow that InvalidOperationException again and I'll make your life exceptional once more. extremely. XD