Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
2 views

Object Oriented Programming

Uploaded by

Akhila Akhila
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Object Oriented Programming

Uploaded by

Akhila Akhila
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 146

Object Oriented Programming - Part 1

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.

let's begin OOP with classes.

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 can be used to bundle related properties and actions.

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.

In Java, we can create a class by using the

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.

2. Attributes & Methods


Similar to Python, Java has instance attributes/methods and class attributes/methods.

In Java, instance or class attributes/methods are distinguished with the

static
keyword.
In this unit, we'll learn instance attributes/methods i.e., without the

static
keyword.

2.1 Instance Attributes


In Java, instance attributes are also called non-static attributes. We can declare instance
attributes in the same way as we have declared variables in the

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

Comparison with Python

In Python, we declare the instance attributes inside the

__init__
method.

Code

1
2
3
4
class Mobile:
def __init__(self):
self.model
self.camera
PYTHON

2.2 Instance Methods


In Java, instance methods are also called non-static methods. Previously, we have defined
methods in a class using the

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

Comparison with Python

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.

 "Instantiating a class" means creating an object of the class.


Key points:
 When a class does not have a constructor, the Java compiler automatically creates a
default constructor during the run-time.
 During the creation of the object of a class, constructors are called implicitly.
 We cannot use the keywords like
static
,
final
or
abstract
with the constructors.
 A constructor can be defined with parameters or without parameters. We can also
have multiple overloading constructors.
Example 1:

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

In the above code, the

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

In Python, we have to access the instance attributes/methods using the

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

Comparison with Python

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

5. Accessing Attributes & Methods with Objects


Similar to Python, we can use the dot (
.
) notation to access the attributes and methods with objects of a class.
Let's access the attributes and methods with the

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

mobile1.model: iPhone 13 Pro


mobile1.camera: 12 MP
Updated mobile2.model: Samsung Galaxy S22
Updated mobile2.camera: 108 MP
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 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.

o We cannot use the keywords like


static

final

or

abstract

with the constructors.

 An instance of a class is called an object.


 We can access the attributes and methods with objects of a class using the dot (
.
) notation.
 The class from which an object is created is considered to be the type of object.

Object Oriented Programming - Part 2


Concepts
 Class Attributes
 Class Methods
 Accessibility Among Instance and Class Attributes and Methods
 Instance vs Class Attributes
 Instance vs Class Methods
 Static Blocks

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.

Let's look at the syntax to declare a class attribute in Java.

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

Comparison with Python

Code
1
2
3
class Cart:
flat_discount = 0
min_bill = 100
PYTHON

1.1 Accessing Class Attributes


Similar to instance attributes, the class attributes can also be accessed using the dot (

.
) 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.

Example 1: Accessing class attributes using the class

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

Let's add a class method to our

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

Comparison with Python

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

2.1 Accessing Class Methods


The class methods can also be accessed using the dot (

.
) 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.

Example 1: Accessing class methods using the class

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

3. Accessibility Among Instance and Class


Attributes and Methods
Instance and class attributes and methods may not be combined in all combinations.

Let's check the accessibilities with examples.

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

Thank you for Shopping!


In the above code, we can see that inside the instance method

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()

4. Instance vs Class Attributes


Class Attribute Instance Attribute

A class attribute is declared using the

No keyword is required for an instance


static attribute.

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.

5. Instance vs Class Methods


Class Method Instance Method

A class method is declared using the

static No keyword is required for an instance method.

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

Let's initialize the class attributes of the

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.

The following are the four core principles of object-oriented programming:

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.

Let's add attributes and methods to superclass

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

In the above code, we have added a constructor, a non-static attribute

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

In the above code, we have added a non-static method

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

 created an object of the


Horse
class.
 invoked the superclass constructor using the
super
keyword.
 invoked the superclass and subclass methods.
