How to distinguish between design patterns and standard polymorphism - java

For example I have one interface and a bunch of classes as follows
public interface Drawable{
void draw(); // draws something on screen for example.
}
abstract class Shape implements Drawable {...}
class Circle extends Shape{...} // assume that draw() is implemented in both classes.
class Square extends Shape{...} // ...
Now if I have a main class and perform the following:
class Main{
Shape s1 = new Circle();
s1.draw(); // assume that this will draw a circle.
s1 = new Square();
s1.draw(); //assume that this will draw a square.
}
I'm I using a design pattern here? or is this just standard polymorphism? If this is a design pattern then what is it called?

In my opinion, a design pattern is a tried-and-tested manner of writing code to solve a problem. The way in which you employ a given design pattern could significantly differ depending on the programming language you use.
Design patterns are rarely supported at the language level (although newer languages like Groovy do implement particular design patterns at the language-level; for example, the "Method Object" pattern is provided in Groovy using a language level feature called "Closures").
The code you've given is an example of Polymorphism, which is one of the fundamental concepts of OOP. Polymorphism is, however, one of the foundations for implementing many design patterns.
Polymorphism is supported at the language-level; it is not something that you can code into your program.

There was a Java book written in 1998, still available at Amazon which in Chapter 4, called out "Inteface", "Abstract Superclass" and other things as "Fundamental Design Patterns."
This claim was somewhat controversial, as many people would say these are just basic mechanisms rather than "design patterns."
Short answer is: people will give you both answers, though in my experience, most people would say no.

Related

Visitor vs Composition

As I see it visitor design pattern is very similar to the way composition work.
In composition I would hold an interface member in the class and pass a concrete implementation of the interface in the constructor, and then either delegate a method to it or use it inside the class.
In visitor design pattern I also have a concrete implementation of the interface, and I send it to the visit method which then delegates the visit method to it.
To show this similarity in code, a visitor would be:
VisitorInterface v = new ConcreteVisitor();
MyClass c = new MyClass();
c.visit(v);
VisitorInterface dv = new DifferentVisitor();
c.visit(dv);
And composition would be:
SomeInterface i = new ConcreteImplementation();
MyClass c = new MyClass(i);
c.visit(); // called visit just to show the symmetry to visitor pattern
SomeInterface di = new DifferentImplementation();
c.changeReference(di);
c.visit();
I would like to hear your thoughts as to in which cases you would prefer one over the other and why
Composition is the means of expressing a has-a relationship between objects, in other words, to model attributes of an object. A cow has horns. Injection is not essential to this. The Visitor pattern is a way to perform an external action on a type. They serve different purposes and operate on different portions of the object model. To answer your question, I prefer composition when the logic of the situation calls for a type to have an attribute, and the Visitor pattern to organize code to perform an action on instances of a type without altering the structure of the target type, as documented for that pattern.
"Visitor design pattern is very similar to the way composition work."
It is actually not. Composition is a basic principle for object creation like Abstraction, Encapsulation, Polymorphism etc. It is simply a has-a relationship. Adapter, Composite and Decorator patterns are perfect examples for utilizing Composition principle.
Visitor pattern is rather a high level solution deduced from basic programming principles. The basic logic behind Visitor is method-overloading based on different sub-class types.
Ex: You have a base-class or interface named Bird and sub classes Crow, Duck and Penguin. And you want a method of some client class to act different w.r.t. the type of the sub-class. i.e. here assume, I want a Hunter class which differentiates the behavior of Hunter.hunt() method w.r.t. whether it is Crow, Duck or Penguin.
So my Hunter class looks like this.
public class Hunter{
public void hunt(Crow crow){
//crow hunting logic.
}
public void hunt(Duck duck){
//duck hunting logic.
}
public void hunt(Penguin penguin){
//penguin hunting logic.
}
}
And if I do like this,
Bird bird = new Duck();
Hunter hunter = new Hunter();
hunter.hunt(bird);
Now this hunter.hunt(); will automatically navigate into hunt(Duck duck) method and get executed.
I think you understood that there's no much relationship between composition principle and visitor pattern.
And as a final note, Visitor is not a good pattern in general. The reason is, it makes you keep overloading more and more methods when different new sub-classes are getting added. In our example if you want to add new classes like Pigeon, Eagle etc., you will have to add methods hunt(Pigeon pigeon) and hunt(Eagle eagle). This would be a terrible maintenance issue in large scale especially. So it would be better, if you use it only if there's no other option or no bouncing back.
maybe you should think where you can use mentioned patterns in order to understand the difference:
Composite:
Compose objects into tree structures to represent part-whole hierarchies.Group of objects is to be treated in the same way as a single instance of an object.
Drawing example(swing library from java):a drawing may be composed(composites) of graphic primitives, such as lines, circles, rectangles, text, and so on. But in order to draw we manipulate composites exactly the same way we manipulate primitive objects.
Visitor:
Allows for one or more operations to be applied to a set of objects at runtime, decoupling the operations from object structure.
Basic idea is to have same mechanism how to walk through object structure(object structure can be tree and that looks similar to Composite) and then on each step via objects in structure we can have one or more operations,
in compilers AST is object struture and visitor can be used to walk via AST and generate binary code, or XML output or ...
hope that this helps

