JAVA Object Oriented Concepts
Java in based on Object Oriented concepts, which permits higher level of abstraction to solve any problem in realistic way.
Object oriented approach conceptualize the problem solution in real-world object which are easier to reuse across the application. For example Chair, Fan, Dog, computer etc.
In Java, a class is a blueprints, template or prototype that define common behavior of object of same kind. An instance is realization of a particular class and all instances of a class have similar properties, as described in the class definition. For example, you can define a class called House with number of room as attribute and create instances such as house with 2 rooms, house with 3 rooms etc.
Below are few advantages of object oriented software development:
- Less maintenance cost mostly because it is modular.
- Better code reusability due to features such as inheritance and hence faster development.
- Improved code reliability and flexibility
- Easy to understand due to real-world modeling.
- Better abstraction at object level.
- Reduced complexity during the transitions from one development phase to another.
There are four main features of OOPS:
Encapsulate provides contract to other object to what to hide and what to expose which can be accessed other objects. In java we use private access modifier to hide method and variable to restrict from outer world. Java also provide different access modifier such as public, default, protected and private, which use to hide the visibility on different level but end goal is to encapsulate the things, which need not to change. As per best practice A class should have only one reason to change and Encapsulate bring the reality to achieve “one-reason” design principle.
As per best practices in Encapsulation means hiding things that are expected to change often so to avoid breaking other classes.
Benefits: Below are few advantages of Encapsulation:
- We can protect the internal state on objects by hiding its attribute.
- It Improves code modularity by preventing objects interacting with each other in an unexpected way.
- Increases usability
- It Maintain the contracts of specific object
- Encapsulation promotes maintenance
- Code changes can be made independently
Polymorphism is the ability (in programming) to present the same interface for differing underlying forms (data types). That means classes have different functionality while sharing a common interface and can be invoked dynamically by passing specific class reference.
The classic example is the Shape class and all the classes that can inherit from it (square, circle, dodecahedron, irregular polygon, splat and so on).
In this example, every class would have its own Draw () function and the client code could simply do:
Shape shape=new Square ();
Shape.area() to get the correct behavior for any shape.
The beauty of polymorphism is that the code working with the different classes does not need to know which class it is using since they’re all used the same way.
The process used by object-oriented programming language to implement run-time polymorphism is called dynamic binding.
Note: Polymorphism is the ability to select more specialized methods in runtime depending on the object being used to call it. Polymorphism could occur with no abstract classes involved.
- Create Reusable code: It means once classes create, implemented and tested then it can be easily used without caring what written in the class.
- It provides more generic and loosely coupled code.
- Compile time is much lower and allow faster development.
- Dynamic binding:
- Same interface could be used for creating methods with different implementations
- Complete implementation can be replaced by using same method signatures
Method Overriding to achieve Polymorphism: Overriding deals with two methods; one in the parent class and the other one in the child class and have the same name and signatures.
Overriding lets you define the same operation in different ways for different object types
Shape s = (Shape) it.next();
totalArea += s.area(dim); //polymorphic method call. Will call right object method
Method Overloading or Ad-hoc polymorphism or static polymorphism:
Overloading deals with multiple methods in the same class with the same name but different method signatures. Overloading lets you define the same operation in different ways for different data. Some time it says as static polymorphism but actually it is not polymorphism.
Method overloading is nothing more than having two methods with the same name but different argument lists. It has nothing to do with inheritance and polymorphism. An overloaded method is not the same as an overridden method. [Head First Java]
Parametric polymorphism through generics in Java:
Within a class declaration, a field name can associate with different types and a method name can associate with different parameter and return types. Java supports parametric polymorphism via generics.
An example is a list, which can accept the type of data it contains through generics.
List<String> list = new ArrayList<String>();
Why we can’t override a static method in Java?
Overriding depends on having an instance of a class. The point of polymorphism is that you can subclass a class and the objects implementing those subclasses will have different behaviors for the same methods defined in the superclass (and overridden in the subclasses). A static method is not associated with any instance of a class so the concept is not applicable.
There were two considerations driving Java’s design that impacted this. One was a concern with performance: there had been a lot of criticism of Smalltalk about it being too slow (garbage collection and polymorphic calls being part of that) and Java’s creators were determined to avoid that. Another was the decision that the target audience for Java was C++ developers. Making static methods work the way they do had the benefit of familiarity for C++ programmers and was also very fast, because there’s no going up the class hierarchy to figure out which method to call, you go straight to the class and call the specified method. [Stack overflow]
It is the inclusion of behavior (i.e. methods) and state (i.e. variables) of a base class in a derived class so that they are accessible in that derived class. The key benefit of Inheritance is that it provides the formal mechanism for code reuse and avoids duplication
Inherited class extends application’s functionality by reusing parent behavior and adding new functionalities. This will make the design tight coupled because if you want to change the superclass, you must know all the details of the subclasses to avoid breaking
It is form of software reusability where new class (sub class) are created from already existing class (super class) which enhance the functionalities while using some of the properties from super class.
So if you have a Parents class, then you have a Child class that extends Parent, Child inherits all the things that Person has.
- Improve reusability
- Establishes logically “is a” relationship: e.g. Dog is a animal
- Modularize code
- Avoid duplicity
- Tightly coupled: Subclass depends on parent class implementation that’s why tight couple.
Abstraction means develop class in terms of their interfaces and functionality, instead of their implementation details. Abstract class expose interfaces without including actual implementation. It separates the object implementation from its behavior or implementation. Abstraction reduces the complexity by hiding irrelevant detail.
- By using abstraction, we can separate the things that can be grouped to another type.
- Frequently changing properties and methods can be grouped to a separate type so that the main type need not under go changes. This adds strength to the OOAD principle -”Code should be open for Extension but closed for Modification”.
- Simplifies the representation of the domain models.
Difference between Abstraction and Encapsulation
Encapsulation is a strategy used as part of abstraction. Encapsulation refers to the state of objects – objects encapsulate their state and hide it from the outside; outside users of the class interact with it through its methods, but cannot access the classes state directly. So the class abstracts away the implementation details related to its state.
Abstraction is a more generic term; it can also be achieved by (amongst others) sub classing. For example, the class List in the standard library is an abstraction for a sequence of items, indexed by their position, concrete examples of a List are an ArrayList or a LinkedList. Code that interacts with a List abstracts over the detail of which kind of a list it is using [Stack overflow]
Abstraction is often not possible without hiding underlying state by encapsulation – if a class exposes its internal state, it can’t change its inner workings, and thus cannot be abstracted
What is abstract class and abstract method?
In design, you want the base class to present only an interface for its derived classes. This means, you don’t want anyone to actually instantiate an object of the base class. You only want to upcast to it (implicit upcasting, which gives you polymorphic behavior), so that its interface can be used. This is accomplished by making that class abstract using the abstract keyword.
Provide some restriction on to not to instantiate the abstract class and whoever use should implement the abstract method. And provide polymorphism
Abstract class can contain both abstract methods and concrete methods. In a class, if one method is declared abstract, the class must be declared abstract. However, reverse of this is not necessarily true. If class is declared abstract class, it may not have abstract method in it.
If a method does not provide actual implementation but just provides method signature, it is called abstract method. Actual implementation is left for the sub classes who extend abstract class.
Abstract method cannot be instantiated; another class can only extend it.
When to use an abstract class?
Abstract classes let you define some default behavior and force subclasses to provide any specific behavior.
For example: List is interface whereas AbstractList provide default behavior of List which can be used as is or refined in subclass e.g. ArrayList.
What is Interface?
The interface keyword takes this concept of an abstract class a step further by preventing any method or function implementation at all. You can only declare a method or function but not provide the implementation. The class, which is implementing the interface, should provide the actual implementation. The interface is a very useful and commonly used aspect in OO design, as it provides the separation of interface and implementation and enables you to:
Benefits on interface:
- Multiple inheritance
- Loose coupling-defined abstraction of operation as separate layer-underline implementation could be anything, JDBC, JPA, JTA etc.
- Program to interface not implement
- Polymorphism with dynamic binding – Reveal an object’s programming interface without revealing its actual implementation.
- Abstract Layer: Separation concerns
Difference between interface and abstract class:
- An interface is a contract to ask classes (whoever going to implement interface) to implement the interface the way it defines in interface. It is an empty shell with method declaration.
- Abstract class define some common behavior and ask subclass to define uncommon or specific behavior to that class
- Methods and members of an abstract class can be defined with any visibility, whereas all methods of an interface must be defined as public
- When inheriting an abstract class, the child class must define the abstract methods, whereas an interface can extend another interface and methods don’t have to be defined
- A child class can only extend a single abstract (or any other) class, whereas an interface can extend or a class can implement multiple other interfaces.
- A child class can define abstract methods with the same or less restrictive visibility, whereas a class implementing an interface must define the methods with the exact same visibility
- Interface doesn’t contain constructor whereas Abstract class does.
- Variables declared in a Java interface is by default final. An abstract class may contain non-final variables
- Members of a Java interface are public by default. A Java abstract class can have the usual flavors of class members like private, protected, etc
Code reusability could be achieved by implementing inheritance or composition but the composition approach to code reuse provides stronger encapsulation than inheritance, because a change to a back-end class needn’t break any code that relies only on the front-end class.
Composition is the design technique to implement has-a relationship in classes. We can use java inheritance or Object composition for code reuse
Composition is about expressing relationships between objects. Think about the chair example. A chair has a Seat. A chair has a back. And a chair has a set of legs. The phrase “has a” implies a relationship where the chair owns, or at minimum, uses, another object. It is this “has a” relationship which is the basis for composition
- Control the visibility
- Implementation can replace run-tim
- Loose coupled as interface class doesn’t depends on implementation.
Difference between Composition and Inheritance?
|No.||Composition (has a)||Inheritance (is a)|
|1||Advocates polymorphism and code reuse||Advocates polymorphism and code reuse|
|2||Object is acquired at Done at run- time||Object is acquired dynamically at compile-time|
|3||Implementation can be replaced at run-time||Implementation can be replaced at compile-time|
|4||Subclass doesn’t depends parent class and favors loose coupling (specifically in interface driven)||Subclass depends on parent class implementation that’s why tight couple|
|5||Used when House has a Bathroom. It is incorrect to say House is a bathroom||Inheritance is Uni-directional. e.g. House is a Building. But Building is not a House|
Note: Don’t use inheritance just to get code reuse. If there is no ‘is a’ relationship then use composition for code reuse.
Difference between Composition and aggregation in Object Relationship
Aggregation: Aggregation is an association in which one class belongs to a collection. This is a part of a whole relationship where a part can exist without a whole. It is weaker relationship. No cyclic dependency. Example: Order and product
Composition: Composition is an association in which one class belongs to a collection. This is a part of a whole relationship where a part cannot exist without a whole. If a whole is deleted then all parts are deleted. It is stronger relationship. e.g. Polygon and points, order and order detail