Category Archives: OOP Concepts

OOP Concept – Encapsulation

Overview

Encapsulation allows an object to separate its interface from its implementation. The data and the implementation code for the object are hidden behind its interface.

Encapsulation hides internal implementation details from users.

Example:
A Customer may issue a check and now know how it is processed. The internal processing is hidden from the customer. Similary, the inessential attributes of a class are hidden from users by using encapsulation. The hidden attributes of a class are called protected attributes.

It ensures that an object supplies only the requested information to another object and hides inessential information.

Example: When a user selects a command from a menu in an application, the code used to perform the actions of that command is hidden from the user.

Encapsulation packages the data and method of an object and provides protection from external tampering by users. It implies that there is visibility to the functionalities offered by an object, and no visibility to its data. The best application of encapsulation is making the data fields private and using public accessor methods.

However, you cannot hide an entire object. To use an object, a part of it needs to be accessed by users. To provide this access, abstraction is used. Abstraction provides access to a specific part of data while encapsulation hides the data. Therefore, abstraction and encapsulation compliment each other.

In OOP, abstraction defines the conceptual boundaries of an object. These boundaries distinguish an object from another objects.

Example: When a user designs an application by using existing templates, the complexity of the template is hidden from the user, but the essential features for creating the application are provided to the user. Abstraction enables an object to display these essential features to develop an application.

Encapsulation and Inheritance are two key concepts in OOP that serve different purposes. While encapsulation hides inessential information, inheritance allows the object of a class to adopt the attributes of another class.

When you implement inheritance in an application, the classes in the application are arranged in a strict hierarchy. The classes at the lower levels inherit the attributes of the classes at the higher levels.

In addition to inheriting the characteristics of the parent class, a class may have its own attributes. This feature implies that the code and characteristics of a class are reusable and extensible. However, inheritance compromises encapsulation because a subclass can directly access the parent’s protected attributes without using operations.

Related Post: Introduction to OOP | Inheritance | Polymorphism

OOP Concept – Polymorphism

Overview

Polymorphism means one entity existing in multiple forms. It provides flexibility to application systems. It simplifies coding and reduces the rework involved in modifying and developing an application. It refers to the ability of an object to take on different forms depending upon the situation.

According to the polymorphism design principle, the same message sent to different objects results in different behavior. The behavior depends on the type of object that receives the message.

Example:
Every key of a keyboard performs a specific action when a keystroke message is generated for that key. However, by using polymorphism, the same code with a small change can be used by different keys of the keyboard to trigger specific actions.

Polymorphism and Classes

In Java, type polymorphism may be implemented using class inheritance, interface implementation, or both. When using class inheritance to implement polymorphism, a class instance may take the form of itself, or any of its superclasses.

Fig 1.1

[Refer above Fig 1.1] When an instance of a class is created, it may always be referenced using its own type. Although this seems obvious, it is important because it is one of the forms that the object instance may take. In addition, since every class in Java has the class Object as a base class, the instance may also always be referenced as an Object.

When a class has a superclass, an instance of the class may also be referenced as if it is the superclass. For example, if a class Car is derived from the class Vehicle, an instance of Car may be referenced as a Vehicle. The possible type references for an instance of the Car class are shown below [Refer Fig 1.2].

Fig 1.2


Fig 1.3

[Refer Fig 1.3] A class instance can be referenced as any of the superclass types regardless of the depth of the inheritance

Example:
The class Mustang, which derives from Car, which derives from Vehicle. Here an Instance of the Mustang class may be referenced as any of its superclasses.

An instance of a class is also considered an instance of its superclass. The ‘instanceof’ operator can be used to show this relationship. When an object is an instance of a class, it is called an is-a relationship. The below example shows that the instance of the Mustang class, is also an instance of all of its superclasses. [Refer Fig 1.4,1.4a]

Fig 1.4

Fig 1.4a

Polymorphism and Interfaces

Fig 2.1

When an instance of a class is created, it may always be referenced using its own type. Refer Fig 2.1

If a class implements an interface, it may be referenced as the interface type. For example, a class CDPlayer implements MusicPlayer interface.[Refer Fig 2.2]

Fig 2.2