Polymorphism vs Strategy pattern

What is the difference between the Strategy pattern and Polymorphism in Java?
I'm confused that whatever is achieved via Strategy Pattern is basically possible by polymorphism. Correct me if I'm wrong in this regard.
Please, also provide me example to eradicate my confusion.
For me, the link from CKing post and the example in Wikipedia are clear enough, but I'll try to give you a new example. As they said, Strategy Pattern is mostly a way to change the behaviour of an algorithm at runtime. Of course you can achieve this in many different ways (such as holding a value and using switch-case, but it wouldn't be as nice as Strategy Pattern).
Let's say you're developing a turn-based strategy game with two kind of Units: Infantry and Tank (subclasses of Unit). Your terrain could be Plains, Railroad or Forests.
class Unit{
MovementStrategy ms;
final int baseMovement;
int x,y;
public Unit(int baseMovement){
this.baseMovement = baseMovement;
}
abstract void fire();
void moveForward(){
x = x + ms.getHexagonsToMove(baseMovement);
}
void setMovementStrategy(MovementStrategy ms){
this.ms = ms;
}
}
Any Unit subclass must implement fire() method because it's going to be completely different for them (Tank shots heavy long-distance round and Infantry shot several short distance light bullets). In this example we use normal polymorphism/inheritance since fire() method will be really different for any unit, and it won't change during the game.
class Infantry extends Unit{
public Infantry(){
super(2);
}
void fire(){
//whatever
}
}
class Tank extends Unit{
public Tank(){
super(5);
}
void fire(){
//whatever
}
}
Units also are able to move, and have a field baseMovement that holds the number of hexagons it can walk. We're developing a strategy game, not a real world simulation, so we don't care how they move, we just want to add a value to their coordinates (in my example I only use X coordinate in order to get a simpler code). If all the terrain was the same, we wouldn't need any Strategy object... but we need to change the behaviour of move() method at runtime!
So, we implement a different MovementStrategy class for each of our kinds of Terrain, and we program our game to trigger a setMovementStrategy() to any unit that move on each hexagon. And we don't even need to write anything else in our Unit subclasses.
interface MovementStrategy{
public int getHexagonsToMove(int base);
}
class PlainMovementStrategy implements MovementStrategy{
public int getHexagonsToMove(int base){
return base;
}
}
class RailroadMovementStrategy implements MovementStrategy{
public int getHexagonsToMove(int base){
return base*3;
}
}
class ForestMovementStrategy implements MovementStrategy{
public int getHexagonsToMove(int base){
return (int)(base/2);
}
}
Now, when any Unit move inside a Forest, we call
unit.setMovementStrategy(new ForestMovementStrategy());
And as soon it goes to a Plain, we do:
unit.setMovementStrategy(new PlainMovementStrategy());
Now we're able to change how far away our units move depending on the Terrain, and we don't need to rewrite in any of the subclasses.
I hope this helps you a better understanding of the difference.
I'm confused that whatever is achieved via Strategy Pattern is basically possible by polymorphism.
You can't drive a car without a steering wheel. That does not mean that a steering wheel is a car. Similarly, the Strategy pattern relies on polymorphism but that does not mean that they are the same thing.
The purpose of the Strategy pattern is to promote the use of composition (has-a) over inheritance (is-a). Instead of your class inheriting behavior from a super class, you define the behavior in a separate class and your class has-a reference to it.
As far as an example goes, take a look at this answer that does a good job.
Basic difference : Polymorphism is programming language concept, and Strategy pattern is one of behavioral design pattern of GoF.
Polymorphism is the provision of a single interface for several different underlying data types.
Example: The steering wheel(i.e., the interface) is same no matter what type of actual steering mechanism is used. That is, the steering wheel works the same whether your car has manual steering, power steering, or rack-and-pinion steering. Therefore once you know how to operate the steering wheel, you can drive any type of car.
In programming, Polymorphism implemented in two ways:
Early-Binding/Static/Compile-Time Polymorphism (ex: function overloading)
Late-Binding/Dynamic/Run-Time Polymorphism (ex: function overriding)
A Strategy pattern defines a set of algorithms that can be used interchangeably.
The Strategy pattern is a dynamic pattern (How do you want run a behavior in software?).
Example of core java: java.util.Comparator#compare(), executed by among others Collections#sort().
Modes of transportation is analogous to strategy design pattern. We use car, bike, bus, local train and so on.. different strategies to go office day by day.
If you are establishing an analogy where:
in one case you have several overridable methods;
in the other case you have a Strategy interface with several implementations,
then the difference is the degree of coupling, which is very strong in the first case, whereas in the second case any foreign code can participate in your class's logic by contributing its Strategy implementation.
Q: What is the difference between the Strategy pattern and Polymorphism
in Java?
The questions is certainly confusing since initially there seems not to be any relation between these two ideas.
Polymorphism is a much broader concept in programming and yes the strategy pattern in Java uses a form of polymorphism catalogued as inclusion polymorphism to accomplish its intent, but this is by no means the only type of polymorphism that exists, neither it is the only way to implement the strategy pattern as I will demonstrate soon.
Also polymorphism is not something that only exists in Java or in object-oriented programming languages. Different forms of polymorphism exist in all the programming paradigms and not in all languages you are forced to use polymorphism to implement a strategy pattern (e.g. functional languages).
For further discussion on this topic please read this other answer where we have discussed whether polymorphism is possible without inheritance and I provide interesting references and examples to other types of polymorphism like parametric and ad-hoc polymorphism.
Ideally this will reveal to you that polymorphism is a bigger concept that goes beyond the boundaries of object-oriented programming and even beyond inheritance and subtyping.
Q: I'm confused that whatever is achieved via Strategy Pattern is
basically possible by polymorphism. Correct me if I'm wrong in this
regard.
From my point of view the relations between these two concepts are: that the strategy pattern leverages the power of polymorphism available in languages like Java to implement its intent, and that polymorphism can be considered in itself a pattern.
For instance, consider this quote from the GoF book:
If we assumed procedural languages, we might have included design
patterns called 'inheritance', 'encapsulation' and 'polymorphism'.
It is just that we rarely think of polymorphism as a pattern, first because it implies many things and because it is implemented differently in different languages and also because it typically presents as some form of language feature.
In his book Elemental Design Patterns, Jason Mc C. Smith comments on the GoF quote above saying:
Pattern are language-independent concepts; they take form and become
concrete solutions when you implement them within a particular
language with a given set of language features and constructs [...]
This means that it is a bit strange to talk about "Java design
pattern", "C++ design patterns", "Websphere design pattern" and so on,
even though we all do it. It's a mildly lazy form of shorthand for
what we really mean, or should mean: design patterns as implemented in
Java, C++, WebSphere and so on, regardless of language or API.
So, as you can see, you are thinking in the Strategy pattern from the perspective of the Java implementation, but in other language paradigms such pattern may have been implemented in different ways, probably without using inheritance at all, for example, in pure functional programming languages this is most certainly implemented using high order functions and function composition.
As such, this would be an strategy pattern implementation without resorting to inclusion polymorphism at all. In a function composition strategy we may still be using other forms of polymorphism (e.g. parametric), but that is not a requirement for the strategy pattern
Q: Please, also provide me example to eradicate my confusion.
As discussed above, in Java we are probably forced to use inclusion polymorphism to implement a Strategy pattern, but as explained above as well, patterns are not something that belong to a specific language, so if we think of the strategy pattern as a concept living outside any language boundaries then you will easily see other languages implement this in different ways.
In some hypothetical functional language I may have a function that reads some data from a file, maybe the file is encrypted and you need to provide a decryption strategy:
function readFile(path: String, decrypt: string -> string) {
return decrypt(loadFromDisk(path));
}
And that decrypt argument is a function that serves the purpose of a strategy pattern, it encapsulates an interchangeable algorithm.
Now you can do
readFile("customers.txt", aes)
readFile("finance.txt", blowfish)
Where aes and blowfish are decryption function strategies.
There are dozens of languages that work like this, SML, Haskell, JavaScript, etc.
First of all. Polymorphism can mean two different things. Most commonly polymorphism refers to a polymorphic type. However, you are asking for the pattern.
Polymorphic code can change itself each time it runs while the function of the code stays the same. An easy example is to do 1+3=4 instead of 5-1=4. Both achieves the same result using different code. This is useful for code that does not want to be recognized i.e computer viruses or cryptographic code.
Strategy pattern on the other hand uses a family of algorithms that can be interchanged. This might be used when translating text. First some code determines the language. if the language is swedish or spanish the text will be processed by, different functions of the same family, translateSwedish() or translateSpanish().
To round things up. Polymorphic code uses different code that achieves the same result. While Strategy uses different code to achieve better results.
Consider this
we have animals and a strategy pattern object to describe how they move...
for instance
fly/swim/walk
Given the large number of animals that use any of these methods (ie thousands of different animals fly), we need to use the same code for many different animals. That code should only exist in one place, so that it is easily changed and doesn't take up any unneeded space.
In this example, a straightforward polymorphism approach will result in massive code duplication. A more complex approach which places a intermediate class between animal and say robin fail to take in to consideration that how a animal moves is not really what defines it. Furthermore, it is possible that a animal has other strategy objects and they cannot all be made polymorphic through intermediate classes.
One definition for Polymorphism is the provision of a single interface to entities of different types.
With that in mind say you have a “bird” interface and all of your bird classes must implement “laysEggs()” method, well no biggie that works. And as you keep coding your “bird paradise program” you now add the “fly()” and realize that overloading and overriding for penguin and kiwi is unnecessary as in real life they can't fly, yet you must still implement that method. This can become tedious and pointless as you are faced with Ostrich and others that can't fly. And even worst off when adding the method “swim()” because even fewer birds can swim. As you may already know, the strategy pattern solves this problem.
In lame-man’s terms you can think of Polymorphism as a conglomerate of practices, while the Strategy Pattern is the best practice for a specific case. Example: the Strategy Pattern is to be used when an algorithm's behavior needs to be selected at Runtime (via interchangeable algorithms). And although it is sort of true that whatever is achieved via Strategy Pattern is basically possible by polymorphism, without knowledge of the Strategy Pattern this would leave you with the “reinvent the wheel” problem to solve this specific problem. In conclusion, they are very different even if one is based on the other.
I'll leave you to see “Ender Muab'Dib” code as it is well explained if you still want a code example from me just ask, cheers and hope I helped.
Polymorphism is a principle and Strategy is a design pattern
From oracle documentation page
The dictionary definition of polymorphism refers to a principle in biology in which an organism or species can have many different forms or stages. This principle can also be applied to object-oriented programming and languages like the Java language. Subclasses of a class can define their own unique behaviors and yet share some of the same functionality of the parent class.
Polymorphism can be achieved in compile time ( method overloading) and run time (method overriding).
Strategy_pattern
Defines a family of algorithms,
Encapsulates each algorithm, and
Makes the algorithms interchangeable within that family.
Strategy can use run-time polymorphism principle to achieve the desired functionality.
Strategy pattern had one more component called Context in it's URL diagram.
Refer to below SE posts:
Real World Example of the Strategy Pattern
Does this Java Strategy pattern have a redundant Context class?
Few more useful articles:
strategy by sourcemaking
Here is the concise response:
Polymorphism is one of the fundamental characteristics of
object-oriented programming.
Strategy pattern is a language-independent pattern that can be implemented by all
programming languages paradigms, such as imperative, functional, and
object-oriented.
Therefore, if you are going to implement Strategy pattern by using Java, that is OOP, then you just need to use polymorphism.
In other words, Strategy pattern is one of many forms of polymorphism.

