Object Oriented Programming
Object Oriented Programming
Concepts
Classes
Attributes & Methods
Constructor
Instance of Class
Accessing Attributes & Methods with Objects
Updating Attributes
Type of an Object
Introduction
Java is an object-oriented programming language. In an object-oriented approach, complex
problems are broken down into smaller parts.
Similar to Python, Java also has classes, encapsulation, inheritance, etc concepts.
1. Classes
While modelling real-life objects with object-oriented programming, we ensure to bundle
related information together to separate information of different objects.
Classes and objects are the two main aspects of object-oriented programming.
In Java, everything is based on classes and objects, along with their attributes and methods.
For example: In real life, mobile is an object. A Mobile has attributes, such as weight and
color, as well as methods, such as calling and playing music.
class
keyword.
Syntax
1
2
3
4
class ClassName {
// attributes
// methods
}
JAVA
The pascal case notation is followed for naming a class. For example: Scanner, System,
Mobile, BigInteger.
static
keyword.
In this unit, we'll learn instance attributes/methods i.e., without the
static
keyword.
main()
method.
Syntax
1
2
3
4
5
class ClassName {
dataType attributeName;
// methods
}
JAVA
Let's create a
Mobile
class with some attributes
Code
1
2
3
4
5
6
class Mobile {
String model;
String camera;
// methods
}
JAVA
__init__
method.
Code
1
2
3
4
class Mobile:
def __init__(self):
self.model
self.camera
PYTHON
static
keyword, which indicates that the method belongs to the class (i.e., class method).
To define the instance methods we just have to define the methods without the
static
keyword.
Code
1
2
3
4
5
6
7
8
class Mobile {
String model;
String camera;
void makeCall() {
System.out.println("calling...");
}
}
JAVA
Code
1
2
3
4
5
6
class Mobile:
def __init__(self):
self.model
self.camera
def make_call(self):
print("calling...")
PYTHON
3. Constructor
Similar to the
__init__
method in Python, Java consists of a constructor method. Unlike Java methods, a constructor
should be named the same as the class and should not return a value.
We majorly use the constructors to initialize the instance/non-static attributes.
Syntax
1
2
3
4
5
class ClassName {
ClassName() {
// constructor body
}
}
JAVA
The constructors are the special methods invoked whenever we instantiate a class.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mobile {
String model;
String camera;
Mobile(String modelSpecification, String cameraSpecification) {
model = modelSpecification;
camera = cameraSpecification;
}
void makeCall() {
System.out.printf("calling...");
JAVA
Expand
Mobile()
method is called as the constructor of the
Mobile
class. we have declared the instance attributes and initializing them using the constructor.
Comparison with Python
self
.
Code
1
2
3
4
5
6
class Mobile:
def __init__(self, model, camera):
self.model = model
self.camera = camera
def make_call(self):
print("calling...")
PYTHON
Example 2:
Overloading constructors
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mobile {
String model;
String camera;
Mobile(String modelSpecification) {
model = modelSpecification;
}
Mobile(String modelSpecification, String cameraSpecification) {
model = modelSpecification;
camera = cameraSpecification;
JAVA
Expand
Example 3:
Similar to
self
in Python, Java consists of
this
keyword to access the instance attributes and methods. In Java, however, we can access them
without using
this
keyword.
Code
1
2
3
4
5
6
7
8
9
10
11
class Mobile {
String model;
String camera;
Mobile(String model, String camera) {
this.model = model;
this.camera = camera;
}
void makeCall() {
System.out.printf("calling...");
JAVA
Expand
We can use
this
keyword and differentiate between the class and instance attributes/methods to increase the
readability of the code.
When the instance attribute name and method parameter are the same, using
this
keyword avoids confusion for the compiler. In the above code, we have
model
as the instance attribute and parameter for the
Mobile
constructor. Hence, we have used
this
keyword to represent the instance attribute inside the constructor.
We can also pass
this
as an argument to an instance/non-static method.
4. Instance of Class
An instance of a class is called an object. An object is simply a collection of attributes and
methods that act on those data.
The
new
keyword is a Java operator that is used to create the object.
The
new
operator is followed by a call to a constructor, which initializes the new object.
Syntax
1
ClassName obj = new ClassName(args);
JAVA
Here,
ClassName
is the name of the class.
obj
is the name (variable name) of the object.
args
indicates the arguments (comma-separated values) sent to the constructor.
Note
In order to keep the
main()
method easy to find and avoid any issues, it is important to keep the
main()
method in a class that is lexicographically higher (alphabetical order) than other classes or
interfaces.
Let's create a
Base
class with
main()
method and create an object of the
Mobile
class inside it.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mobile {
String model;
String camera;
Mobile(String modelSpecification, String cameraSpecification) {
model = modelSpecification;
camera = cameraSpecification;
}
void makeCall() {
System.out.println("calling...");
JAVA
Expand
Code
1
2
3
4
5
6
7
8
class Mobile:
def __init__(self, model, camera):
self.model = model
self.camera = camera
def make_call(self):
print("calling...")
mobile1 = Mobile("Samsung Galaxy S22", "108 MP")
PYTHON
mobile1
object.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mobile {
String model;
String camera;
Mobile(String modelSpecification, String cameraSpecification) {
model = modelSpecification;
camera = cameraSpecification;
}
void makeCall(long phnNum) {
System.out.printf("calling...%d", phnNum);
JAVA
Expand
Output
iPhone 12 Pro
12 MP
calling...9876543210
Comparison with Python
Code
1
2
3
4
5
6
7
8
9
10
11
class Mobile:
def __init__(self, model, camera):
self.model = model
self.camera = camera
def make_call(self, phn_num):
print("calling...{}".format(phn_num))
mobile1 = Mobile("iPhone 12 Pro", "12 MP")
print(mobile1.model)
print(mobile1.camera)
mobile1.make_call(9876543210)
PYTHON
Expand
Output
iPhone 12 Pro
12 MP
calling...9876543210
6. Updating Attributes
We can update the attributes of the objects. Let's create multiple instances of the
Mobile
class and update the attributes.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mobile {
String model;
String camera;
Mobile(String modelSpecification, String cameraSpecification) {
model = modelSpecification;
camera = cameraSpecification;
}
void makeCall(long phnNum) {
System.out.printf("calling...%d", phnNum);
JAVA
Expand
Output
Code
1
2
3
4
5
6
7
8
9
10
11
class Mobile:
def __init__(self, model, camera):
self.model = model
self.camera = camera
def make_call(self, phn_num):
print("calling...{}".format(phn_num))
mobile1 = Mobile("iPhone 13 Pro", "12 MP")
mobile2 = Mobile("iPhone 12 Pro", "12 MP")
mobile2.model = "Samsung Galaxy S22"
PYTHON
Expand
Output
iPhone 13 Pro
12 MP
Samsung Galaxy S22
108 MP
7. Type of an Object
The class from which an object is created is considered to be the type of that object.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mobile {
String model;
String camera;
Mobile(String modelSpecification, String cameraSpecification) {
model = modelSpecification;
camera = cameraSpecification;
}
void makeCall() {
System.out.println("calling...");
JAVA
Expand
Output
Mobile
In the above code,
mobile1
is the object of the class
Mobile
. Hence, the output is Mobile.
Comparison with Python
Code
1
2
3
4
5
6
7
8
9
class Mobile:
def __init__(self, model, camera):
self.model = model
self.camera = camera
def make_call(self, phn_num):
print("calling...{}".format(phn_num))
mobile1 = Mobile("Samsung Galaxy S22", "108 MP")
print(type(mobile1))
PYTHON
Output
<class '__main__.Mobile'>
Summary
Attributes are like variables within a class.
In Java, instance or class attributes/methods are distinguished with the
static
keyword.
Every class consists of a constructor. If the constructor is not defined in a class, the
Java compiler automatically creates a default constructor during the run-time.
Constructors
o A constructor should be named the same as the class and should not return a
value.
o During the creation of the object of a class, constructors are called implicitly.
final
or
abstract
Introduction
In the previous unit, we learned the instance attributes and methods.
In this unit, we'll learn the class attributes and methods. We'll also learn the static blocks.
1. Class Attributes
In Java, class attributes are also called static attributes. The
static
keyword is used to create the class attributes.
Attributes whose values stay common for all the objects are modelled as class Attributes.
Syntax
1
2
3
4
5
class ClassName {
static dataType attributeName;
// methods
}
JAVA
Let's create a
Cart
class with some class attributes.
Code
1
2
3
4
class Cart {
static int flatDiscount = 0;
static int minBill = 100;
}
JAVA
Code
1
2
3
class Cart:
flat_discount = 0
min_bill = 100
PYTHON
.
) notation. We can access the class attributes directly using the class name. There is no need
to create instances to access the class attributes.
The objects of the class can also access and modify the class attributes.
Code
1
2
3
4
5
6
7
8
9
10
11
class Cart {
static int flatDiscount = 0;
static int minBill = 100;
}
class Base {
public static void main(String[] args) {
System.out.println(Cart.flatDiscount);
System.out.println(Cart.minBill);
}
}
JAVA
Expand
Output
0
100
Comparison with Python
Code
1
2
3
4
5
6
class Cart:
flat_discount = 0
min_bill = 100
print(Cart.flat_discount)
print(Cart.min_bill)
PYTHON
Output
0
100
Example 2: Accessing class attributes using its object
Code
1
2
3
4
5
6
7
8
9
10
11
class Cart {
static int flatDiscount = 0;
static int minBill = 100;
}
class Base {
public static void main(String[] args) {
Cart cart1 = new Cart();
System.out.println(cart1.flatDiscount);
System.out.println(cart1.minBill);
JAVA
Expand
Output
0
100
Comparison with Python
Code
1
2
3
4
5
6
class Cart:
flat_discount = 0
min_bill = 100
cart_1 = Cart()
print(cart_1.flat_discount)
print(cart_1.min_bill)
PYTHON
Output
0
100
2. Class Methods
In Java, class methods are also called static methods. The
static
keyword is used to create the class methods.
The class methods cannot access the instance attributes or methods
Cart
class.
Code
1
2
3
4
5
6
7
8
class Cart {
static int flatDiscount = 0;
static int minBill = 100;
static void updateFlatDiscount(int newFlatDiscount) {
flatDiscount = newFlatDiscount;
}
}
JAVA
In Python, the
@classmethod
decorator is used to define the class methods.
Code
1
2
3
4
5
6
7
class Cart:
flat_discount = 0
min_bill = 100
@classmethod
def update_flat_discount(cls, new_flat_discount):
cls.flat_discount = new_flat_discount
PYTHON
The
main()
method should be always defined with
public
and
static
keywords in order to be accessible for the Java Virtual Machine (JVM) to call the
main()
method.
Note
JVM acts as a run-time engine to run Java applications. In Java code, it is the JVM that
actually calls the
main()
method
.
) notation. We can access the class methods directly using the class name. There is no need to
create instances to access the class attributes.
The objects of the class and instance methods can also access the class methods.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Cart {
static int flatDiscount = 0;
static int minBill = 100;
static void updateFlatDiscount(int newFlatDiscount) {
flatDiscount = newFlatDiscount;
}
}
class Base {
public static void main(String[] args) {
JAVA
Expand
Output
50
Comparison with Python
Code
1
2
3
4
5
6
7
8
9
10
class Cart:
flat_discount = 0
min_bill = 100
@classmethod
def update_flat_discount(cls, new_flat_discount):
cls.flat_discount = new_flat_discount
Cart.update_flat_discount(50)
print(Cart.flat_discount)
PYTHON
Output
50
Example 2: Accessing class methods using its object
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Cart {
static int flatDiscount = 0;
static int minBill = 100;
static void updateFlatDiscount(int newFlatDiscount) {
flatDiscount = newFlatDiscount;
}
}
class Base {
public static void main(String[] args) {
JAVA
Expand
Output
50
Comparison with Python
Code
1
2
3
4
5
6
7
8
9
10
11
class Cart:
flat_discount = 0
min_bill = 100
@classmethod
def update_flat_discount(cls, new_flat_discount):
cls.flat_discount = new_flat_discount
cart_1 = Cart()
cart_1.update_flat_discount(50)
print(cart_1.flat_discount)
PYTHON
Expand
Output
50
1. Instance methods can access class and instance attributes and methods
directly.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Cart {
static int flatDiscount = 0;
static int minBill = 100;
int totalBill = 150;
static String thankYou() {
return "Thank you for Shopping!";
}
String checkout() {
if (minBill > totalBill) { // accessing the class attribute 'minBill' inside an instance method
JAVA
Expand
Output
checkout()
, we have accessed the class attribute
minBill
and invoked the class method
thankYou()
. Similarly, an instance method can also be invoked from an instance method.
2. Class methods can access class attributes and class methods directly.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Cart {
static int flatDiscount = 0;
static int minBill = 100;
static boolean validateDiscount(int newFlatDiscount) {
boolean isValid = newFlatDiscount >= 0;
return isValid;
}
static void updateFlatDiscount(int newFlatDiscount) {
if (validateDiscount(newFlatDiscount)) { // accessing the class method
JAVA
Expand
Output
50
In the above code, we can see that inside the class method
updateFlatDiscount()
, we have invoked the class method
validateDiscount()
and accessed the class attribute
flatDiscount
3. Class methods cannot access instance attributes or instance methods
directly.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Cart {
static int flatDiscount = 0;
static int minBill = 100;
int totalBill = 150;
String checkout() {
if (minBill > totalBill) {
return "Minimum Bill should be 100";
}
return "Thank you for Shopping!";
JAVA
Expand
Output
file.java:15: error: non-static method checkout() cannot be referenced from a static context
checkout(); // calling instance method inside a class method
^
file.java:17: error: non-static variable totalBill cannot be referenced from a static context
System.out.printf("Your Bill is %d", totalBill);
In the above output, we can see that two errors have been thrown.
The first error occurred because we tried to call the instance method
checkout()
from a class method
printReceipt()
The second error occurred because we tried to access the instance attribute
totalBill
inside a class method
printReceipt()
keyword.
Class attributes can be accessed using the class name Instance attributes can only be accessed using
and also with the instance of that class. the instance of that class.
Class attributes can be accessed by class and instance Instance attributes cannot be accessed inside a
methods class method.
Class attributes reduce the amount of memory used by a Instance attributes do not reduce the amount of
program. memory used by a program.
Class attributes are shared among all instances of a Instance attributes are specific to the instance
class. of a class.
keyword.
A class method can be called with the class name Instance methods can access any class method and
and also with the instance of that class. class attribute directly.
Class Method Instance Method
The class methods can only access class The instance methods can access class and instance
attributes and class methods of another class or attributes and methods of another class or the same
the same class class.
The class methods use less memory for The instance methods use much memory as the
execution because memory allocation happens memory allocation happens every time when the
only once. method is called.
6. Static Blocks
A static block in a Java class consists of a set of instructions that are only executed once
when the class is loaded into memory. We can write any number of static blocks in a class.
A static block is also called a static initialization block because static blocks can be used to
initialize the static attributes (class attributes).
Syntax
1
2
3
static {
// body of the static block
}
JAVA
Cart
class.
Example 1:
Code
1
2
3
4
5
6
7
8
9
10
11
class Cart {
static int flatDiscount;
static int minBill;
static {
flatDiscount = 0;
minBill = 100;
}
}
class Base {
JAVA
Expand
Output
0
100
Example 2:
Code
1
2
3
4
5
6
7
8
9
10
11
import java.util.ArrayList;
class Cart {
static ArrayList<String> items = new ArrayList<>();
static {
items.add("Candy");
items.add("Lollipop");
}
}
JAVA
Expand
Output
[Candy, Lollipop]
Summary
The
static
keyword is used to create the class attributes.
The class attributes and methods can be accessed using the class name.
The object of a class can access both instance and class attributes and methods.
The static blocks are only executed once when the class is loaded into memory.
Inheritance - Part 1
Concepts
Inheritance
Final Class
Composition
Method Overriding
Introduction
Java is a class-based object-oriented programming language designed around the concept of
objects. Java programs can be structured efficiently using OOP concepts to improve
readability and reusability.
1. Inheritance
2. Polymorphism
3. Encapsulation
4. Abstraction
In this unit, we'll learn Inheritance in Java, and the remaining principles will be covered
later in the course.
1. Inheritance
Similar to Python, Java also consists of the concept of Inheritance.
Inheritance is the mechanism in Java by which one class is allowed to inherit the
features(fields and methods) of another class.
Example
1
2
3
4
5
6
7
8
class Mammal {
// attributes and methods
}
class Horse extends Mammal { // use of extends keyword to perform inheritance
// attributes and methods of Horse
}
JAVA
The
extends
is the keyword used to perform inheritance in Java.
The class that is derived from another class is called a subclass (also called a
derived/extended/child class). In the above example,
Horse
is the subclass.
The class from which the subclass is derived is called a superclass (also called a base/parent
class). In the above example,
Mammal
is the superclass.
In a class, attributes, methods, etc are called class members. Constructors are not class
members.
A subclass inherits all the members from its superclass. As constructors are not members,
subclasses cannot inherit them, but the constructor of the superclass can be invoked from the
subclass.
Mammal
and subclass
Horse
Superclass
1
2
3
4
5
6
7
8
9
10
11
class Mammal {
String name;
Mammal(String name) {
this.name = name;
}
void eat() {
System.out.println("I am eating");
}
}
JAVA
Expand
name
and a non-static method
eat()
to the
Mammal
class.
Subclass
1
2
3
4
5
6
class Horse extends Mammal {
void displayName() {
System.out.println("My name is " + name);
}
}
JAVA
displayName()
to the
Horse
class.
Code
1
2
3
4
5
6
7
8
9
10
11
class Mammal {
String name;
Mammal(String name) {
this.name = name;
}
void eat() {
System.out.println("I am eating");
}
}
JAVA
Expand
In the above code, we have implemented the inheritance and the subclass
Horse
inherits all the members of the superclass
Mammal
.
We have also created the
Base
class and created an object of a
Horse
. We are passing an argument to the constructor of the
Horse
which needs to be passed to the constructor of the
Mammal
class to initialize the
name
attribute.
In Java, the
super
keyword is used in subclasses to access the members and constructors of the superclass.
We will learn more about
super
keyword later in the course.
Unlike Python, in Java, we have to invoke a superclass constructor which accepts arguments
from the subclass constructor.
The parenthesis
()
along with the
super
keyword is used to invoke the superclass constructor. It must be the first statement in the
subclass constructor.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mammal {
String name;
Mammal(String name) {
this.name = name;
}
void eat() {
System.out.println("I am eating");
}
}
JAVA
Expand
Output
My name is Alex
I am eating
In the above code, we have
displayName()
of the
Horse
class, we have accessed the non-static attribute
name
of the
Mammal
class. As the subclass
Horse
inherits the attributes and methods of the superclass
Mammal
we can directly access them inside the
Horse
.
Comparison with Python
Code
1
2
3
4
5
6
7
8
9
10
11
class Mammal:
def __init__(self, name):
self.name = name
def eat(self):
print("I am eating")
class Horse(Mammal):
def display_name(self):
print("My name is " + self.name)
PYTHON
Expand
Output
My name is Alex
I am eating
IS-A Relationship
From the above code, we can say that
Horse
is a
Mammal
, this is called an IS-A relationship. For example, Apple is a Fruit, Car is a Vehicle, etc. The
concept of IS-A is based on Inheritance.
Inheritance is uni-directional. For example, House is a Building. But Building is not a House.
2. Final Class
The
final
keyword can be used for classes also. A class declared with
final
is called a final class.
The final classes cannot be extended (inherited). All the wrapper classes like
String
,
Integer
,
Float
, etc are final classes. Hence, we cannot inherit the wrapper classes.
Syntax
1
2
3
final class ClassName {
// body of the class
}
JAVA
Example 1:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
final class Product {
String name;
int price;
Product(String name, int price) {
this.name = name;
this.price = price;
}
void displayProductDetails() {
System.out.printf("Product: %s\n", this.name);
JAVA
Expand
Output
file.java:16: error: cannot inherit from final Product
class ElectronicItem extends Product {
^
Product
class as
final
. As the final classes cannot be inherited the error has been thrown.
Example 2:
Code
1
2
3
4
5
class Base extends Integer {
public static void main(String[] args) {
System.out.println("Inherited the Integer wrapper class");
}
}
JAVA
Output
3. Composition
Similar to Python, Java also consists of the concept of Composition.
Composition describes a class whose non-static attributes refer to one or more objects of
other classes.
In composition, an object contains another object, and the contained object cannot exist
without the other object.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
import java.util.*;
class Book {
String title;
String author;
Book(String title, String author) {
this.title = title;
this.author = author;
}
}
JAVA
Expand
Output
Title: Head First Design Patterns, Author: Eric Freeman
Title: Clean Code, Author: Robert C. Martin
In the above code, we have mentioned the
Book
class as the type of the ArrayList (i.e.,
ArrayList<Book>
) as it stores the objects of the
Book
class. This is similar to declaring
ArrayList<String>
,
ArrayList<Integer>
, etc which stores the corresponding wrapper class objects.
We have created two objects
book1
and
book2
of the
Book
class. Also created a
library
object and initialized its non-static attribute with the list of
Book
objects.
Here, the
library
object consists of the
Book
objects as its non-static attribute value. The
library
object consists of
book1
object and the
library
cannot exist without the
book1
object. Hence, the composition is achieved.
Comparison with Python
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
class Library:
def __init__(self, books):
self.books = books
def display_books(self):
for book in self.books:
PYTHON
Expand
Output
HAS-A Relationship
From the above code, we can say that the
Library
has a
Book
, this is called the HAS-A relationship.
For example, Car has a Engine, Human has a Heart, etc.
Inheritance: Prefer modeling with inheritance when the classes have an IS-A relationship.
Composition: Prefer modeling with composition when the classes have the HAS-A
relationship.
4. Method Overriding
Similar to Python, we can override methods in Java. Method overriding allows a subclass to
provide a specific implementation of a method that its superclass already provides.
When a method in a subclass has the same name, parameters, and return type as a method in
its superclass, then the subclass's method is said to override the superclass's method.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mammal {
void eat() {
System.out.println("Mammal is eating");
}
}
class Horse extends Mammal {
void eat() { // overrides the eat() method of Mammal class
System.out.println("Horse is eating");
}
}
JAVA
Expand
Output
Horse is eating
In the above code, the
eat()
method of the subclass
Horse
has overridden the
eat()
method of the superclass
Mammal
.
The
eat()
method of the
Mammal
class is said to be overridden method. The
eat()
method of the
Horse
class is said to be the overriding method.
Comparison with Python
Code
1
2
3
4
5
6
7
8
9
10
class Mammal:
def eat(self):
print("Mammal is eating")
class Horse(Mammal):
def eat(self):
print("Horse is eating")
horse = Horse()
horse.eat()
PYTHON
Output
Horse is eating
calling that method using the parent object (superclass object) invokes the method in
the parent class.
calling that method using the child object (subclass object) invokes the method in the
child class.
Code
1
2
3
4
5
6
7
8
9
10
11
class Mammal {
void eat() {
System.out.println("Mammal is eating");
}
}
class Horse extends Mammal {
void eat() {
System.out.println("Horse is eating");
}
}
JAVA
Expand
Output
Mammal is eating
Horse is eating
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mammal {
Mammal() {
System.out.println("Mammal");
}
void eat() {
System.out.println("Mammal is eating");
}
}
class Horse extends Mammal {
JAVA
Expand
Output
Mammal
constructor in the
Horse
class to override the constructor of the
Mammal
class. Here, we are breaking a rule that constructors of a class should consist of the same
name as the class.
As the constructor name is not matching with the class name of the
Horse
, the compiler considers it as a normal class method and the error has been thrown conveying
that the return type is required while declaring the methods.
2. The overriding method should have the same return type and parameters
Code
1
2
3
4
5
6
7
8
9
10
11
class Mammal {
void eat() {
System.out.println("Mammal is eating");
}
}
class Horse extends Mammal {
String eat() { // overriding method
return "Horse is eating";
}
}
JAVA
Expand
Output
the
eat()
method of the
Mammal
class accepts no arguments and the return type is
void
the
eat()
method of the
Horse
class accepts no arguments and the return type is
String
The overriding method
eat()
of the
Horse
class only differs with the return type when compared to the
eat()
method of the
Mammal
class. Hence error has been thrown.
3. A
final
method cannot be overridden
The
final
keyword can be used for methods also. A method declared with
final
is called a final method.
The purpose of creating the final methods is to restrict the unwanted and improper use of
method definition while overriding the method.
Syntax
1
2
3
final returnType methodName() {
// body of the method
}
JAVA
Code
1
2
3
4
5
6
7
8
9
10
11
class Mammal {
final void eat() { // final method
System.out.println("Mammal is eating");
}
}
class Horse extends Mammal {
void eat() {
System.out.println("Horse is eating");
}
}
JAVA
Expand
Output
Summary
In Java, inheritance is performed using the
extends
keyword.
A subclass inherits all the members from its superclass except the constructors.
In Java, the
super
keyword is used in subclasses to access the members and constructors of the
superclass.
The final classes cannot be inherited.
Inheritance consists of an IS-A relationship.
Composition consists of the HAS-A relationship.
Method overriding allows a subclass to provide a specific implementation of a
method that its superclass already provides.
Rules of Method Overriding
o Constructors cannot be overridden
o The overriding method should have the same return type and parameters
o A
final
Inheritance - Part 2
Concepts
The Super Keyword
o Accessing Attributes
o Invoking Methods
o Invoking Constructors
Types of Inheritance
o Single Inheritance
o Multilevel Inheritance
o Hierarchical Inheritance
Upcasting
Introduction
In the previous unit, we learned the concepts like inheritance and composition in Java.
In this unit, we'll learn the different types of inheritance, and more about
super
keyword, etc.
1. The
super
Keyword
The
super
is the keyword in Java, used to access the superclass members like attributes, methods, and
also the constructors inside the subclass.
Uses of
super
keyword
To access the attributes of the superclass when both superclass and subclass have
attributes with the same name.
To call the overridden methods of the superclass inside the subclass.
To invoke the superclass constructor having parameters explicitly from the subclass
constructor.
1.1 Accessing Attributes using
super
Keyword
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mammal {
String type = "animal";
}
class Horse extends Mammal {
String type = "mammal";
void display() {
System.out.println("Horse is a " + type);
System.out.println("Horse is an " + super.type); // accessing the superclass attribute
}
JAVA
Expand
Output
Horse is a mammal
Horse is an animal
In the above code, we have accessed the superclass attribute
type
inside the subclass using the
super
keyword.
Keyword
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mammal {
void eat() {
System.out.println("Eating");
}
}
class Horse extends Mammal {
void eat() { // overriding the eat() method of Mammal class
System.out.println("Horse eats grass");
super.eat(); // invoking the overridden method of the Mammal class
}
JAVA
Expand
Output
eat()
of the
Mammal
class inside the subclass using the
super
keyword.
Comparison with Python
In Python,
super()
is a built-in function that only allows us to access methods of the superclass.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mammal:
def __init__(self):
self.type = "animal"
def eat(self):
print("Eating")
class Horse(Mammal):
def eat(self): # overriding the eat() method of Mammal class
print("Horse eats grass")
super().eat() # invoking the overridden method of the Mammal class
PYTHON
Expand
Output
The constructors which do not accept arguments are also called non-parameterized
constructors. The constructors which accept arguments are also called parameterized
constructors.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mammal {
String name;
Mammal() {
System.out.println("Superclass constructor called");
}
}
class Horse extends Mammal {
String breed;
JAVA
Expand
Output
super()
When the superclass constructor is invoked explicitly, the
super()
must be the first statement inside the subclass constructor.
1.3.2 Invoking parameterized superclass constructor
When the superclass consists of a parameterized constructor, it needs to be called explicitly
using the
super()
and pass the required arguments
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mammal {
String name;
Mammal(String name) {
this.name = name;
}
}
class Horse extends Mammal {
String breed;
JAVA
Expand
Output
Alex
Shire
In the above code, we have invoked the superclass constructor which accepts a single
argument using the
super()
and passed the required argument.
Comparison with Python
What if we do not call the superclass constructors which accept arguments?
Code
1
2
3
4
5
6
7
8
9
10
11
class Mammal {
String name;
Mammal(String name) {
this.name = name;
}
void displayName() {
System.out.println("My name is " + name);
}
}
JAVA
Expand
Output
file.java:16: error: constructor Mammal in class Mammal cannot be applied to given types;
Horse(String name, String breed) {
^
required: String
In the above code, the superclass
Mammal
consists of a parameterized constructor. As we did not invoke the parameterized constructor
explicitly, the error has been thrown.
1.3.3 Superclass with overloaded constructors
If a superclass consists of overloaded constructors, only one constructor can be invoked.
let's create a superclass with two constructors. One non-parameterized constructor and a
parameterized constructor.
If we do not invoke any of the superclass constructors from the subclass, the Java
compiler implicitly invokes the non-parameterized constructor.
If we invoke any of the superclass constructors from the subclass, then the other
constructor will not be invoked.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mammal {
String name;
Mammal() {
System.out.println("Non-parameterized constructor");
}
Mammal(String name) {
System.out.println("Parameterized constructor");
}
}
JAVA
Expand
Output
Parameterized constructor
In the above code, the superclass
Mammal
consists of two overloaded constructors. We have invoked the parameterized constructor
inside the subclass constructor and can see that the non-parameterized constructor is not
invoked.
2. Types of Inheritance
Java majorly supports three types of inheritances with classes,
1. Single Inheritance
2. Multilevel Inheritance
3. Hierarchical Inheritance
The examples we have seen so far are all examples of single inheritances.
Code
1
2
3
4
5
6
7
8
9
10
11
class Mammal {
String name;
Mammal(String name) {
this.name = name;
}
}
class Horse extends Mammal {
String breed;
JAVA
Expand
Output
Alex
In the above code, there is only a single superclass
Mammal
and only a single subclass
Horse
and the
Horse
extends
Mammal
. Hence, it is called Single Inheritance.
Comparison with Python
Code
1
2
3
4
5
6
7
8
9
10
11
class Mammal:
def __init__(self, name):
self.name = name
class Horse(Mammal):
def __init__(self, name, breed):
super().__init__(name)
self.breed = breed
horse = Horse("Alex", "Shire")
print(horse.name)
PYTHON
Expand
Output
Alex
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mammal {
void eat() {
System.out.println("I am eating");
}
}
class Horse extends Mammal {
void run() {
System.out.println("I am running");
}
}
JAVA
Expand
Output
I am eating
I am running
I am known for my strength and stamina
In the above code, the
Horse
class extends
Mammal
and the
MustangHorse
class extends
Horse
. The
Horse
class acts as a subclass to
Mammal
and a superclass to
MustangHorse
. Hence, it is called Multilevel Inheritance.
Comparison with Python
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mammal:
def eat(self):
print("I am eating")
class Horse(Mammal):
def run(self):
print("I am running")
class MustangHorse(Horse):
def display_skill(self):
print("I am known for my strength and stamina")
PYTHON
Expand
Output
I am eating
I am running
I am known for my strength and stamina
Code
1
2
3
4
5
6
7
8
9
10
11
class Mammal {
public void eat() {
System.out.println("Eating ...");
}
}
class Horse extends Mammal {
public void run() {
System.out.println("Running ...");
}
}
JAVA
Expand
Output
Eating ...
Running ...
Eating ...
Bow bow ...
In the above code, the
Horse
class extends
Mammal
and the
Dog
class also extends
Mammal
. Here, both
Horse
and
Dog
are the subclasses of a single superclass
Mammal
. Hence, it is called Hierarchical Inheritance
Comparison with Python
Code
1
2
3
4
5
6
7
8
9
10
11
class Mammal:
def eat(self):
print("Eating ...")
class Horse(Mammal):
def run(self):
print("Running ...")
class Dog(Mammal):
def bark(self):
print("Bow bow ...")
PYTHON
Expand
Output
Eating ...
Running ...
Eating ...
Bow bow ...
3. Upcasting
In Java, a superclass reference variable can be used to refer to its subclass object i.e., we can
specify a superclass as a type while creating an object of its subclass. This process of
typecasting a subclass object to a superclass variable is called Upcasting.
In this case, we can access all the members of the superclass but can only access a few
members like overriding methods of the subclass.
Syntax
1
Superclass variableName = new Subclass();
JAVA
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mammal {
void eat() {
System.out.println("Mammal is eating");
}
}
class Horse extends Mammal {
void eat() { // overrides the eat() method of Mammal class
System.out.println("Horse is eating");
}
}
JAVA
Expand
animal
variable as
Mammal
and assigned it an object of
Horse
.
Here, before the execution of the code, the type of the
animal
variable will be
Mammal
. And during the actual execution, the type will be
Horse
.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mammal {
void sleep() {
System.out.println("Mammal is sleeping");
}
void eat() {
System.out.println("Mammal is eating");
}
}
class Horse extends Mammal {
JAVA
Expand
Output
Horse is eating
Mammal is sleeping
In the above code, we are able to invoke the
sleep()
method of superclass
Mammal
. And we can see that the
eat()
method of the
Horse
class is invoked instead of the
Mammal
class.
Example 2: Invoking a method specific to subclass
Code
1
2
3
4
5
6
7
8
9
10
11
class Mammal {
void eat() {
System.out.println("Mammal is eating");
}
}
class Horse extends Mammal {
void eat() {
System.out.println("Horse is eating");
}
JAVA
Expand
Output
run()
method which is specific to the
Horse
subclass. As we cannot access the methods that are specific to the subclass the error has been
thrown.
Before the execution, the type of the variable will be of the superclass, so the attributes will
not be inherited. Hence, we cannot access the attributes of the subclass.
Code
1
2
3
4
5
6
7
8
9
10
11
class Mammal {
String name = "Alex";
}
class Horse extends Mammal {}
class Base {
public static void main(String[] args) {
Mammal animal = new Horse();
JAVA
Expand
Output
Alex
In the above code, we are able to access the attribute of superclass
Mammal
Example 2: Accessing subclass attributes
Code
1
2
3
4
5
6
7
8
9
10
11
class Mammal {}
class Horse extends Mammal {
String breed = "Shire";
}
class Base {
public static void main(String[] args) {
Mammal animal = new Horse();
JAVA
Expand
Output
Summary
The
super
keyword can be used to,
o access the attributes of the superclass when both superclass and subclass have
attributes with the same name.
Types of inheritance,
Upcasting
o We can access all the members of the superclass but can only access a few
members like overriding methods of the subclass.
Access Modifiers
Concepts
Access Modifiers
Access Modifiers with Attributes
Access Modifiers with Methods and Constructors
Access Modifiers with Classes
More Method Overriding Rules
Introduction
In the previous units, we learned classes and class members like attributes, methods, etc. In
Java, it is possible to specify whether a class or any member of a class can be accessed in
another class/subclass of the same package, or another class/subclass of a different package.
In this unit, we'll learn different types of Access Modifiers that are used to control the
accessibility.
1. Access Modifiers
Access modifiers are the keywords that set access levels when used with the classes,
methods, constructors, attributes, etc.
In Java, we have four access modifiers to set the accessibility. They are,
1. Private: The access level of a private modifier is only within the declared class. It is
not accessible outside of the class.
2. Default: The access level of a default modifier is up to the class/subclass of the same
package. It cannot be accessed from outside the package.
3. Protected: The access level of a protected modifier is up to the class/subclass of the
same package and also to a different package through the subclass. A subclass is
required to access it from a different package.
4. Public: The access level of a public modifier is everywhere in the program. It means
that it is accessible from the class/subclass of the same/different package.
Package (Recap)
Let's learn the behaviour of different modifiers with classes, methods, etc.
2.1 Private
The keyword
private
is used to specify the private access modifier. The private access modifier has the most
restricted scope among all other access modifiers.
Syntax
1
private static dataType attributeName;
JAVA
final
, and
static
are called Non-Access Modifiers. We can use access modifiers along with non-access
modifiers. When a declaration consists of both access and non-access modifiers, the access
modifiers must be placed prior to the non-access modifiers as shown above.
The
private
attributes are accessible only within the declared class.
Example 1: Accessing private attributes within the declared class
Code
1
2
3
4
5
6
7
8
9
10
11
class Mobile {
private String model;
Mobile(String modelSpecification) {
model = modelSpecification;
}
public static void main(String[] args) {
Mobile mobile = new Mobile("iPhone 13 Pro");
System.out.println(mobile.model);
JAVA
Expand
Output
iPhone 13 Pro
In the above code, we are able to an create object and access the attribute as we have created
it inside the
Mobile
class.
Example 2: Accessing private attributes inside another class
Code
1
2
3
4
5
6
7
8
9
10
11
class Mobile {
private String model;
Mobile(String modelSpecification) {
model = modelSpecification;
}
}
class Base {
public static void main(String[] args) {
Mobile mobile = new Mobile("iPhone 13 Pro");
JAVA
Expand
Output
file.java:13: error: model has private access in Mobile
System.out.println(mobile.model);
^
In the above code, attribute is declared as private and tried to access it inside the
Base
class. As we have learned they are only accessed within the declared class. Hence, we are
unable to access them from any other class and the error is thrown.
The default attributes are accessible only to the classes or subclasses of the same package.
We cannot access them in other packages.
Let's understand it with an example by defining two classes in the same file.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mobile {
String model;
String camera;
Mobile(String modelSpecification, String cameraSpecification) {
model = modelSpecification;
camera = cameraSpecification;
}
}
class Base {
JAVA
Expand
Output
iPhone 13 Pro
12 MP
In the above code, no access modifiers are mentioned for attributes. Hence, they are
considered to be the default and we are able to access the attributes of the
Mobile
class inside the
Base
class.
2.3 Protected
The keyword
protected
is used to specify the protected access modifier.
Syntax
1
protected dataType attributeName;
JAVA
protected
, it means that it is accessible to the class/subclass of the same package and subclass of other
packages.
For example, we have a public
classA
of
packageA
having a protected attribute
name
and a
classB
of
packageB
(another package). Now, the
name
is accessible inside the
classB
only when the
classB
extends
classA
.
We will learn public classes later in this unit
The access modifier
protected
is less restrictive when compared to the default and private.
Code
1
2
3
4
5
6
7
8
9
10
11
class Mobile {
protected String model;
Mobile(String modelSpecification) {
model = modelSpecification;
}
}
class Base {
public static void main(String[] args) {
Mobile mobile = new Mobile("iPhone 13 Pro");
JAVA
Expand
Output
iPhone 13 Pro
In the above code, the protected attributes are accessible to other classes of the same package.
So, we are able to create objects and access the attributes and methods of it.
2.4 Public
The keyword
public
is used to specify the public access modifier.
Syntax
1
public dataType attributeName;
JAVA
public
, it means that those are accessible from the class/subclass of the same/different package.
Code
1
2
3
4
5
6
7
8
9
10
11
class Mobile {
public String model;
Mobile(String modelSpecification) {
model = modelSpecification;
}
}
class Base {
public static void main(String[] args) {
Mobile mobile = new Mobile("iPhone 13 Pro");
JAVA
Expand
Output
iPhone 13 Pro
In the above code, the public attributes are accessible from the class/subclass of the
same/different package. So, we are able to access them in another class (
Base
class) of the same package.
private Yes No No No No
Different
Access Same Same package Same package Different package
package
Modifier Class subclass other classes other classes
subclass
3.1 Private
The methods declared with the
private
access modifier can be called private methods.
Similarly, the constructors declared with the
private
access modifiers can be called private constructors.
1
2
3
private returnType methodName() {
// method body
}
JAVA
1
2
3
private ClassName() {
// constructor body
}
JAVA
The private methods and constructors are accessible only within the declared class.
Code
1
2
3
4
5
6
7
8
9
10
11
class Mobile {
private String model;
private Mobile(String modelSpecification) {
model = modelSpecification;
}
private void makeCall(long phnNum) {
System.out.printf("calling...%d", phnNum);
}
JAVA
Expand
Output
iPhone 13 Pro
calling...9876543210
In the above code, we are able to create objects and access the attributes and methods of the
Mobile
class as we access them inside the
Mobile
class.
Example 2: Accessing private methods inside another class
Code
1
2
3
4
5
6
7
8
9
10
11
class Mobile {
private String model;
private Mobile(String modelSpecification) {
model = modelSpecification;
}
private void makeCall(long phnNum) {
System.out.printf("calling...%d", phnNum);
}
}
JAVA
Expand
Output
In the above code, the constructor and method are declared as private and tried to access it
inside the
Base
class. As we have learned they are only accessed within the declared class. Hence, we are
unable to access them from any other class and the error is thrown.
Code
1
2
3
4
5
6
7
8
9
10
11
class Mobile {
String model;
Mobile(String modelSpecification) {
model = modelSpecification;
}
void makeCall(long phnNum) {
System.out.printf("calling...%d", phnNum);
}
}
JAVA
Expand
Output
iPhone 13 Pro
calling...9876543210
In the above code, no access modifiers are mentioned for the attribute, method, and
constructor. Hence, they are considered to be the default and we are able to access the
attributes of the
Mobile
class inside the
Base
class.
3.3 Protected
The methods and constructors declared with
protected
access modifiers can be called protected methods and protected constructors respectively.
1
2
3
protected returnType methodName() {
// method body
}
JAVA
1
2
3
protected ClassName() {
// constructor body
}
JAVA
Similar to the protected attributes, the protected methods and constructors are accessible to
the class/subclass of the same package and subclass of other packages.
Code
1
2
3
4
5
6
7
8
9
10
11
class Mobile {
protected String model;
protected Mobile(String modelSpecification) {
model = modelSpecification;
}
protected void makeCall(long phnNum) {
System.out.printf("calling...%d", phnNum);
}
}
JAVA
Expand
Output
iPhone 13 Pro
calling...9876543210
In the above code, the protected attributes, methods and constructors are accessible to other
classes of the same package. So, we are able to create objects and access the attributes and
methods of it.
3.4 Public
The methods and constructors declared with
public
access modifier can be called public methods and public constructors respectively.
1
2
3
public returnType methodName() {
// method body
}
JAVA
1
2
3
public ClassName() {
// constructor body
}
JAVA
Similar to the public attributes, the public methods and constructors are accessible from can
be accessed from the class/subclass of the same/different package.
Code
1
2
3
4
5
6
7
8
9
10
11
class Mobile {
public String model;
public Mobile(String modelSpecification) {
model = modelSpecification;
}
public void makeCall(long phnNum) {
System.out.printf("calling...%d", phnNum);
}
}
JAVA
Expand
Output
iPhone 13 Pro
calling...9876543210
In the above code, the public methods, etc are accessible from the class/subclass of the
same/different package. So, we are able to create objects and access the attributes and
methods in the
Base
class.
4. Access Modifiers with Classes
Classes in Java can only have Public or Default as access modifiers.
4.1 Public
The classes declared with
public
access modifier can be called public classes.
Syntax
1
2
3
public class ClassName {
// body of the class
}
JAVA
public
, it means that it is accessible from the class/subclass of the same/different package.
Previously we have learned what are packages. We have used different classes like
Scanner
,
Math
, etc of different packages by importing them to our Java program. This is because all those
are
public
classes. Hence, we are able to import and utilise them in our program.
A Java file can consist of only one public class.
Note: Currently we cannot define public classes in the provided code playground. We will
provide support to write public classes soon.
Syntax
1
2
3
class ClassName {
// body of the class
}
JAVA
A default class is accessible only to the classes or subclasses of the same package. We cannot
access the default classes in other packages.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Mobile {
String model;
String camera;
Mobile(String modelSpecification, String cameraSpecification) {
model = modelSpecification;
camera = cameraSpecification;
}
}
class Base {
JAVA
Expand
In the above code, no access modifiers are mentioned for both classes. Hence both the classes
are considered as the default classes.
Mobile
class is accessible inside the
Base
class and able to create objects.
Similar to classes, only the access modifiers public and default we learned till now are
applicable to Interfaces also and work in the same way.
Example 1:
Code
1
2
3
4
5
6
7
8
9
10
11
class Telephone {
private void makeCall(long phnNum) {
System.out.println("Calling from Telephone");
}
}
class Smartphone extends Telephone {
private void makeCall(long phnNum) {
System.out.println("Calling from Smartphone");
}
JAVA
Expand
Output
smartphone
object using the superclass
Telephone
. So, the
smartphone
object can access all the methods of the
Telephone
class and overriding methods of the
Smartphone
class.
Also we tried to invoke the
makeCall()
method of the
Smartphone
class. As the private method
makeCall()
cannot be overridden, the compiler tries to invoke the
makeCall()
method of the
Telephone
class. But the private methods are only accessible in the declared class. Hence, the error has
been thrown.
Let's declare the
smartphone
object using the
Smartphone
class.
Example 2:
Code
1
2
3
4
5
6
7
8
9
10
11
class Telephone {
private void makeCall(long phnNum) {
System.out.println("Calling from Telephone");
}
}
class Smartphone extends Telephone {
private void makeCall(long phnNum) {
System.out.println("Calling from Smartphone");
}
JAVA
Expand
Output
Calling from Smartphone
The above code works. This is because private methods cannot be inherited to the subclasses.
So, the Java compiler directly invokes the
makeCall()
method of the
Smartphone
class.
5. The access level cannot be more restrictive than the overridden method's
access level
We have learned that the
private
is more restrictive (i.e., narrow scope) and the
public
is less restrictive (i.e., widely scoped) access modifier.
Below is the hierarchy of the access modifiers based on the access levels, more restrictive to
less restrictive from left to right.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Telephone {
String model;
Telephone(String modelSpecification) {
model = modelSpecification;
}
protected void makeCall(long phnNum) {
System.out.println("Calling from Telephone");
}
}
JAVA
Expand
Output
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Telephone {
String model;
Telephone(String modelSpecification) {
model = modelSpecification;
}
private void makeCall(long phnNum) {
System.out.println("Calling from Telephone");
}
}
JAVA
Expand
Output
Calling from Smartphone
In the above code,
protected
modifier is less restrictive than the
private
. So, the
makeCall()
method of the
Telephone
class has overridden by the
makeCall()
method of the
Smartphone
class.
Summary
Accessibility of Access Modifiers
Same Different Different
Access Same Same package
package package package other
Modifier Class other classes
subclass subclass classes
private Yes No No No No
The public access modifier is having the widest scope among all the access modifiers.
Polymorphism
Concepts
Execution of a Java Code
Polymorphism
Introduction
In the previous units, we have seen the four core principles of object-oriented programming:
1. Inheritance
2. Polymorphism
3. Encapsulation
4. Abstraction
In this unit, we'll look into the execution of Java code and learn another important principle
of OOP called Polymorphism.
1. Compilation
2. Execution
Compilation: In this stage, the file containing our Java code (with
.java
extension) is passed through the compiler, which then converts the source code (our Java
code) into a machine-independent encoding, known as Bytecode. For each class inside the
source file, a separate class file (with
.class
as file extension) is created and the corresponding code is stored in it. The class files
generated are independent of the machine or OS (Operating System).
Note: The creation of bytecode,
.class
files, etc will happen internally in the code playground provided to you.
Execution: In this stage, the main class file i.e., the class that contains the
main()
method is passed to the Java Virtual Machine (JVM) and the code will be run after a few
checks like variables are initialized before they are used, rules for accessing private data and
methods are not violated, etc.
2. Polymorphism
Polymorphism is derived from two Greek words poly and morphs. The word poly means
"many" and morphs means "forms". So polymorphism means many forms.
1. Compile-time polymorphism
2. Runtime polymorphism
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Shapes {
public void area(int radius) {
System.out.println("Area of Circle = " + 3.14 * radius * radius);
}
public void area(double base, double height) {
System.out.println("Area of Triangle = " + 0.5 * base * height);
}
public void area(int length, int breadth) {
System.out.println("Area of Rectangle = " + length * breadth);
JAVA
Expand
Output
area
which differ in their parameters. We have also invoked the same method with different
numbers or types of arguments.
Here, compile-time polymorphism occurs and the decision of which method to be invoked for
which call is done in the compilation stage.
Code
1
2
3
4
5
6
7
8
9
10
11
class Mammal {
void eat() {
System.out.println("Mammal is eating");
}
}
class Dog extends Mammal {
void eat() {
System.out.println("Dog is eating");
}
}
JAVA
Expand
Output
Dog is eating
In the above code, we have used the superclass reference variable
mammal
to refer to its subclass object. We also invoked
eat()
method using the reference variable
mammal
. The method invocations with objects are resolved (i.e., deciding which method should be
called by the statement
mammal.eat()
) during the runtime.
During the runtime, the
mammal
refers to the
Dog
object and the method invocation is resolved and the
eat()
method of the
Dog
class has been invoked as it overrides the
eat()
method of the
Mammal
class.
Summary
The execution of a Java code will be commenced in two stages:- Compilation and
Execution.
Introduction
In the previous units, we have seen the four core principles of object-oriented programming:
1. Inheritance
2. Polymorphism
3. Encapsulation
4. Abstraction
In this unit, we'll learn another important principle of OOP called Encapsulation.
1. Encapsulation
Encapsulation in Java is a process of wrapping related code and data together into a single
unit, for example, a capsule which contains several medicines.
In Java, the idea behind encapsulation is to ensure that implementation details are not visible
to users by hiding data within a class to prevent unauthorized access and avoid unnecessary
modifications from outside the class.
Code
1
2
3
4
5
6
7
8
9
10
11
class Student {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
JAVA
Expand
Output
20
In the above code, we declared the attribute
age
, and
getAge()
,
setAge()
methods in the
Student
class. Here, we have bundled similar codes together in a single class.
To hide the implementation details, we have declared the
age
attribute as
private
and defined public methods
setAge()
and
getAge()
in the class.
This will restrict access to the attributes from outside the class. This is called Data Hiding.
Generally, getters start with get, followed by the variable name in camel case notation.
Example: getBalance, getName, getLength, etc.
Setters: The Setters are used to set a new value to the non-static attribute of a class. These
are also called mutators.
Generally, setters start with set, followed by the variable name in camel case notation.
Example: setBalance, setName, setLength, etc.
Getters and setters provide us with control over the data in our program. For example, we can
write conditions inside the
setAge()
method so that no one can provide an invalid age.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Student {
private int age;
public int getAge() {
return age;
}
public void setAge(int studentAge) {
if (studentAge >= 3) {
age = studentAge;
}
JAVA
Expand
Output
15
15
In the above code, we have written a condition in the setter method
setAge()
that a student's age must be greater than or equal to 3. So, when
15
is provided as an argument, the
age
attribute has been updated to
15
and when
1
is provided as an argument the
age
attribute has not been updated.
Summary
Encapsulation refers to the bundling of attributes and methods inside a single class.
Getter method returns the value of a particular non-static attribute of the class.
Setter method sets a new value to a particular non-static attribute of the class.
Getters and setters provide us with control over the data in our program.
Abstraction
Concepts
Abstraction
Abstract Classes and Methods
Implementing Abstract Classes and Methods
Abstraction vs Encapsulation
Introduction
In the previous units, we have seen the four fundamental principles of object-oriented
programming:
1. Inheritance
2. Polymorphism
3. Encapsulation
4. Abstraction
In this unit, we'll learn another fundamental principle of OOP called Abstraction.
1. Abstraction
Abstraction is the process of hiding certain details and showing only essential information to
the user.
Let's look at a real-life example of a man driving a car. As far as he knows, pressing the
accelerator increases the speed of the car or applying the brakes stops it. However, he doesn't
know how the speed actually increases when pressing the accelerator. He doesn't know
anything about the car's inner mechanisms or how the accelerator, brakes, etc., work.
1. Abstract classes
2. Interfaces
In the unit, we'll learn abstract classes and later in the course, we'll learn interfaces.
abstract
keyword is a non-access modifier, applied to classes and methods in Java. A class which is
declared with the
abstract
keyword is known as an abstract class.
Syntax
1
2
3
abstract class ClassName {
// attributes and methods
}
JAVA
Similar to regular classes, abstract classes can have constructors, attributes, static and final
methods, etc.
However,
Abstract classes cannot be instantiated i.e., we cannot create objects using the abstract
classes.
Abstract classes can have abstract methods.
Abstract classes cannot be declared as final.
Let's try to create an object of an abstract class.
Code
1
2
3
4
5
6
7
8
9
10
11
abstract class Vehicle { // abstract class
void start() {
System.out.println("Vehicle started");
}
void stop() {
System.out.println("Vehicle stopped");
}
}
class Base {
JAVA
Expand
Output
In the above code, the error has been thrown because we cannot create objects using the
abstract classes.
abstract
keyword is known as an abstract method.
The abstract methods don't contain any implementation i.e., abstract methods do not have a
body. The abstract methods can only be declared inside abstract classes.
Syntax
1
abstract returnType methodName();
JAVA
Code
1
2
3
4
abstract class Vehicle { // abstract class
abstract void start(); // abstract method
abstract void stop(); // abstract method
}
JAVA
The abstract classes can have abstract methods and non-abstract methods (i.e., methods
without
abstract
keyword).
Example 1:
Vehicle
from a
Car
class and implement the abstract methods inside the
Car
class.
Code
1
2
3
4
5
6
7
8
9
10
11
abstract class Vehicle { // abstract class
abstract void start(); // abstract method
abstract void stop(); // abstract method
}
class Car extends Vehicle {
void start() { // overriding abstract method
System.out.println("Car started");
};
void stop() { // overriding abstract method
JAVA
Expand
Output
Car started
Car stopped
In the above code, we have inherited the abstract class
Vehicle
. we provided the implementation for abstract methods
start()
and
stop()
inside the class
Car
and accessed them using the
car
object.
Example 2:
We can declare a reference variable of an abstract class and assign it an object of its subclass.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
abstract class Vehicle { // abstract class
abstract void start(); // abstract method
abstract void stop(); // abstract method
}
class Motorbike extends Vehicle {
void start() {
System.out.println("Motorbike started");
}
void stop() {
JAVA
Expand
Output
Motorbike started
Motorbike stopped
Truck started
Truck stopped
In the above code, the
Vehicle
is an abstract class and the
Motorbike
and
Truck
classes extend the
Vehicle
. We declared a superclass reference variable
vehicle
.
The
start()
and
stop()
methods of
Motorbike
and
Truck
are different in their implementations. Still, we can invoke those methods using the variable
vehicle
without knowing how they are implemented.
Here, the
start
and
stop
mechanisms may differ for different vehicles, but every vehicle consists of
start
and
stop
features regardless of the inner mechanisms.
The abstract classes focus on what should be done and not on how it should be done.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
abstract class Vehicle { // abstract class
abstract void start(); // abstract method
abstract void stop(); // abstract method
}
abstract class Car extends Vehicle { // abstract class
boolean areHeadlightsOn;
Car() {
areHeadlightsOn = false;
}
JAVA
Expand
Output
Ferrari started
Ferrari stopped
Are headlights turned on: true
Ferrari handbrake applied
In the above code,
Ferrari
is a concrete class.
The
Car
class in the above code has two non-abstract methods. Hence, only partial abstraction is
achieved here.
Key Points:
Abstract Class:
o An abstract class must be declared with an
abstract
keyword.
Abstract Method:
o An abstract method must be declared with an
abstract
keyword.
4. Possible Mistakes
Let's look at the most common mistakes while working with abstract classes.
Code
1
2
3
4
5
6
7
8
9
10
11
abstract class Vehicle { // abstract class
abstract void start(); // abstract method
abstract void stop(); // abstract method
}
class Car extends Vehicle {
void start() {
System.out.println("Car started");
};
}
JAVA
Expand
Output
file.java:6: error: Car is not abstract and does not override abstract method stop() in Vehicle
class Car extends Vehicle {
^
Car
is not an abstract class and doesn't implement the abstract method
stop()
. Hence, the error has been thrown.
2. Declaring a method as
abstract
which cannot be overridden
We cannot declare private methods, final methods, etc as abstract as they cannot be
overridden.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
abstract class Vehicle { // abstract class
abstract final void start(); // declaring a final method as abstract
private abstract void stop(); // declaring a private method as abstract
}
class Car extends Vehicle {
void start() {
System.out.println("Car started");
}
void stop() {
JAVA
Expand
Output
5. Abstraction vs Encapsulation
Following are the differences between abstraction and encapsulation:
Abstraction Encapsulation
The abstraction process hides unwanted In addition to hiding data, encapsulation protects
information. information.
We can implement abstraction using abstract classes Encapsulation can be implemented using by access
and interfaces. modifier i.e. private, protected and public.
In abstraction, implementation complexities are In encapsulation, the data is hidden using access
hidden using abstract classes and interfaces. modifiers.
Abstraction focus on what should be done. Encapsulation focus on How it should be done.
Summary
Abstraction is the process of hiding certain details and showing only essential
information to the user.
Abstract Class
o An abstract class must be declared with an
abstract
keyword.
abstract
keyword.
Interfaces
Concepts
Interface
Default Methods in Interfaces
Inheritance among Interfaces
Multiple Inheritance
Abstract Classes vs Interfaces
Introduction
In the previous unit, we learned abstraction and it can be achieved by,
1. Abstract classes
2. Interfaces
1. Interface
An Interface is similar to an abstract class. It cannot be instantiated and consists of abstract
methods.
Syntax
1
2
3
interface InterfaceName {
// body of the interface
}
JAVA
Similar to classes, the Pascal case notation is followed for naming the interfaces.
CricketPlayer
with an attribute
hasKit
and abstract methods as
run()
, and
field()
.
Code
1
2
3
4
5
interface CricketPlayer {
boolean hasKit = true;
void run();
void field();
}
JAVA
CricketPlayer
and declared two abstract methods.
Here, we can notice that we did not declare the abstract methods
run()
and
field()
using the
abstract
keyword.
The methods inside the interfaces are
public
and
abstract
by default. And the attributes inside the interfaces are
public
,
static
and
final
by default.
So, the above code is equivalent to,
1
2
3
4
5
interface CricketPlayer {
public static final boolean hasKit = true;
public abstract void run();
public abstract void field();
}
JAVA
Code
1
2
3
4
5
6
7
8
9
10
11
interface CricketPlayer {
void run();
void field();
}
class Person implements CricketPlayer {
public void run() { // overriding abstract method
System.out.println("Running");
};
public void field() { // overriding abstract method
JAVA
Expand
Output
Running
Fielding
In the above code, the
Person
class implements the
CricketPlayer
interface and has overridden the
run()
and
field()
methods. We declared the overriding methods as
public
because according to the rules of overriding, the overriding method should not be more
restrictive than the overridden method.
The
public
has the widest scope among all the access modifiers. As, the methods of interfaces are
public
and
abstract
by default, specifying any other access modifier other than
public
makes the overriding methods more restrictive. Hence,
public
methods should be used to override the methods of the interfaces.
The
default
keyword is used to declare a method in the interface as default method.
Syntax
1
2
3
accessModifier default returnType methodName() {
// block of code
}
JAVA
If there are many classes that implement this interface, we would have to track down all of
these classes and make changes to them, which can be both tedious and error-prone.
To avoid this issue, Java introduced default methods, which are inherited like regular
methods and provide an implementation for the new method within the interface.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
interface OnlineShoppingSite {
void processOrder(String item);
default void sendEmailsToCustomers() { // default method
System.out.println("Sending emails to customers who made a purchase in the last week.");
}
}
class Flipkart implements OnlineShoppingSite {
public void processOrder(String item) {
System.out.println("Processing order for " + item + " on Flipkart.");
JAVA
Expand
Output
Processing order for Book on Flipkart.
Sending personalized emails to Flipkart customers.
Processing order for Laptop on Walmart.
Sending emails to customers who made a purchase in the last week.
OnlineShoppingSite
with an abstract method
processOrder(String item)
and a default method
sendEmailsToCustomers()
. The
Flipkart
class implements the
OnlineShoppingSite
interface and provides an implementation for the
processOrder(String item)
method and overrides the
sendEmailsToCustomers()
method. The Walmart class also implements the
OnlineShoppingSite
interface and provides an implementation for the
processOrder(String item)
method.
In the
main()
method, we created objects of the
Flipkart
and
Walmart
classes and called their respective methods. The
processOrder(String item)
method processes the order and the
sendEmailsToCustomers()
method sends emails to customers who made a purchase in the last week.
In the case of the
Flipkart
object, the overridden method is called, whereas in the case of the
Walmart
object, the default method is called.
extends
keyword to inherit an interface from another interface.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
interface CricketPlayer {
void run();
void field();
}
interface Wicketkeeper extends CricketPlayer { // interface extending another interface
void wicketkeeping();
}
class Person implements Wicketkeeper {
public void field() {
JAVA
Expand
Output
Fielding
Wicketkeeping
Running
In the above code, we have extended the interface
CricketPlayer
from another interface
Wicketkeeper
and implemented all the methods in the
Person
class.
In Java,
4. Multiple Inheritance
In multiple inheritance, a single class/interface can inherit multiple interfaces.
the
ArrayList
class implements
List
,
Cloneable
, etc interfaces
o the
List
Collection
interface.
the
HashMaps
class implements
Map
,
Cloneable
, etc interfaces.
Multiple inheritance is not possible among classes i.e., a single class cannot extend multiple
classes.
Example 1: A class implementing multiple interfaces
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
interface InswingBowler {
void inswing();
}
interface OutswingBowler {
void outswing();
}
class BowlerA implements InswingBowler, OutswingBowler { // a class implementing multiple
interfaces
public void inswing() {
System.out.println("Inswing bowling");
JAVA
Expand
Output
Inswing bowling
Outswing bowling
In the above code, we have declared two interfaces
InswingBowler
and
OutswingBowler
and implemented them inside the
BowlerA
class.
The interfaces represent the IS-A relationship. Here, the
BowlerA
is a
InswingBowler
and the
BowlerA
is a
OutswingBowler
.
Example 2: An interface extending multiple interfaces
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
interface Camera {
void captureImage();
}
interface Calculator {
void calculate();
}
interface Smartphone extends Camera, Calculator { // interface extending multiple interfaces
void videoCall();
}
JAVA
Expand
Output
Image captured
Calculate mathematical expressions
Video calling
In the above code, the
Smartphone
interface extends two superinterfaces
Camera
and
Calculator
. We declared another class
IPhone
and have provided implementation for all the methods inside it.
Similar to using a superclass reference variable, we have used an interface reference variable
smartphone
to store the object of its subclass
IPhone
.
While using the superclass or superinterface reference variable make sure that it has all the
methods that are implemented in the subclass object that it will be storing in the runtime.
For example, in the above code, we cannot use the reference variable of a
Camera
because it doesn't have the
calculate()
and
videoCall()
methods. The
Smartphone
interface has all the methods the
IPhone
class implemented as it extended the
Camera
and
Calculator
interfaces.
4.1 Extending and Implementing from a Single SubClass
In Java, we can extend a superclass and implement multiple interfaces from a single subclass.
Syntax
1
2
3
class Subclass extends Superclass implements InterfaceOne, InterfaceTwo, ... {
// body of the subclass
}
JAVA
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
interface MachineGun {
void fireBullets();
}
interface MissileSystem {
void fireMissiles();
}
abstract class Boat {
abstract void move();
}
JAVA
Expand
Output
Moving
Firing bullets
Firing missiles
In the above code, we have extended the abstract class
Boat
and implemented the
MachineGun
and
MissileSystem
interfaces from a single class
Warship
. We have provided all the implementations for the methods declared in the interfaces and an
abstract class.
An abstract class can have final, non-final, static and Every attribute is public, static and final by
non-static attributes. default.
An abstract class doesn't support multiple inheritance. Interface supports multiple inheritance.
Abstract Class Interface
An abstract class can provide the implementation of Interface can't provide the implementation of
interface. abstract class.
An abstract class can extend another Java class and An interface can extend another Java
implement multiple Java interfaces. interface only.
An abstract class can be extended using the keyword An interface can be implemented using the
"extends". keyword "implements".
An abstract class can have class members like private, Members of a Java interface are public by
protected, etc. default.
Summary
Interfaces
o Interfaces are similar to abstract classes. It cannot be instantiated and consists
of abstract methods.
public
static
and
final
by default.
public
and
abstract
by default
o The
default
Multiple Inheritance
o a single class/interface can inherit multiple interfaces.
o a single class can extend another class and implement multiple interfaces.
Multiple inheritance is not possible among classes i.e., a single class cannot extend
multiple classes.