A class may implement as many interfaces as necessary. The example [Refer Fig 2,3] shows a new interface called MusicRecorder. The class CDPlayerRecorder implements the MusicPlayer and MusicRecorder interfaces.

Fig 2.3

When a class implements multiple interfaces, an instance of the class is considered an instance of the interfaces that it implements. Therefore, the class can be referenced as if it is any of its implemented interfaces.[Refer Fig 2.4]

Fig 2.4

An interface may extend other interfaces. When an interface extends other interfaces, a class that implements the interface also implements the extended interfaces. An instance of the class may be referenced using any of the interfaces, including the extended interfaces.[Refer Fig 2.5]

Fig 2.5

If a class has a superclass that implements an interface, an instance of the class may be referenced using the interface type.

Example: We have a CDPlayer class that implements the MusicPlayer interface. If we have a class CustomCDPlayer that derives from the CDPlayer class, the instance of the CustomCDPlayer may be referenced as a MusicPlayer. [Refer Fig 2.6]

Fig 2.6

Since a class may have superclasses as well as implemented interfaces, it therefore may be referenced both as superclass types and interface types.

Example: [Refer Fig 2.6] a CustomCDPlayer instance may be referenced using both the superclass CDPlayer, and the interface MusicPlayer.

Valid Variable Assignments

Java allows you to assign variables of a derived class with the instances of the base class and vice versa.

Upcasting:

When a derived class extends a base class, the derived class inherits all the members of the base class. It may also contain some additional methods and fields. In Java, you can assign an instance of the derived class to a variable type of base class.

Example: [Refer Fig 3.1]
Consider a class Wind that extends class Instrument. In this case, the class Wind inherits the methods of the class Instrument. In this case, the Wind derived class is a superset of the base class Instrument. It might contain more methods than the base class.

Fig 3.1

Downcasting:

Fig 3.2

It refers to assigning a variable of a base class to an instance of a derived class. This implies that the variables of the base class can be initialized to the base class or to one of the derived classes. [Refer Fig 3.2] If class Wind extends Instrument, you can initialize the variables of class Instrument to the instances of class Wind or class Instrument.

When downcasting, you should explicitly indicate a variable of type Brass to one of the variables of type Instrument. A faulty cast construct can cause a run-time error. If a base class is assigned to a derived class without a cast construct, it can lead to a compilation error. [Refer Fig 3.3]

Fig 3.3

Related Post: Introduction to OOP | Inheritance | Encapsulation

OOP Concept – Inheritance

Basics

Different kinds of objects often have a certain amount in common with each other. Tiger & Cow, for example share the characteristics of Animal; Yet each also defines additional features that make them different. Object-oriented programming allows classes to inherit commonly used state and behavior from other classes.

Inheritance provides a way to extend existing classes to make a new classes with specialized behavior. Inheritance creates a hierarchy of classes and helps you reuse the code of a parent class in a child class.

A Class inherits the attributes and behavior of its parent class or superclass. The attributes and behavior of the superclass need to be public or protected. Members of the superclass can be inherited with some restrictions.

Subclasses inherit the superclass members that are declared with no access modifiers, if the subclasses are in the same package as the superclass.

Example:

Tiger and Cow are the subclasses of the Animal class. Animal class contains all common behaviors and states that belong to animals [tiger or cow] however Tiger / Cow has distinct behaviors too. These are defined in their respective classes. Tiger & Cow classes are called subclasses because they are derived from the Animal class – the super class. They inherit the attributes and behavior of the Animal class. The subclasses may also define more attributes and behavior.

Syntax:
<<Access modifiers>> class <subclass name> extends <superclass name>

<<Access modifiers>> – default access [nothing] or public access [public keyword]

There are two types of inheritance, single inheritance and multiple inheritance.

Single Inheritance: A subclass inherits from a single class.
Multiple Inheritance: A class inherits from more than one immediate superclass.

HINT: Java classes cannot extend multiple classes. In Java, Only interfaces are allowed to extend multiple interfaces. Also, classes can implement multiple interfaces.

Although a subclass inherits all the members of its superclass, it cannot access the private member variables of the superclass. The public and protected member variables of the superclasses are accessible to a subclass. If the subclass is in the same package as the superclass, default members are also accessible.

Method Overridding