Inside the non-static method

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 {
^

In the above code, we have declared the

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

file.java:1: error: cannot inherit from final Integer


class Base extends Integer {
^

In the above code, we tried to extend the wrapper class


Integer
. As the wrapper classes are final classes and cannot be inherited the error has been thrown.

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.

Let's understand it with an example.

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

Title: Head First Design Patterns, Author: Eric Freeman


Title: Clean Code, Author: Robert C. Martin

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.

When to use Inheritance & Composition?

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

When a method is overridden,

 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

4.1 Rules of Method Overriding


Let's learn some of the rules of method overriding.

1. Constructors cannot be overridden


In Java, constructors are not inherited to the subclass. If a method cannot be inherited, it
cannot be overridden. So, the constructors in Java cannot be overridden.

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

file.java:12: error: invalid method declaration; return type required


Mammal(){
^

In the above code, we have defined an

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

file.java:8: error: eat() in Horse cannot override eat() in Mammal


String eat() { // overriding method
^

In the above code,

 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.

The final methods cannot be overridden.

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

file.java:10: error: eat() in Horse cannot override eat() in Mammal


void eat() {
^
overridden method is final

In the above code, we have declared the


eat()
method in
Mammal
class as
final
. As the final methods cannot be overridden the error has been thrown.

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

method cannot be overridden

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.

1.2 Invoking Methods using


super

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

Horse eats grass


Eating
In the above code, we have invoked the overridden method

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

Horse eats grass


Eating

1.3 Invoking Constructors using


super()

The constructors which do not accept arguments are also called non-parameterized
constructors. The constructors which accept arguments are also called parameterized
constructors.

1.3.1 Invoking non-parameterized superclass constructor


The Java compiler implicitly calls the non-parameterized superclass constructor if we do not
call the superclass constructor explicitly.

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

Superclass constructor called


In the above code, we can see that the superclass constructor has been called even though we
did not invoke it explicitly.

We can invoke the superclass constructor explicitly as

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

2.1 Single Inheritance


Single inheritance involves extending a single superclass from a single subclass.

In Java, a subclass can have only one superclass.

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

2.2 Multilevel Inheritance


In multilevel inheritance, a subclass extends from a superclass and then the same subclass
acts as a superclass for another class.
Code

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

2.3 Hierarchical Inheritance


In hierarchical inheritance, multiple subclasses extend from a single superclass.

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

In the above code, we specified the type of

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
.

3.1 Invoking Methods


The method invocations depend on the type of the object during the execution of code. So,
we can invoke all the methods of the superclass, but when the subclass consists of the same
method, it overrides the superclass method and the method of the subclass is invoked.

Example 1: Invoking the overriding method of the subclass

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

file.java:21: error: cannot find symbol


animal.run();
^
In the above code, we tried to invoke the

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.

3.2 Accessing Attributes


Accessing of attributes depends on the type of the object before the execution of code.

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.

Example 1: Accessing superclass attributes

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

file.java:13: error: cannot find symbol


System.out.println(animal.breed);
^
In the above code, as we cannot access the subclass attributes an error has been thrown.

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.

o call the overridden methods of the superclass inside the subclass.


o invoke the parameterized superclass constructors explicitly from the subclass
constructor.

 Types of inheritance,

o Single Inheritance: It involves extending a single superclass from a single


subclass.

o Multilevel Inheritance: In multilevel inheritance, a subclass extends from


a superclass and then the same subclass acts as a superclass for another class.

o Hierarchical Inheritance: In hierarchical inheritance, multiple subclasses


extend from a single superclass.

 Upcasting

o We can specify a superclass as a type to refer to an object of its subclass.

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. Access Modifiers with Attributes


Let's learn the behaviour of each of the access modifiers with attributes

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

The keywords like

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.

2.2 Default (no keyword required)


If we do not specify any access modifier, it is considered as default.

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

When an attribute is declared as

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

When attributes are declared as

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.

2.5 Accessibility of Access Modifiers


Different
Access Same Same package Same package Different package
package
Modifier Class subclass other classes other classes
subclass

private Yes No No No No
Different
Access Same Same package Same package Different package
package
Modifier Class subclass other classes other classes
subclass

default Yes Yes Yes No No

protected Yes Yes Yes Yes No

public Yes Yes Yes Yes Yes

 The private access modifier is most restrictive compared to other modifiers


 The default and protected access modifiers are almost similar with protected having
little more scope that it can be accessed in other packages with its subclass.
 The public access modifier is having the widest scope among all the access modifiers.

3. Access Modifiers with Methods and


Constructors
All the access modifiers we learned till now are applicable and work the same with the
methods and constructors.

Let's understand them with examples,

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.

Syntax for Methods

1
2
3
private returnType methodName() {
// method body
}
JAVA

Syntax for Constructors

1
2
3
private ClassName() {
// constructor body
}
JAVA

The private methods and constructors are accessible only within the declared class.

Example 1: Accessing private methods 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

file.java:15: error: Mobile(String) has private access in Mobile


Mobile mobile = new Mobile("iPhone 13 Pro");
^
/usercode/file.java:16: error: makeCall(long) has private access in Mobile
mobile.makeCall(9876543210L);
^

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.

3.2 Default (no keyword required)


When no access modifier is specified to the methods and constructors, then they can be called
default methods and default constructors respectively.

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.

Syntax for Methods

1
2
3
protected returnType methodName() {
// method body
}
JAVA

Syntax for Constructors

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.

Syntax for Methods

1
2
3
public returnType methodName() {
// method body
}
JAVA

Syntax for Constructors

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

When a class is declared

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.

4.2 Default (no keyword required)


When no access modifier is specified to the classes, then they can be called default classes.

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.

As we have learned, we can see that the

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.

We will learn about Interfaces later in the course.

5. More Method Overriding Rules


In the previous unit, we learned few rules of the method overriding.

1. Constructors cannot be overridden


2. The overriding method should have the same return type and parameters
3. A final method cannot be overridden

Now, let's learn few more rules of the method overriding,

4. The private methods cannot be overridden.


5. The access level cannot be more restrictive than the overridden method's access level.

Let's understand each of the above rules with examples

4. The private methods cannot be overridden


We have learned that private methods are accessible only within the declared class. It means
that private methods cannot be inherited to the subclasses, so they cannot be overridden too.

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

file.java:24: error: makeCall(long) has private access in Telephone


smartphone.makeCall(9876543210L);
^

In the above code, we have declared the

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.

private -> default -> protected -> public


Example 1:

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

file.java:18: error: makeCall(long) in Smartphone cannot override makeCall(long) in


Telephone
private void makeCall(long phnNum) {
^
attempting to assign weaker access privileges; was protected

In the above code,

 we have defined the


makeCall()
method in the superclass
Telephone
as
protected
 we have defined the
makeCall()
method in the subclass
Smartphone
as
private
The
private
modifier is more restrictive than the
protected
. So, the
makeCall()
method of the
Telephone
class cannot be overridden with the
makeCall()
method of the
Smartphone
class and the error has been thrown.
Example 2:

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,

 we have defined the


makeCall()
method in the superclass
Telephone
as
private
 we have defined the
makeCall()
method in the subclass
Smartphone
as
protected
The

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

default Yes Yes Yes No No

protected Yes Yes Yes Yes No

public Yes Yes Yes Yes Yes

 The private access modifier is most restrictive compared to other modifiers


 The default and protected access modifiers are almost similar with protected having
little more scope that it can be accessed in other packages with its subclass.

 The public access modifier is having the widest scope among all the access modifiers.

 Classes in Java can only have Public or Default as access modifiers.

 Rules of Method Overriding

i. Constructors cannot be overridden


ii. The overriding method should have the same return type and parameters
iii. A final method cannot be overridden
iv. The private methods cannot be overridden
v. The access level cannot be more restrictive than the overridden method's
access level

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

and also learned one of fundamental principles called Inheritance.

In this unit, we'll look into the execution of Java code and learn another important principle
of OOP called Polymorphism.

1. Execution of a Java Code


The execution of Java code will be done in two stages.

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.

Polymorphism in Java refers to an object’s capacity to take several forms. Polymorphism


allows us to perform the same action in multiple ways in Java.

Polymorphism is of two types:

1. Compile-time polymorphism
2. Runtime polymorphism

2.1 Compile-time Polymorphism


A polymorphism that occurs during the compilation stage is known as a Compile-time
polymorphism. Method overloading is an example of compile-time 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 of Circle = 314.0


Area of Triangle = 43.4775
Area of Rectangle = 15
In the above code, we have defined multiple overloading methods with the name

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.

2.2 Runtime Polymorphism


A polymorphism that occurs during the execution stage is called Runtime polymorphism.
Method overriding is an example of Runtime polymorphism.

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.

 Polymorphism is of two types:

o Compile-time polymorphism: A polymorphism that occurs during the


compilation stage is called Compile-time polymorphism. Method overloading
is an example of compile-time polymorphism.

o Runtime polymorphism: A polymorphism that occurs during the


execution stage is called Runtime polymorphism. Method overriding is an
example of Runtime polymorphism.
Encapsulation
Concepts
 Encapsulation
 Getters and Setters

Introduction
In the previous units, we have seen the four core principles of object-oriented programming:

1. Inheritance
2. Polymorphism
3. Encapsulation
4. Abstraction

and also learned two fundamental principles Inheritance and Polymorphism.

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.

Let's understand it better with an example

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.

1.1 Getters and Setters


Getters and setters are the methods which are mostly used to access and update the non-static
attributes respectively.

For each non-static attribute,


Getters: The Getters are used to access/get the value of the non-static attribute of a class.
These are also called accessors.

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

Till now we learned three fundamental principles Inheritance, Encapsulation, and


Polymorphism.

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.

Abstraction can be achieved with,

1. Abstract classes
2. Interfaces

In the unit, we'll learn abstract classes and later in the course, we'll learn interfaces.

2. Abstract Classes and Methods


2.1 Abstract Classes
The

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

file.java:13: error: Vehicle is abstract; cannot be instantiated


Vehicle vehicle = new Vehicle();
^

In the above code, the error has been thrown because we cannot create objects using the
abstract classes.

2.2 Abstract Methods


A method which is declared with the

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

Here, the body of the method is replaced by

Code
1
2
3
4
abstract class Vehicle { // abstract class
abstract void start(); // abstract method
abstract void stop(); // abstract method
}
JAVA

The implementation of the abstract methods should be provided by its subclasses.

3. Implementing Abstract Classes and Methods


3.1 Inheriting Abstract Classes
As we cannot create objects using an abstract class, to access the members of an abstract
class we have to inherit the class from another class.

The abstract classes can have abstract methods and non-abstract methods (i.e., methods
without

abstract
keyword).
Example 1:

let's inherit the

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.

3.2 Multilevel Inheritance with Abstraction


If the subclass of an abstract class is also an abstract class, then the subclass may or may not
implement the abstract methods of its superclass.

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,

 we inherited an abstract class


Vehicle
from another abstract class
Car
. As the
Car
is also an abstract class, we may or may not implement the
start()
and
stop()
methods.
 we declared an abstract method
applyHandbrake()
in the
Car
class.
 we inherited the
Car
class from the
Ferrari
class. Here, due to the multilevel inheritance, the methods
start()
,
stop()
,
applyHandbrake()
are inherited to the
Ferrari
class. As
Ferrari
is a regular class, we have implemented all the abstract methods
start()
,
stop()
, and
applyHandbrake()
.
The class which consists of implementation for all its methods is called a concrete class. 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.

o It can have constructors, attributes, static and final methods, etc.

o It can have abstract and non-abstract methods.

o It cannot be instantiated i.e., we cannot create objects using the abstract


classes.

o An abstract class cannot be declared as final.

 Abstract Method:
o An abstract method must be declared with an

abstract

keyword.

o The abstract methods can only be declared inside abstract classes.

o An abstract method must be overridden by its subclass method unless the


subclass is an abstract class.

o Abstract methods cannot be private, final, etc which cannot be overridden

4. Possible Mistakes
Let's look at the most common mistakes while working with abstract classes.

1. Not implementing the abstract methods in its subclass

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 {
^

In the above code, the

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

file.java:2: error: illegal combination of modifiers: abstract and final


abstract final void start();
^
file.java:3: error: illegal combination of modifiers: abstract and private
private abstract void stop();
^
...

In the above code, the


start()
method is declared as
final
and the
stop()
method is declared as
private
. As the final and private methods cannot be overridden, the error has been thrown.

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.

o It can have constructors, attributes, static and final methods, etc.

o It can have abstract and non-abstract methods.

o It cannot be instantiated i.e., we cannot create objects using the abstract


classes.

o An abstract class cannot be declared as final.


 Abstract Method
o An abstract method must be declared with an

abstract

keyword.

o The abstract methods can only be declared inside abstract classes.

o An abstract method must be overridden by its subclass method unless the


subclass is an abstract class.

o Abstract methods cannot be private, final, etc which cannot be overridden.

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

We learned to use abstract classes to achieve abstraction.

In this unit, we'll learn Interfaces.

1. Interface
An Interface is similar to an abstract class. It cannot be instantiated and consists of abstract
methods.

The interfaces act as a blueprint for a class. The


interface
keyword is used to create an interface.

Syntax

1
2
3
interface InterfaceName {
// body of the interface
}
JAVA

Similar to classes, the Pascal case notation is followed for naming the interfaces.

Unlike abstract classes, interfaces cannot have constructors.

Let's create an interface

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

In the above code, we have created an interface

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

1.1 Inheriting Interfaces


The
implements
keyword is used to inherit interfaces from a class.

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.

2. Default Methods in Interfaces


In Java 8, there is a new feature according which we can write the implementation of a
method inside the interface. These methods are called default methods.

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

Why default methods are introduced?


Imagine a scenario where we need to add a new method to an interface in Java. We can easily
add the method to the interface without providing an implementation, but all the classes that
implement this interface must provide their own implementation for the new method.

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.

Let's understand it better with an example,

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.

In the above code, we have defined an interface

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.

3. Inheritance among Interfaces


An interface can inherit another interface. We use the

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,

 a class can extend another class


 a class can implement an interface
 an interface can extend another interface

4. Multiple Inheritance
In multiple inheritance, a single class/interface can inherit multiple interfaces.

We can specify multiple interfaces separated by a comma while extending/implementing the


interfaces.
Similar to superclass and subclass, we have superinterface and subinterface in interfaces.

Previously, we came across interfaces at ArrayLists, HashMaps, etc

 the
ArrayList
class implements
List
,
Cloneable
, etc interfaces
o the

List

interface extends the

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.

5. Abstract Classes vs Interfaces


Differences between abstract classes and interfaces are,

Abstract Class Interface

The interface keyword is used to declare an


The abstract keyword is used to declare an abstract class.
interface.

An abstract class can have abstract and non-abstract


Every method is abstract by default.
methods.

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 can have constructors. Interface cannot have constructors.

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.

When to use Abstract classes and Interfaces?

Use Abstract classes:


 When we want to share among several closely related classes. For example: Vehicle,
Car, etc.
 When the subclass that extending our abstract class has many common methods or
attributes or requires access modifiers other than
public
 When we want to declare non-static and non-final attributes.
Use Interfaces:
 When we expect that an unrelated class may implement our code. For example, a
smartphone implementing a calculator interface.
 When we want to use the multiple inheritance.

Summary
 Interfaces
o Interfaces are similar to abstract classes. It cannot be instantiated and consists
of abstract methods.

o Attributes inside the interfaces are

public

static

and
final

by default.

o Methods inside the interfaces are

public

and

abstract

by default

 Default Methods in Interfaces


o Through default methods, we can provide the implementation of a method
inside the interface.

o The

default

keyword is used to declare a method in the interface as default method.

 Inheritance with Interfaces

o an interface extends another interface.

o a class implements an interface.

o a class extends another class.

 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.

You might also like