How does an Interface in Java work?

I'm self learning Java, and I'm stuck on a chapter about Interfaces. I simply cannot understand how they work in Java.
I believe I understand perfectly what Interface means and how they apply in everyday situations and technology.
But when it comes to Java, code-wise and logic-wise, I'm stuck. I don't get it. How does the concept work?
Say I have 3 objects, and 1 interface object. 2 Objects are ObjectCalculatingA, ObjectCalculatingB, ObjectMathFunctions, and ObjectInterface.
Supposedly in ObjectInterface there must be some sort of reference to the ObjectMathFunctions, so that ObjectCalculatingA and B can just access the math functions in ObjectMathFunctions without writting them all again in A and B.
Am I right?
An interface exists to facilitate polymorphism. It allows declaring a contract that any class that implements the interface must honor. And so it is a way to achieve abstraction and model complexity by looking for commonality between things.
An example? How about shapes? All shapes have an area, right? So you could have the following classes:
Square
Circle
Then let's say you have another class that allows you to collect shapes, and return the total area:
for (Shape shape in shapes)
{
area += shape.area() //This is polymorphism
}
In the example above, we don't care whether the shape is a square or a circle. We can accept either. We only care that it implements the Shape interface. Each object will provide their own custom implementation of area - these internal details aren't important, only that it honors the area contract . See now how we're managing complexity? We can use the class without having to worry about all of the things that go on inside. At this point what it does is important to us, not how it does it, which lets us focus on the problem at hand not getting distracted by complex details.
This polymorphism is one of the reasons why object oriented programming was considered such a powerful evolutionary step in programming. The other key foundation concepts in Object Oriented Programming are:
Encapsulation
Inheritance
. . . you'll also need to learn these.
Abstract Base Class vs Interface
As a comment said, another way to achieve polymorphism is to use an Abstract Base Class. Which should you choose?
Use an interface class implementing it will have its own hierarchy and dependencies. For example a media player. A Movie Player and a Sound Player might have totally different base classes, so use an interface.
Use an Abstract base class when you have some commonality between things, but the specifics vary. For example a message parsing framework.
In simple lay mans language. Interface is a contract and classes implementing the interface need to adhere to the contract. There can be many implementations for same interface and users can select which implementation they wish to use. For more detailed information I suggest you read book like HeadFirst JAVA.
Once you begin software development you will understand that many a times you would come across an already implemented piece of code which you feel is not properly implemented. But at the same time a colleague of yours feels its correctly implemented and serves his purpose. This is where interfaces come into play. Your colleague who feels this implementation works for him can continue using the current one whereas you can implement your new implementation but you need to make sure that it adheres to the interface so that in future if your implementation is better, your colleague will have an oion to switch over.
List<String> myList = new ArrayList<String>();
In above example arraylist is on of the implementations of the List interface. Consider this example, ArrayList is not suiting your requirments so you can do the following.
myList = new LinkedList<String>();
This is the power of 'Coding to interface'
From your example, it shows that you lack a basic understanding of Object-Oriented Programming. You are trying to learn how to run without having learned to stand up yet.
In your example, you assume there is a class ObjectMathFunctions. This is not Object-oriented at all, classes should model a real concept.
1. Learn about objects / classes
You should first learn how classes and objects work. A class is not just any arbitrary division of code, it models something real. Examples: Car, Wheel, etc.
2. Learn about inheritance
After you understand that, learn about inheritance: a Car has a getWeight() method. A Wheel has a getWeight() method as well. Hmm, maybe they are both subdivisions of a broader concept: PhysicalThings. Every PhysicalThing has a getWeight() method.
After this, learn about overriding methods in subclasses, learn about abstract classes, etc.
3. Learn about interfaces
Now you will understand that an interface is very similar to an abstract class. You will have done some exercises where you already encountered the problem "This is a PhysicalThing, but it is also CanExplode (e.g. wheel of car, dynamite, etc). This single inheritance model is annoying, how do I fix this?".
If you know that a class can consist of both data and the functions that operate on the data, then an interface is just a list of the functions that a class has to implement.
Take a light switch interface, ILightSwitch ...
public interface ILightSwitch {
void turnOn();
void turnOff();
}
A class implements an interface if it implements those functions above.
e.g. A LightSwitch class might be
public class LightSwitch implements ILightSwitch {
boolean on = false;
void turnOn() { on = true; }
void turnOff() { on = false; }
}
The LightSwitch class implements the ILightSwitch interface.