A subclass inherits members and methods from its superclass. However, a subclass can change the functionality of an inherited method by overriding the method.

Encapsulation allows an object to supply requested information to another object.
Overriding is the ability of a subclass to modify the behavior that it inherits from the superclass. By overriding a method, the developer is free to charge the implementations of the method in the subclass.

In Java terminology, the method in the subclass that has the same name and signature as a method in the superclass is called the overridding method. The method in the superclass is called the overridden method.

Example: Consider the class Employee that contains a method named calculateSalary. Consider Manager and Engineer subclasses that extend Employee Class. The process for calculating salary for Manager and Engineer are different from each other. And So, to solve this problem, you can override calculateSalary method of Employee class and provide different implementations in Manager and Engineer class seperately.

Guidelines for Overriding a Method

  • The overriding and overridden methods should have the same return type, method name, and the number, type, and order of arguments.
  • The overriding method should have equal or greater access than an overridden method.

‘Super’ Keyword

The ‘super’ keyword is used when a subclass needs to refer to its immediate superclass.

Constructor Overriding

Constructors contain code that initializes an object during instance creation. The object should be properly initialized. This is to ensure that the object is not in an invalid state and is usable.

A subclass calls a constructor defined by its superclass by using the ‘super’ keyword.

Syntax: super(arg 1, arg 2, ..);

In the displayed syntax, the super keyword specifies any arguments required by the constructors in the superclass. An implicit call to the zero argument is made, if the method does not appear on the first line of the subclasses constructor. The super method needs to be the first statement in a subclass constructor. These constructors run regardless of whether the super method exists. If the super method is not used, the default constructor of each superclass is automatically executed.

Final Classes

A Class than cannot have subclasses and the member variables of which cannot be overridden is called final class.
Similarly, methods and variables that cannot be overridden are called final methods and final variables, respectively.

When a class is declared as final, the class cannot be extended. Therefore, a final class cannot have subclasses. This provides security because other application developers cannot create subclasses for this final class or modify its behavior.

Example: String class in java.lang.String package. This class is declared as a final class because the authors of the class did not want anyone to extend it.

Syntax for Class: final class <Class Name>
Syntax for Method: final <return type> <method name>

Features of a Final Class In Short:

  • Restricts a class from being extended.
  • Prevents its methods from being overridden
  • Restricts the declaration of abstract methods.
  • Cannot be simultaneously declared as final and abstract.

HINT: Why Final class cannot have abstract methods?
This is because final classes cannot be extended and abstract methods need to be implemented in nonabstract subclasses.

Method lookup

Method lookup is the process that a Java program uses to identify the appropriate method to be invoked. The method lookup process in Java is derived from the inheritance hierarchy. Inheritance in Java is implemented by using the extends keyword.

Example:
class B extends A {…}
To denote that class B inherits from class A, you declare class B using the above syntax.

The method lookup process searches for the method in the class of the receiver object. If a matching method definition is not found, method lookup continues to look for the method in the superclass.

Java allows a subclass to access the methods and fields in the superclass by using the super keyword.

Fig 1.1
Fig 1.1
Let consider an example [Refer fig 1.1], class Vehicle is the base class that defines a variable wheels and a method displayDetails. Class Truck inherits from class Vehicle, and class Tanker inherits from class Truck. Although class Truck and class Tanker inherit from class Vehicle, the variable wheels declared in class Truck and class Tanker is local variable and does not refer to the variable wheels in the class Vehicle. Therefore, any reference to the variable wheels within a method of class Truck will refer only its local value.

To refer to wheels in Truck from within Tanker, you use the syntax super.wheels. Java casts this reference to the super type. Super.wheels is shorthand for ((Truck) this).wheels. However, you cannot use super to discover the value of wheels in Vehicle from within Tanker. To refer to the wheels in Vehicle from within Tanker, you use the syntax ((Vehicle)this).wheels from within Tanker.

The super keyword can be used to bypass the overridden version of a method in a subclass and run the version in the superclass. The super keyword can also be used to bypass a member variable in a subclass for accessing a member variable that has the same name in a superclass.

Suppose class Tanker contains the call super.displayDetails, this call actually invokes the method displayDetails in class Truck because Tanker has inherited it from Truck. If you use the syntax ((Vehicle) this).displayDetails(), it results in the execution of method displayDetails from Vehicle.

