Difference between revisions of "Object Oriented Programming (OOP)"
(→Composition over Inheritance) |
(→Encapsulation) |
||
Line 25: | Line 25: | ||
== Encapsulation == | == Encapsulation == | ||
− | Encapsulation provides objects with the ability to hide their internal characteristics and behavior. Each object provides a number of methods, which can be accessed by other objects and change its internal data. In Java, there are three access modifiers: public, private and protected. Each modifier imposes different access rights to other classes, either in the same or in external packages. Some of the advantages of using encapsulation are listed below: | + | Encapsulation provides objects with '''the ability to hide their internal characteristics and behavior'''. Each object provides a number of methods, which can be accessed by other objects and change its internal data. In Java, '''there are three access modifiers: public, private and protected'''. Each modifier imposes different access rights to other classes, either in the same or in external packages. Some of the advantages of using encapsulation are listed below: |
The internal state of every objected is protected by hiding its attributes. | The internal state of every objected is protected by hiding its attributes. |
Revision as of 01:31, 27 June 2018
Java is a computer programming language that is concurrent, class-based and object-oriented. The advantages of object oriented software development are shown below:
- Modular development of code, which leads to easy maintenance and modification.
- Reusability of code.
- Improved reliability and flexibility of code.
- Increased understanding of code.
Object-oriented programming contains many significant features, such as encapsulation, inheritance, polymorphism and abstraction. We analyze each feature separately in the following sections.
Contents
SOLID principles
SOLID is one of the most popular sets of design principles in object-oriented software development. It’s a mnemonic acronym for the following five design principles:
S – Single-Responsibility Principle.
O – Open-Closed Principle.
L – Liskov Substitution Principle.
I – Interface Segregation Principle.
D – Dependency Inversion Principle.
Encapsulation
Encapsulation provides objects with the ability to hide their internal characteristics and behavior. Each object provides a number of methods, which can be accessed by other objects and change its internal data. In Java, there are three access modifiers: public, private and protected. Each modifier imposes different access rights to other classes, either in the same or in external packages. Some of the advantages of using encapsulation are listed below:
The internal state of every objected is protected by hiding its attributes. It increases usability and maintenance of code, because the behavior of an object can be independently changed or extended. It improves modularity by preventing objects to interact with each other, in an undesired way.
more on Encapsulation..
Polymorphism
Polymorphism is the ability of programming languages to present the same interface for differing underlying data types. A polymorphic type is a type whose operations can also be applied to values of some other type.
more on Polymorphism..
Inheritance
Inheritance provides an object with the ability to acquire the fields and methods of another class, called base class. Inheritance provides re-usability of code and can be used to add additional features to an existing class, without modifying it.
more on Inheritance
Abstraction
Abstraction is the process of separating ideas from specific instances and thus, develop classes in terms of their own functionality, instead of their implementation details. Java supports the creation and existence of abstract classes that expose interfaces, without including the actual implementation of all methods. The abstraction technique aims to separate the implementation details of a class from its behavior.
more on Abstraction..
Differences between Abstraction and Encapsulation
Abstraction and encapsulation are complementary concepts. On the one hand, abstraction focuses on the behavior of an object. On the other hand, encapsulation focuses on the implementation of an object’s behavior. Encapsulation is usually achieved by hiding information about the internal state of an object and thus, can be seen as a strategy used in order to provide abstraction.
Composition vs Inheritance
Both composition and inheritance are object oriented programming concepts. They are not tied up with any specific programming language such as java. Before we compare composition over inheritance programmatically, let’s have a quick definition about them.
Composition
Composition is the design technique in object oriented programming to implement has-a relationship between objects. Composition in java is achieved by using instance variables of other objects. For example, Person has-a Job relationship is implemented like below in java object oriented programming.
package com.journaldev.composition;
public class Job {
// variables, methods etc.
}
package com.journaldev.composition;
public class Person {
//composition has-a relationship
private Job job;
//variables, methods, constructors etc.
}
Inheritance
Inheritance is the design technique in object oriented programming to implement is-a relationship between objects. Inheritance in Java is implemented using extends keyword.
For example, Cat is a Animal relationship in java programming will be implemented like below.
package com.journaldev.inheritance;
public class Animal {
// variables, methods etc.
}
package com.journaldev.inheritance;
public class Cat extends Animal{
}
Composition over Inheritance
Both composition and inheritance promotes code reuse through different approaches. So which one to choose? How to compare composition vs inheritance. You must have heard that in programming you should favor composition over inheritance. Let’s see some of the reasons that will help you in choosing composition vs inheritance.
- Inheritance is tightly coupled whereas composition is loosely coupled. Let’s assume we have below classes with inheritance.
package com.journaldev.java.examples;
public class ClassA {
public void foo(){
}
}
class ClassB extends ClassA{
public void bar(){
}
}
For simplicity we have both the superclass and subclass in single package. But mostly they will be in separate codebase. There could be many classes extending the superclass ClassA. A very common example of this situation is extending Exception class.
package com.journaldev.java.examples;
public class ClassA {
public void foo(){
}
public int bar(){
return 0;
}
}
As soon as you start using new ClassA implementation, you will get compile time error in ClassB as The return type is incompatible with ClassA.bar(). The solution would be to change either the superclass or the subclass bar() method to make them compatible.
If you would have used Composition over inheritance, you will never face this problem. A simple example of ClassB implementation using Composition can be like below.
class ClassB{
ClassA classA = new ClassA();
public void bar(){
classA.foo();
classA.bar();
}
}
- There is no access control in inheritance whereas access can be restricted in composition. We expose all the superclass methods to the other classes having access to subclass. So if a new method is introduced or there are security holes in the superclass, subclass becomes vulnerable. Since in composition we choose which methods to use, it’s more secure than inheritance. For example, we can provide ClassA foo() method exposure to other classes using below code in ClassB.
class ClassB {
ClassA classA = new ClassA();
public void foo(){
classA.foo();
}
public void bar(){
}
}
This is one of the major advantage of composition over inheritance.
- Composition provides flexibility in invocation of methods that is useful with multiple subclass scenario. For example, let’s say we have below inheritance scenario.
abstract class Abs {
abstract void foo();
}
public class ClassA extends Abs{
public void foo(){
}
}
class ClassB extends Abs{
public void foo(){
}
}
class Test {
ClassA a = new ClassA();
ClassB b = new ClassB();
public void test(){
a.foo();
b.foo();
}
}
So what if there are more subclasses, will composition make our code ugly by having one instance for each subclass? No, we can rewrite the Test class like below.
class Test {
Abs obj = null;
Test1(Abs o){
this.obj = o;
}
public void foo(){
this.obj.foo();
}
}
This will give you flexibility to use any subclass based on the object used in the constructor.
- One more benefit of composition over inheritance is testing scope. Unit testing is easy in composition because we know what all methods we are using from other class. We can mock it up for testing whereas in inheritance we depend heavily on superclass and don’t know what all methods of superclass will be used. So we will have to test all the methods of superclass. This is an extra work and we need to do it unnecessarily because of inheritance.
That’s all for composition vs inheritance. You have got enough reasons to choose composition over inheritance. Use inheritance only when you are sure that superclass will not be changed, otherwise go for composition.