OOP Task (class hierarchy, inheritance, interface, etc.)

Since I am trying to learn more about OOP (Java) I'm working my way through some literature where I found this 'task'. Unfortunately I am having kind of a hard time since I am pretty new to OOP and I don't have any sample solution to this. Maybe some of you can give me some input so can work my way through this.
Define a class hierarchy for these classes:
quadrilateral
convex quadrilateral
trapezoid
parallelogram
rhombus
rectangle
square
Create an instance of each class if possible
Define reasonable attributes and methods in each class
Overload and override methods
Write reasonable constructors for each class
Use modifiers (abstract, static, final, public, protected and private) in a meaningful way
How could an interface be used for this task?
01 Class hierarchy
Okay, this is simple math and you can find tons of information on the hierarchy of quadrilaterals everywhere. Here is what I did:
Creating Objects of each class is no big deal, but I still have some problems with understanding all the OOP-techniques. There are some points where I don't know what would be the better way to do it... (e.g. the square which inherits from two classes, which in java is simply not possible). Also, formulas (like calculating the surface area) would be overwritten all the time anyhow (since they are different most of the time), so why would I need inheritance anyway? Couldn't I just use an interface, use it in all of those classes an force them to implement these formulas?
Greetings - Vulpecula
In real life, you probably would be better off using an interface. Deep inheritance structures like that are often frowned upon; it's generally considered good to 'prefer composition over inheritance' (http://en.wikipedia.org/wiki/Composition_over_inheritance). You might for instance have a 'quadrilateral' interface that defines 'surface area' and 'perimeter', and then have the other shapes satisfy that interface.
If this is a homework question however, then you should probably base the class hierarchy on whatever examples your textbook/teacher have provided previously. It's not about designing robust software, it's about proving to your teacher that you learned how to do things in whatever way they think you should do them.
An abstract class as the base of a moderately complicated hierarchy is not as flexible as an interface. A class--abstract or not--forces a specific type of implementation.
Without thinking too hard about it, here's one way to start:
public interface Quadrilateral {
int getTopMillimeters();
int getLeftMillimeters();
int getRightMillimeters();
int getBottomMillimeters();
}
From this raw data, you could also define
getTopLeftAngle(), getTopRightAngle(), ...
which would all compute their values based on the lengths.
I too would emphasize composition over inheritance. The end-effect can indeed be a complex inheritance structure.
For me, composition is heirarchy of "Composer" classes, which do NOT implement the interface. Such as
public class QuadrilateralComposer {
private final int iTopMM;
private final int iBtmMM;
...
public QuadrilateralComposer(int i_topMM, int i_bottomMM, ...) {
if(i_topMM < 1) {
throw new IllegalArgumentException...
}
if(i_bottomMM < 1) {
throw new IllegalArgumentException...
}
...
iTopMM = i_topMM;
iBtmMM = i_bottomMM;
...
}
public int getTopMillimeters() {
return iTopMM;
}
...
Which is then composed by an abstract class:
public class AbstractQuadrilateral implements Quadrilateral
private final QuadrilateralComposer qc;
public AbstractQuadrilateral(int i_topLen, int i_bottomLen, ...) {
gc = new QuadrilateralComposer(i_topLen, i_bottomLen, ...);
}
public int getTopLength() {
return gc.getTopLength();
}
...
Abstract classes never extend other abstract classes, they only use internal Composers (and actually implement the interface). On the other end, Composers only extend Composers, and use other composers internally.
(Three notes: Protected functions are in the Composer as public function_4prot() and are implemented as protected function(), which call the _4prot version. And sometimes the abstract class can indeed implement everything in the interface. In this case, it would be concrete [non-abstract] and be named "SimpleXYZ", instead of "AbstractXYZ". Finally, static utility functions reside in the Composer.)
If EVERY interface is designed in this way, then ANY class can easily implement ANY interface, regardless which class they must actually extend. If abstract classes extend other abstract classes, that is a lot more work for classes that need to implement the interface, but happen to--and have to--extend something else.
This is not what you asked, but learning this concept changed my code for the WAY better. Seeing it mentioned in the accepted answer made me think through all of it. I've actually been slowly drifting away from inheritance to composition over the past few years, and after reading Effective Java, it was the final nail in the inheritance coffin, as it were.
Okay, the plan now is that I am trying to resolve this without any interface first. So here's the map of inheritance:
I am ignoring the fact, that the square is not only a rectange but also a rhombus.
The abstract class (quadrilateral) will define (but not implement) methods for calculating 'surface area' and 'perimeter'. Overriding methods is easy since every shape has different formumals for calculation but I am not really sure where I could use the overloading feature.
One more thing: Using an interface, would this be the desired way?

Disadvantage of object composition over class inheritance

Most design patten books say we should "Favor object composition over class inheritance."
But can anyone give me an example that inheritance is better than object composition.
Inheritance is appropriate for is-a relationships. It is a poor fit for has-a relationships.
Since most relationships between classes/components fall into the has-a bucket (for example, a Car class is likely not a HashMap, but it may have a HashMap), it then follows the composition is often a better idea for modeling relationships between classes rather than inheritance.
This is not to say however that inheritance is not useful or not the correct solution for some scenarios.
My simple answer is that you should use inheritance for behavioral purposes. Subclasses should override methods to change the behaviour of the method and the object itself.
This article (interview with Erich Gamma, one of the GoF) elaborates clearly why Favor object composition over class inheritance.
In Java, whenever you inherit from a class, your new class also automatically becomes a subtype of the original class type. Since it is a subtype, it needs to adhere to the Liskov substitution principle.
This principle basically says that you must be able to use the subtype anywhere where the supertype is expected. This severely limits how the behavior of your new inherited class can differ from the original class.
No compiler will be able to make you adhere to this principle though, but you can get in trouble if you don't, especially when other programmers are using your classes.
In languages that allow subclassing without subtyping (like the CZ language), the rule "Favor object composition over inheritance" is not as important as in languages like Java or C#.
Inheritance allows an object of the derived type to be used in nearly any circumstance where one would use an object of the base type. Composition does not allow this. Use inheritance when such substitution is required, and composition when it is not.
Just think of it as having an "is-a" or a "has-a" relationship
In this example Human "is-a" Animal, and it may inherits different data from the Animal class. Therefore Inheritance is used:
abstract class Animal {
private String name;
public String getName(){
return name;
}
abstract int getLegCount();
}
class Dog extends Animal{
public int getLegCount(){
return 4;
}
}
class Human extends Animal{
public int getLegCount(){
return 2;
}
}
Composition makes sense if one object is the owner of another object. Like a Human object owning a Dog object. So in the following example a Human object "has-a" Dog object
class Dog{
private String name;
}
class Human{
private Dog pet;
}
hope that helped...
It is a fundamental design principle of a good OOD. You can assign a behaviour to a class dynamicly "in runtime", if you use composition in your design rather than inheritance like in Strategy Pattern. Say,
interface Xable {
doSomething();
}
class Aable implements Xable { doSomething() { /* behave like A */ } }
class Bable implements Xable { doSomething() { /* behave like B */ } }
class Bar {
Xable ability;
public void setAbility(XAble a) { ability = a; }
public void behave() {
ability.doSomething();
}
}
/*now we can set our ability in runtime dynamicly */
/*somewhere in your code */
Bar bar = new Bar();
bar.setAbility( new Aable() );
bar.behave(); /* behaves like A*/
bar.setAbility( new Bable() );
bar.behave(); /* behaves like B*/
if you did use inheritance, the "Bar" would get the behaviour "staticly" over inheritance.
Inheritance is necessary for subtyping. Consider:
class Base {
void Foo() { /* ... */ }
void Bar() { /* ... */ }
}
class Composed {
void Foo() { mBase.Foo(); }
void Bar() { mBase.Foo(); }
private Base mBase;
}
Even though Composed supports all of the methods of Foo it cannot be passed to a function that expects a value of type Foo:
void TakeBase(Base b) { /* ... */ }
TakeBase(new Composed()); // ERROR
So, if you want polymorphism, you need inheritance (or its cousin interface implementation).
This is a great question. One I've been asking for years, at conferences, in videos, in blog posts. I've heard all kinds of answers. The only good answer I've heard is preformance:
Performance differences in languages. Sometimes, classes take advantage of built-in engine optimizations that dynamic compositions don't. Most of the time, this is a much smaller concern than the problems associated with class inheritance, and usually, you can inline everything you need for that performance optimization into a single class and wrap a factory function around it and get the benefits you need without a problematic class hierarchy.
You should never worry about this unless you detect a problem. Then you should profile and test differences in perf to make informed tradeoffs as needed. Often, there are other performance optimizations available that don't involve class inheritance, including tricks like inlining, method delegation, memoizing pure functions, etc... Perf will vary depending on the specific application and language engine. Profiling is essential, here.
Additionally, I've heard lots of common misconceptions. The most common is confusion about type systems:
Conflating types with classes (there are a couple existing answers concentrate on that here already). Compositions can satisfy polymorphism requirements by implementing interfaces. Classes and types are orthogonal, though in most class-supporting languages, subclasses automatically implement the superclass interface, so it can seem convenient.
There are three very good reasons to avoid class inheritance, and the crop up again and again:
The gorilla/banana problem
"I think the lack of reusability comes in object-oriented languages, not functional languages. Because the problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle." ~ Joe Armstrong, quoted in "Coders at Work" by Peter Seibel.
This problem basically refers to the lack of selective code reuse in class inheritance. Composition lets you select just the pieces you need by approaching software design from a "small, reusable parts" approach rather than building monolithic designs that encapsulate everything related to some given functionality.
The fragile base class problem
Class inheritance is the tightest coupling available in object-oriented design, because the base class becomes part of the implementation of the child classes. This is why you'll also hear the advice from the Gang of Four's "Design Patterns" classic: "Program to an interface, not an implementation."
The problem with implementation inheritance is that even the smallest change to the inner details of that implementation could potentially break child classes. If the interface is public, exposed to user-land in any way, it could break code you are not even aware of.
This is the reason that class hierarchies become brittle -- hard to change as you grow them with new use-cases.
The common refrain is that we should be constantly refactoring our code (see Martin Fowler et al on extreme programming, agile, etc...). The key to refactor success is that you can't break things -- but as we've just seen, it's difficult to refactor a class hierarchy without breaking things.
The reason is that it's impossible to create the correct class hierarchy without knowing everything you need to know about the use-cases, but you can't know that in evolving software. Use cases get added or changed in projects all the time.
There is also a discovery process in programming, where you discover the right design as you implement the code and learn more about what works and what doesn't. But with class inheritance, once you get a class taxonomy going, you've painted yourself into a corner.
You need to know the information before you start the implementation, but part of learning the information you need involves building the implementation. It's a catch-22.
The duplication by necessity problem. This is where the death spiral really gets going. Sometimes, you really just want a banana, not the gorilla holding the banana, and the entire jungle. So you copy and paste it. Now there's a bug in a banana, so you fix it. Later, you get the same bug report and close it. "I already fixed that". And then you get the same bug report again. And again. Uh-oh. It's not fixed. You forgot the other banana! Google "copy pasta".
Other times, you really need to work a new use-case into your software, but you can't change the original base class, so instead, you copy and paste the entire class hierarchy into a new one and rename all the classes you need in the hierarchy to force that new use-case into the code base. 6 months later a new dev is looking at the code and wondering which class hierarchy to inherit from and nobody can provide a good answer.
Duplication by necessity leads to copy pasta messes, and pretty soon people start throwing around the word "rewrite" like it's no big deal. The problem with that is that most rewrite projects fail. I can name several orgs off the top of my head that are currently maintaining two development teams instead of one while they work on a rewrite project. I've seen such orgs cut funding to one or the other, and I've seen projects like that chew through so much cash that a startup or small business runs out of money and shuts down.
Developers underestimate the impact of class inheritance all the time. It's an important choice, and you need to be aware of the trade offs you opt into every time you create or inherit from a base class.

Categories

Resources