Inheritance:
When we want to create a new class and there is already a class that includes some of the code that we want, we can derive our new class from the existing class. In doing this, we can reuse the fields and methods of the existing class.
Composition
The composition also provides code reusability but the difference here is we do not extend the class for this.
Inheritance |
Composition |
We define the class which we are inheriting(super class) and most importantly it cannot be changed at runtime |
We only define a type which we want to use and which can hold its different implementation also it can change at runtime. Hence, Composition is much more flexible than Inheritance. |
We can only extend one class, in other words more than one class can’t be extended as java does not support multiple inheritance. |
It allows to use functionality from different class. |
Inheritance cannot extend final class. |
Composition allows code reuse even from final classes. |
It is an is-a relationship. |
It is a has-a relationship. |
Inheritance should only be used when subclass ‘is a’ superclass. Don’t use inheritance to get code reuse. If there is no ‘is a’ relationship, then use composition for code reuse. Classes should achieve polymorphic behavior, design flexibility, and code reuse by their composition rather than inheritance from a base or parent class.
Example:
Inheritance:
class Person {
String title;
String name;
int age;
}
class Employee extends Person {
int salary;
String title;
}
Composition:
class Person {
String title;
String name;
int age;
public Person(String t, String n, int a) {
this.title = t;
this.name = n;
this.age = a;
}
}
class Employee {
int salary;
private Person person;
public Employee(Person p, int s) {
this.person = p;
this.salary = s;
}
}
Here the Employee class has a Person. It does not inherit from Person but instead gets the Person object passed to it, which is why it "has a" Person.
In your case:
Using Composition:
import java.util.Date;
class License{
String type;
String name;
public License(String t, String n) {
this.type = t;
this.name = n;
}
}
class A{
Date valid;
Date expire;
private License license;
public A(License l, Date v, Date e) {
this.license = l;
this.valid = v;
this.expire = e;
}
}
What if Licence and A both declared 'color'?
Should Documents.color return "Red" or "Blue"? Under composition this ambiguity is better handled:
class Documents {
String color;
public Documents(License li, A aa) {
this.color = li.color;
}
}
The Documents object is composed as an Licence and a class A. The Color behavior is taken from class Licence. This explicit composition removes ambiguity among other things and you'll encounter fewer bugs.
General rule of thumb: Before using inheritance, consider if composition makes more sense.
Reason: Subclassing usually means more complexity and connectedness, i.e. harder to change, maintain, and scale without making mistakes. Prefer composition over inheritance.