Object-Oriented Programming
Object-oriented programming is a programming practice or we can call it a programming paradigm. Which is the most popular practice among programmers based on objects and classes. The most commonly used OOP languages are Java, JavaScript, C#, and Python.
Let us have a brief look at the basics of OOP.
The Object
The object is any real-world entity.
Ex: Cat, Car, Software Engineer, Student, Flower
It has its own states and behaviors.
ex: Cat
States :
The cat has a color.
The cat has a name.
The cat has a puffy tail.
Objects are instances of classes, which serve as blueprints or templates defining the structure and behavior of the objects. Objects encapsulate both data (attributes or properties) and behavior (methods or functions) into a single unit, promoting modularity, reusability, and maintainability in software development.
The Class
A class is a blueprint or template that defines the structure and behavior of objects. It specifies the attributes (fields) and methods that the objects of the class will have. Not consume any memory space.
example :
In this example:
- The
Person
class defines attributes (name
andage
), a constructor for instantiation, and a method (introduce
) for behavior. - Two objects (
person1
andperson2
) are created based on thePerson
class. - The objects’ attributes are accessed, and their methods are called in the
main
method.
Objects in OOP provide a way to model and interact with entities in a software system, facilitating a modular and reusable approach to software design. They enable the creation of systems that closely mirror real-world scenarios.
Core concepts of Java
- Inheritance (IS-A) — (Represent IS A Relationship)
With the use of inheritance, the information is made manageable in a hierarchical order. When some object needs to use all the states/properties and behaviors of another object it is called inheritance. The new object will be the child and the object we inherited from is a parent.
ex: Software engineer object inherited from employee object.
This means we can use the same code -reusable. So it provides run time polymorphism.
ex: Assume that we have several toys as below.
As you can see same methods are repeated in all toys. So we can take the common methods into one-up level class as below.
As you can see code repetition reduces. We can use the toys() supper class to inherit the other subclasses. (toycar, doll, musicbook)
Polymorphism:
poly means multiple. So If one task can be done in different ways, it is known as polymorphism. Polymorphism occurs when we have many classes related to each other by inheritance.
ex: Animal object .Different animals can make sounds (behavior) .Like dog bark, cat mew, cow -moo .
In Java, we use method overloading and method overriding to achieve this.
class Animal {
public void animalSound() {
System.out.println("The animal makes a sound");
}
}
class Pig extends Animal {
public void animalSound() {
System.out.println("The pig says: wee wee");
}
}
class Dog extends Animal {
public void animalSound() {
System.out.println("The dog says: bow wow");
}
}
class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal(); // Create a Animal object
Animal myPig = new Pig(); // Create a Pig object
Animal myDog = new Dog(); // Create a Dog object
myAnimal.animalSound();
myPig.animalSound();
myDog.animalSound();
}
}
Method Overloading :
Method overloading allows a class to have multiple methods with the same name but different parameter lists. This means you can define two or more methods with the same name within the same class, as long as the number or types of parameters are different. The compiler determines which method to call based on the arguments provided during the method invocation.
Key Points about Method Overloading:
- Same Method Name:
- In an overloaded set of methods, all methods must have the same name.
2. Different Parameter Lists:
- Overloaded methods must have different types or numbers of parameters. This can include differences in the order of parameters.
3. Return Type:
- The return type alone does not determine method overloading. Two methods with the same name and parameter types but different return types will result in a compilation error.
4. Inheritance:
- Overloaded methods can exist in the same class or its subclasses. They can also be present in interfaces.
Example :
- In this example, the
MathOperations
class has two overloadedadd
methods—one for integers and another for doubles. It also has aconcatenate
method that takes two strings.
Benefits of Method Overloading:
- Improved Readability:
- Overloading allows you to use the same method name for logically similar operations, making the code more readable and intuitive.
2. Code Reusability:
- Overloaded methods promote code reuse by providing a single method name for different variations of the same operation.
3. Flexibility:
- Developers can choose the method that best fits their needs based on the types of arguments they want to pass.
4. Default Values (Java 8 and later):
- With the introduction of default values for method parameters in Java 8 and later versions, you can achieve a form of method overloading with fewer method signatures.
Method Overriding :
Method overriding is a concept in object-oriented programming that allows a subclass to provide a specific implementation of a method that is already defined in its superclass. The overridden method in the subclass should have the same method signature (name, return type, and parameters) as the method in the superclass. When an object of the subclass calls the overridden method, the subclass’s version of the method is executed instead of the superclass’s version.
Consider the above toy example. There are three toys which are can on the lights and play the music. But the toy car plays a piece of siren music and lights will on according to the music intervals.
Therefore the toy cars onLights() method and playMusic() methods differ from other toys.
Now here the same inherited methods from the supper class toys onLight() method and playMusic() methods have been overridden with special features that need to be performed within the toy car sub-class.
Key Points about Method Overriding:
- Inheritance Requirement:
Method overriding is applicable in an inheritance hierarchy, where a subclass inherits from a superclass.
2. Same Method Signature:
The overriding method in the subclass must have the same method signature (name, return type, and parameters) as the method in the superclass.
3. Annotation (Optional):
While not required, using the @Override
annotation before the method in the subclass helps the compiler catch errors if the method is not correctly overridden.
4. Access Modifiers:
The access level of the overriding method in the subclass cannot be more restrictive than the overridden method in the superclass. It can be the same or more permissive.
5. Return Type:
The return type of the overriding method must be the same as, or a subtype of, the return type of the overridden method. If the return types differ, it will result in a compilation error.
6. Checked Exceptions:
The overriding method is allowed to throw fewer, more specific, or no checked exceptions than the overridden method. It cannot throw broader or new checked exceptions.
Encapsulation
The meaning of Encapsulation is to make sure that “sensitive” data is hidden from users. To achieve this, you must:
- declare class variables/attributes as
private
- provide public get and set methods to access and update the value of a
private
variable
Getter and Setter
private
variables can only be accessed within the same class (an outside class has no access to it). However, it is possible to access them if we provide public get and set methods.
The get
method returns the variable value, and the set
method sets the value.
The syntax for both is that they start with either get
or set
, followed by the name of the variable, with the first letter in upper case:
Example
public class Person {
private String name; // private = restricted access// Getter
public String getName() {
return name;
}// Setter
public void setName(String newName) {
this.name = newName;
}
}
- Better control of class attributes and methods
- Class attributes can be made read-only (if you only use the
get
method), or write-only (if you only use theset
method) - Flexible: the programmer can change one part of the code without affecting other parts
- Increased security of data
Data Abstraction
Data abstraction is the process of hiding certain details and showing only essential information to the user.
Abstraction can be achieved with either abstract classes or interfaces
The abstract
keyword is a non-access modifier, used for classes and methods:
- Abstract class: is a restricted class that cannot be used to create objects (to access it, it must be inherited from another class).
- Abstract method: can only be used in an abstract class, and it does not have a body. The body is provided by the subclass (inherited from).
An abstract class can have both abstract and regular methods:
Interface
Another way to achieve abstraction in Java is with interfaces.
An interface
is a completely "abstract class" that is used to group related methods with empty bodies:
Example
// interface
interface Animal {
public void animalSound(); // interface method (does not have a body)
public void run(); // interface method (does not have a body)
}
To access the interface methods, the interface must be “implemented” (kinda like inherited) by another class with the implements
keyword (instead of extends
). The body of the interface method is provided by the "implement" class:
Notes on Interfaces:
- Like abstract classes, interfaces cannot be used to create objects (in the example above, it is not possible to create an “Animal” object in the MyMainClass)
- Interface methods do not have a body — the body is provided by the “implement” class
- On implementation of an interface, you must override all of its methods
- Interface methods are by default
abstract
andpublic
- Interface attributes are by default
public
,static
andfinal
- An interface cannot contain a constructor (as it cannot be used to create objects)
Why And When To Use Interfaces?
1) To achieve security — hide certain details and only show the important details of an object (interface).
2) Java does not support “multiple inheritances” (a class can only inherit from one superclass). However, it can be achieved with interfaces, because the class can implement multiple interfaces. Note: To implement multiple interfaces, separate them with a comma (see example below).