Related Post:
Introduction to OOP | Polymorphism | Encapsulation

OOP – Introduction

Advantages of OOP

OOP provides advantages over traditional structural programming languages. OOP facilitates writing applications by turning real-world objects into code components. OOP enables users to model real-world objects. Modeling means representing real-world objects as components in Java. Object-Oriented Programming allows programmers and customers to use the same terminology to explain the business domain and the program.

 

In Summary:

  • Enables the use of real-world modeling

  • Promotes the reuse of code

  • Provides flexibility in the modification of an existing application

  • Helps with the maintainability of code.

Let’s go in detail with the advantages…

Enables the use of real-world modeling

Consider an example. A car is an object that has specific attributes, such as an engine and wheels. Using OOP principles, you would model the car as a car object in Java that would have the same properties.

Creating applications that model the real world closely enables developers to understand an application faster than any other applications. Therefore, an application that implements OOP concepts effectively is implemented and used.

Promotes the reuse of code

Another advantage of OOP is that it promotes the reuse of code. The code used to define an object can be shared by several objects of an application. For E.g.: the code used to design a type of car can be used for designing different types of cars. This saves you from rewriting code for various types of cars. A benefit of code reuse is that it reduces the amount of code to write, debug, test, and possibly upgrade in the future.

 

Provides flexibility in the modification of an existing application

 

OOP promotes flexibility in the design and implementation of a solution. Maintenance and upgrades are seen as further cycles in application development. By using OOP practices, applications become easier to extend.

Consider an example of XYZ Corporation. The application used by the production department of this organization is currently designated to create two types of chairs, plastic and metal. To meet the demands of its customers, the organization decides to produce wooden chairs as well. To meet the change in the requirement, the XYZ

corp. needs to incorporate changes into its current application system. If the current system was built using OOP best practices, extensions to the system may be simplified. For Eg: the new chair type would be able to share or reuse some of the other chair types’ code.

 

Helps with the maintenance of Code

 

Finally, OOP helps in the maintenance of code. By using OOP, you can create separate components for different requirements. In OOP, a component is known as a class. For example, to design a payroll system of an organization, you could create classes such as Employee and Payroll. By creating the Employee and the Payroll classes, information related to each class can be segregated. An internal change in one of these classes should not affect the functionality of the other class. Therefore, the maintenance of a system is simplified by reducing dependencies in between classes.

 

OOP Design Principles

An application that implements Object-Oriented Programming (OOP) concepts is distinguished by four design principles. The four design principles are encapsulation, abstraction, inheritance, and polymorphism.

Encapsulation

Encapsulation hides the inner workings of an object from outside users of the object. This protects outside users from making internal changes or optimizations to such objects. The object needs only to maintain its external functionality to support its clients. Internal details, such as data representation, should not be accessible externally.

 

Abstraction

The principle of abstraction is modeling real-world objects as objects in Java. However, these objects are only modeled at a certain level of detail. Only the behavior and data that is needed by your application will be included in your model.

The abstraction design principle focuses on the essential characteristics of an object. In OOP, abstraction defines the conceptual boundaries of an object. These boundaries distinguish one type of object from another

Inheritance

The inheritance design principle allows a class to inherit the characteristics of another class. When inheritance is used in an application, the application consists of classes that are arranged in hierarchies. The classes defined at the lower levels of a hierarchy inherit from the classes higher up in the hierarchy.

By creating a hierarchy of classes, the characteristics and code of a class are made reusable. A class can inherit characteristics from other classes and provide additional features. The new class has its own attributes and the attributes of the existing class. This feature provides extensibility and reusability in classes.

 

Polymorphism

Polymorphism refers to the ability of an object to take on different forms depending upon the situation. Consider an example of a class Sedan that inherits from the class Car that inherits from the class Vehicle. An instance of the Sedan class can be referred to as a Sedan, a Car, or a Vehicle.

Polymorphism provides flexibility to an application based on requirements. It simplifies coding and reduces the rework involved in developing and modifying an application. This is because different types of objects can react to the same type of stimulus.

Related Post:
Inheritance | Polymorphism | Encapsulation