I have 2 classes A and B, both of which have properties X and Y; but class B also has another property, Z. Classes A and B are completely unrelated to one another, they just share properties X and Y.
Inheritance
class A
{
public int X;
public int Y;
}
class B : A
{
public int Z;
}
Class B does not have a "is-a" relationship to class A, so it breaks inheritance principals is OOP.
Composition
class A
{
public int X;
public int Y;
}
class B
{
public A ObjA;
public int Z;
}
Class B does not have a "has-a" relationship to class A so it breaks composition principals is OOP.
Without duplicate code, should I use inheritance or composition (even though they brake the principles of OOP) or is there another design pattern? I personally think that using inheritance is going to be the lesser of the evils because of readability.
Since Class B does not have a "has-a" relationship to class A ..
so "Composition" should not be used.
You can use OOP Inheritance way as you designed. It does not break OOP principles as you said. Class A & B are not 100% unrelated. They have common properties so OOP Inheritance way is acceptable.
Remember that OOP does not require inheritance of Method members.
BUT for your case.You should duplicate Properties declaration so changes of a class does not affect the other.
class A
{
public int X;
public int Y;
}
class B
{
public int X;
public int Y;
public int Z;
}
Its hard to say with everything being so abstract an ill-defined, but generally, you should use inheritance when it makes sense, and not when it doesn't, and composition when it makes sense and not when it doesn't.
If A and B truly have no relationship, then it probably makes more sense to structure things differently, with the stuff you want common in its own class that is used or inherited by A and B:
class hasXY {
int X;
int Y;
}
class A : hasXY { }
class B : hasXY { int Z }
or
class A {
hasXY XY;
}
class B {
hasXY XY;
int Z;
}
Of course, this introduces extra overhead in some languages (depending on their implementation details)
It all depends on what you mean by "they just share properties X and Y".
Both properties are public, so they contribute to the behaviour of the class. Therefore, if the properties are really the same (have the same semantics), I would not say that the classes are unrelated. They share some behaviour, so it makes sense to use inheritance or better composition, which in most cases should be prefered.
But as you assume that Aand B are unrelated, it is more likely that the properties are just unrelated variables of the same type to which you have assigned the same names. Therefore, just rename the properties in one of the classes and it will be clear that both the properties and the classes are unrelated.
Related
I have an interface and two data sources that populate concrete instances of objects that implement the interface. The interface exposes methods that only one of the two instances can satisfy in a meaningful way.
public interface IFoo {
public int getValueA();
public int getValueB();
}
public FooFromFile implements IFoo {
int a;
int b;
...
public int getValueA() {
return a;
}
public int getValueB() {
return b;
}
}
public FooFromNetwork implements IFoo {
int a;
...
public int getValueA() {
return a;
}
public int getValueB() {
return 0; // return 0 because FooFromNetwork never gets value b.
}
}
Every code base I've worked on has code like this and I find it usually stems from a desire to apply 'is-a' relationships where something else may be more appropriate. I have some time to refactor the code base on which I am currently working. What would be some good modeling solutions for situations like this? The actual code is much more complicated than this but solving the toy issue here, with a robust pattern that scales, would go a long way.
The problem described here "is a" (pun intended) violation of the Liskov Substitution Principle. There are many solutions to LSP violations, but nothing is one-size-fits-all. For example, depending on context you may choose to favor composition over inheritance or apply interface segregation.
From what I understand, does it mean. making methods to build up different components of a program. e.g. if i was to make a program that adds and subtracts numbers then I would have something like;
public void addnum(int addnum){
addnum= addnum+1;
system.out.println(addnum);
}
public void subtractnum int subtractnum){
subtractnum = subtractnum-1;
system.out.println(addnum);
}
public static void main(String args[]){
int num = 21;
addnum(num);
subtractnum(num);
}
Am I correct, or does it mean something else?
In the Java and .NET frameworks, among others, having a class X inherit from Y has two benefits:
Instances of class X encapsulate the values of all of Y's fields, and can use any of Y's protected members on themselves as if those members belonged to X; additionally, the definition of class X may use Y's static members as though they were its own.
Variables of type Y may hold references to instances of type X.
Allowing a class object to regard as its own the contents of multiple other classes makes it impossible to have upcasts and downcasts preserve identity; since identity-preserving upcasts and downcasts are useful, Java and .NET allow each class to regard members of only one parent as its own (members of the parent's parent are also members of the parent, and get incorporated as such). The limitation of incorporating members from only one parent class is generally not overly restrictive.
On the other hand, if each type could only be stored in references of its own type or its ancestors' types, that would be restrictive. To allow for the possibility that it may be helpful to store references to an object in multiple independent types, Java and .NET both make it possible to define interface types. A reference to an object which implements an interface may be stored in a variable of that interface type (achieving the second benefit of inheritance) but unlike class inheritance which is restricted to a single parent, interface implementation is relatively unrestricted. A class may implement an arbitrary number of independent interfaces, and references to such a class may be stored in variables of any of those interfaces' types.
In short, interfaces provide the most important benefit of inheritance (reference substitutability), but give up some features in exchange for giving up a significant restriction (the inability to inherit from multiple classes).
You´re confusing different methods with different parameter types.
Maybe this example will help:
public interface GeometricalObject {
double getArea();
double getPerimeter();
}
...
public class Circle implements GeometricalObject {
public double r;
public double getArea() {
return 3.14 * r * r;
}
public double getPerimeter()
{
return 3.14 * 2 * r;
}
}
...
public class Square implements GeometricalObject {
public double s;
public double getArea() {
return s * s;
}
public double getPerimeter()
{
return 4 * s;
}
}
...
public void printGeomObject(GeometricalObject g) {
System.out.println("Area is " + g.getArea());
System.out.println("Perimeter is " + g.getPerimeter());
}
Interface provides us the way of multilevel inheritance.
Interface can be extended to any class
Common properties of any class can be define in interface and can be inherited to many classes.
I'm trying to find a good example for the use of multiple inheritance what cannot be done with normal interfaces.
I think it's pretty hard to find such an example which cannot be modeled in another way.
Edit: I mean, can someone name me a good real-world example of when you NEED to use multiple inheritance to implement this example as clean as possible. And it should not make use of multiple interfaces, just the way you can inherit multiple classes in C++.
The following is a classic:
class Animal {
public:
virtual void eat();
};
class Mammal : public Animal {
public:
virtual void breathe();
};
class WingedAnimal : public Animal {
public:
virtual void flap();
};
// A bat is a winged mammal
class Bat : public Mammal, public WingedAnimal {
};
Source: wiki.
One example where multiple class inheritance makes sense is the Observer pattern. This pattern describes two actors, the observer and the observable, and the former wants to be notified when the latter changes its object state.
A simplified version for notifying clients can look like this in C#:
public abstract class Observable
{
private readonly List<IObserver> _observers = new List<IObserver>();
// Objects that want to be notified when something changes in
// the observable can call this method
public void Subscribe(IObserver observer)
{
_observers.Add(observer);
}
// Subclasses can call this method when something changes
// to notify all observers
protected void Notify()
{
foreach (var observer in _observers)
observer.Notify();
}
}
This basically is the core logic you need to notify all the registered observers. You could make any class observable by deriving from this class, but as C# does only support single class inheritance, you are limited to not derive from another class. Something like this wouldn't work:
public class ImportantBaseClass { /* Members */ }
public class MyObservableSubclass : ImportantBaseClass, Observable { /* Members */ }
In these cases you often have to replicate the code that makes subclasses observable in all of them, basically violating the Don't Repeat Yourself and the Single Point of Truth principles (if you did MVVM in C#, think about it: how often did you implement the INotifyPropertyChanged interface?). A solution with multiple class inheritance would be much cleaner in my opinion. In C++, the above example would compile just fine.
Uncle Bob wrote an interesting article about this, that is where I got the example from. But this problem often applies to all interfaces that are *able (e.g. comparable, equatable, enumerable, etc.): a multiple class inheritance version is often cleaner in these cases, as stated by Bertrand Meyer in his book "Object-Oriented Software Construction".
I hear (and read on this site) a lot about "favour composition over inheritance".
But what is Compositon? I understand inheritance from the point of Person : Mammal : Animal, but I can't really see the definition of Compostion anywhere.. Can somebody fill me in?
Composition refers to combining simple types to make more complex ones. In your example, composition could be:
Animal:
Skin animalSkin
Organs animalOrgans
Mammal::Animal:
Hair/fur mammalFur
warm-blooded-based_cirulation_system heartAndStuff
Person::Mammal:
string firstName
string lastName
If you wanted to go totally composition (and get rid of all inheritance) it would look like this:
Animal:
Skin animalSkin
Organs animalOrgans
Mammal:
private Animal _animalRef
Hair/fur mammalFur
warm-blooded-based_cirulation_system heartAndStuff
Person:
private Mammal _mammalRef
string firstName
string lastName
The advantage to this approach is that the types Mammal and Person do not have to conform to the interface of their previous parent. This could be a good thing because sometimes a change to the superclass can have serious effects on the subclasses.
They still can have access to the properties and behaviours of these classes through their private instances of these classes, and if they want to expose these former-superclass behaviours, they can simply wrap them in a public method.
I found a good link with good examples here: http://www.artima.com/designtechniques/compoinh.html
Composition is simply the parts that make up the whole. A car has wheels, an engine, and seats. Inheritance is a "is a " relationship. Composition is a "has a" relationship.
There are three ways to give behavior to a class. You can write that behavior into the class; you can inherit from a class that has the desired behavior; or you can incorporate a class with the desired behavior into your class as a field, or member variable. The last two represent forms of code reuse, and the final one - composition - is generally preferred. It doesn't actually give your class the desired behavior - you still need to call the method on the field - but it puts fewer constraints on your class design and results in easier to test and easier to debug code. Inheritance has its place, but composition should be preferred.
class Engine
{
}
class Automobile
{
}
class Car extends Automobile // car "is a" automobile //inheritance here
{
Engine engine; // car "has a" engine //composition here
}
Composition - Functionality of an object is made up of an aggregate of different classes. In practice, this means holding a pointer to another class to which work is deferred.
Inheritance - Functionality of an object is made up of it's own functionality plus functionality from its parent classes.
As to why composition is preferred over inheritance, take a look at the Circle-ellipse problem.
An example of Composition is where you have an instance of a class within another class, instead of inheriting from it
This page has a good article explaining why people say "favour composition over inheritance" with some examples of why.
composition
simply mean using instance variables that are references to other objects.
For an illustration of how inheritance compares to composition in the code reuse department, consider this very simple example:
1- Code via inheritance
class Fruit {
// Return int number of pieces of peel that
// resulted from the peeling activity.
public int peel() {
System.out.println("Peeling is appealing.");
return 1;
}
}
class Apple extends Fruit {
}
class Example1 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel();
}
}
When you run the Example1 application, it will print out "Peeling is appealing.", because Apple inherits (reuses) Fruit's implementation of peel(). If at some point in the future, however, you wish to change the return value of peel() to type Peel, you will break the code for Example1. Your change to Fruit breaks Example1's code even though Example1 uses Apple directly and never explicitly mentions Fruit.
for more info ref
Here's what that would look like:
class Peel {
private int peelCount;
public Peel(int peelCount) {
this.peelCount = peelCount;
}
public int getPeelCount() {
return peelCount;
}
//...
}
class Fruit {
// Return a Peel object that
// results from the peeling activity.
public Peel peel() {
System.out.println("Peeling is appealing.");
return new Peel(1);
}
}
// Apple still compiles and works fine
class Apple extends Fruit {
}
// This old implementation of Example1
// is broken and won't compile.
class Example1 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel();
}
}
2- Code via composition
Composition provides an alternative way for Apple to reuse Fruit's implementation of peel(). Instead of extending Fruit, Apple can hold a reference to a Fruit instance and define its own peel() method that simply invokes peel() on the Fruit. Here's the code:
class Fruit {
// Return int number of pieces of peel that
// resulted from the peeling activity.
public int peel() {
System.out.println("Peeling is appealing.");
return 1;
}
}
class Apple {
private Fruit fruit = new Fruit();
public int peel() {
return fruit.peel();
}
}
class Example2 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel();
}
}
for more information ref
I'm reading some books about Design Patterns and while some describe the relation between the abstraction and the implementation as a composition, some describe it as an aggregation. Now I wonder: is this dependant on the implementation? On the language? Or context?
The terms "composition" and "aggregation" mean more or less the same thing and may be used interchangeably. Aggregation may be used more frequently when describing container classes such as lists, dynamic arrays, maps, and queues where the elements are all of the same type; however, both terms may be found to describe classes defined in terms of other classes, regardless of whether those types are homogenous (all of the same type) or heterogenous (objects of different types).
To make this clearer:
class Car {
// ...
private:
Engine engine;
Hood hood;
};
// The car is *composed* of an engine and a hood. Hence, composition. You are
// also bringing together (i.e. *aggregating*) an engine and hood into a car.
The relationship between abstraction and implementation typically implies inheritance, rather than composition/aggregation; typically the abstraction is an interface or virtual base class, and the implementation is a fully concrete class that implements the given interface. But, to make things confusing, composition/aggregation can be a part of the interface (because, for example, you may need to set/get the objects that are used as building blocks), and they are also an approach to implementation (because you might use delegation to provide the definition for methods in your implementation).
To make this clearer:
interface Car {
public Engine getEngine();
public Hood getHood();
public void drive();
}
// In the above, the fact that a car has these building blocks
// is a part of its interface (the abstraction).
class HondaCivic2010 implements Car {
public void drive(){ getEngine().drive(); }
// ...
}
// In the above, composition/delegation is an implementation
// strategy for providing the drive functionality.
Since you have tagged your question "bridge", I should point out that the definition of the bridge pattern is a pattern where you use composition rather than inheritance to allow for variation at multiple different levels. An example that I learned at college... using inheritance you might have something like:
class GoodCharacter;
class BadCharacter;
class Mage;
class Rogue;
class GoodMage : public GoodCharacter, Mage;
class BadMage : public BadCharacter, Mage;
class GoodRogue : public GoodCharacter, Rogue;
class BadRogue : public BadCharacter, Rogue;
As you can see, this kind of thing goes pretty crazy, and you get a ridiculous number of classes. The same thing, with the bridge pattern, would look like:
class Personality;
class GoodPersonality : public Personality;
class BadPersonality : public Personality;
class CharacterClass;
class Mage : public CharacterClass;
class Rogue : public CharacterClass;
class Character {
public:
// ...
private:
CharacterClass character_class;
Personality personality;
};
// A character has both a character class and a personality.
// This is a perfect example of the bridge pattern, and we've
// reduced MxN classes into a mere M+N classes, and we've
// arguably made the system even more flexible than before.
the bridge pattern must use delegation (aggregation/composition and not inheritance). from the gang-of-four book:
Use the Bridge pattern when
* you want to avoid a permanent binding between an abstraction and its implementation. This might be the case, for example, when the implementation must be selected or switched at run-time.
* both the abstractions and their implementations should be extensible by subclassing. In this case, the Bridge pattern lets you combine the different abstractions and implementations and extend them independently.
* changes in the implementation of an abstraction should have no impact on clients; that is, their code should not have to be recompiled.
* (C++) you want to hide the implementation of an abstraction completely from clients. In C++ the representation of a class is visible in the class interface.
* you have a proliferation of classes as shown earlier in the first Motivation diagram. Such a class hierarchy indicates the need for splitting an object into two parts. Rumbaugh uses the term "nested generalizations" [RBP+91] to refer to such class hierarchies.
* you want to share an implementation among multiple objects (perhaps using reference counting), and this fact should be hidden from the client. A simple example is Coplien's String class [Cop92], in which multiple objects can share the same string representation (StringRep).
Standard UML of Bridge pattern clears out all air around the confusion. Below is an explanation with a brief example to clear the air around this.
Apologies for this lengthy code, best way is to copy this code to Visual Studio to easily understand it.
Read through the explanation written at the end of code
interface ISpeak
{
void Speak();
}
class DogSpeak : ISpeak
{
public void Speak()
{
Console.WriteLine("Dog Barks");
}
}
class CatSpeak : ISpeak
{
public void Speak()
{
Console.WriteLine("Cat Meows");
}
}
abstract class AnimalBridge
{
protected ISpeak Speech;
protected AnimalBridge(ISpeak speech)
{
this.Speech = speech;
}
public abstract void Speak();
}
class Dog : AnimalBridge
{
public Dog(ISpeak dogSpeak)
: base(dogSpeak)
{
}
public override void Speak()
{
Speech.Speak();
}
}
class Cat : AnimalBridge
{
public Cat(ISpeak catSpeak)
: base(catSpeak)
{
}
public override void Speak()
{
Speech.Speak();
}
}
-- ISpeak is the abstraction that bot Dog and Cat has to implement
-- Decoupled Dog and Cat classes by introducing a bridge "Animal" that is composed of ISpeak
-- Dog and Cat classes extend Animal class and thus are decoupled from ISpeak.
Hope this clarifies