191

Basically we want things to behave sensibly. Consider the following problem: I am given a group of rectangles and I want to increase their area by 10%. So what I do is I set the length of the rectangle to 1.1 times what it was before. public void IncreaseRectangleSizeByTenPercent(IEnumerable<Rectangle> rectangles) { foreach(var rectangle in ...


127

A common misunderstanding with the DRY principle is that it is somehow related to not repeating lines of code. The DRY principle is "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system". It's about knowledge, not code. LoginPage knows about how to draw the page for logging in. If EditInfoPage knew how to ...


127

I wouldn't use any form of inheritance for World and Country. The World is not a Country, and a Country is not the World. Instead, the World is a "bag" which contains many Countries. By "bag" I mean some kind of container class of your choosing (linked list, set, dictionary/map, or whatever). Pick whichever container type allows you to most efficiently ...


121

Gosh, there are some weird misconceptions on what OCP and LSP and some are due to mismatch of some terminologies and confusing examples. Both principles are only the "same thing" if you implement them the same way. Patterns usually follow the principles in one way or another with few exceptions. The differences will be explained further down but first let ...


90

I know that this is meant to be a fairly contrived example to demonstrate the idea at play. But I would say that as a rule of thumb, you want to exhaust every possible option before relying on Subtype polymorphism. Using composition is a better solution here just based on the domain. Marriage does not define a "type" of person any more than race, wealth, ...


82

From my perspective: your design is wrong. Translated to natural language, you are saying the following: Given we have animals, there are cats and fish. animals have properties, which are common to cats and fish. But that's not enough: there are some properties, which differentiate cat from fish, therefore you need to subclass. Now you have the problem, ...


78

UPDATE: I've revised this answer. A number of good points were raised in the comments that deserved calling out. If my class implements an interface then can I say that I'm following inheritance? It is not entirely clear what you mean by "following inheritance". Let's ask a slightly different question? What is inheritance? When members of one type X ...


77

There is no need to have specific subclasses for every person. You're right, those should be instances instead. Goal of subclasses: to extend parent classes Subclasses are used to extend the functionality provided by the parent class. For example, you may have: A parent class Battery which can Power() something and can have a Voltage property, And a ...


73

In many cases, people use inheritance to provide a trait to a class. For example think of a Pegasus. With multiple inheritance you might be tempted to say the Pegasus extends Horse and Bird because you've classified the Bird as an animal with wings. However, Birds have other traits that Pegasi don't. For example, birds lay eggs, Pegasi have live birth. If ...


72

The simplest answer is that if you put everything into one class, you have to worry about everything at once when you're writing new code. This may work for small projects, but for huge applications (we're talking hundreds of thousands of lines), this quickly becomes next to impossible. To solve this issue, you break up pieces of functionality into their ...


69

It depends on the context, but I would argue you should declare the most abstract type possible. That way your code will be as general as possible and not depend on irrelevant details. An example would be having a LinkedList and ArrayList which both descend from List. If the code would work equally well with any kind of list then there is no reason to ...


65

This is something that I use to prevent polymorphism from being used. Say you have 15 different classes that have NamedEntity as a base class somewhere in their inheritance chain and you are writing a new method that is only applicable to OrderDateInfo. You "could" just write the signature as void MyMethodThatShouldOnlyTakeOrderDateInfos(NamedEntity ...


63

A commitment is something that reduces your future options. Publishing a method implies that users will call it, therefore you can't remove this method without breaking compatibility. If you'd kept it private, they couldn't (directly) call it, and you could some day refactor it away without problems. Therefore, publishing a method is a stronger commitment ...


61

Is there something that I am not seeing here? Allowing multiple inheritence makes the rules about function overloads and virtual dispatch decidedly more tricky, as well as the language implementation around object layouts. These impact language designers/implementors quite a bit, and raise the already high bar to get a language done, stable and adopted. ...


58

The general rule reads "Prefer delegation over inheritance", not "avoid all inheritance". If the objects have a logical relationship and a B can be used wherever an A is expected, it is good practice to use inheritance. However, if the objects just happen to have fields with the same name, and have no domain relationship, do not use inheritance. Quite ...


54

If all you want to do is create class X with certain arguments, subclassing is an odd way of expressing that intent, because you aren't using any of the features that classes and inheritance give you. It's not really an anti-pattern, it's just strange and a bit pointless (unless you have some other reasons for it). A more natural way of expressing this ...


50

It's completely terrible in every possible way. At most, use a factory function to produce JButtons. You should only inherit from them if you have some serious extension needs.


46

Er wait you're concerned that repeating public LoginPage loginPage; in two places violates DRY? By that logic int x; can now only ever exist in one object in the entire code base. Bleh. DRY is a good thing to keep in mind but come on. Besides ... extends LoginPage is getting duplicated in your alternative so even being anal about DRY wont make sense ...


43

There can't be any proper inheritance of constructors in C++, because the constructor of a derived class needs to perform additional actions that a base-class constructor does not have to do and does not know about. These additional actions are the initialisation of the data members of the derived class (and in a typical implementation, also setting the ...


36

You ask why, as if the whether is decided. Lets consider your supposition: Why is inheritance generally viewed as a bad thing by OOP proponents I disagree with the premise of the question. Inheritance isn't generally viewed as bad, it is viewed as misused and overused. GoF Design Patterns says no such thing about it being bad. Let's see what GoF ...


35

In principle there's no difference between inheriting from generic types and inheriting from anything else. However, why on earth would you derive from any class and not add anything further?


35

You want to avoid base classes knowing about derived classes. It introduces tight coupling and is a maintenance headache because you have to remember to add to the list every time you create a new derived class. It will also prevent you from being able to put the Notification class into a reusable package/assembly if you wanted to use this class in ...


34

It all depends upon the exact problem you're trying to solve. Consider a concrete example: your abstract base class is Vehicle and you currently have the concrete implementations Bicycle and Car. You're considering moving numberOfWheels from Bicycle and Car to vehicle. Should you do this? No! Because not all vehicles have wheels. You can already tell that ...


32

There are a number of problems with multiple inheritance when it is used with full fledged classes, but they all revolve around ambiguity. The ambiguity shows up in a few different ways: If you have two base classes with the same field x, and the derived type asks for x, what does it get? If the two x variables have incongruent types, you could infer it. ...


31

Assume your baseclass works with a member int. Now your subtype requires that int to be positive. This is strengthened pre-conditions, and now any code that worked perfectly fine before with negative ints is broken. Likewise, assume the same scenario, but the base class used to guarantee that the member would be positive after being called. Then the subtype ...


31

This seems to be too big a difference to just boil down to style. What is the reasoning behind this? My understanding is that it largely is simply a stylistic decision. Well, perhaps not style, but the idioms of the language/environment. Java standard library developers followed one set of design guidelines and the .NET developers another (though they had ...


31

The seminal paper on mixins is Gilad Bracha's PhD thesis The Programming Language Jigsaw: Mixins, Modularity and Multiple Inheritance. It has answers to all of your questions, like Why not make a language with mixin-only inheritance? Jigsaw is such a language, as is Newspeak, Bracha's current language However, to me it looks like traditional inheritance ...


31

That all seems like a fine description of what type systems provide. And your implementation sounds like a reasonable enough one for what it's doing. For some languages, you won't need the runtime information since your language doesn't do runtime dispatch (or you do single dispatch via vtables or another mechanism, so don't need the type information). For ...


30

The only reason why it is disallowed is because it makes it easy for people to shoot themselves in the foot. What usually follows in this sort of a discussion is arguments as to whether the flexibility of having the tools is more important than the safety of not shooting off your foot. There is no decidedly correct answer to that argument, because like most ...


30

If all your objects are immutable, there is no problem. Every Square is also a Rectangle. All the properties of a Rectangle are also properties of a Square. The problem begins when you add the ability to modify the objects. Or really - when you start passing arguments to the object, not just reading property getters. There are modifications that you can do ...


Only top voted, non community-wiki answers of a minimum length are eligible