Unit 2 – Java OOP
Concepts
Inheritance, Polymorphism, Interfaces & Packages
A Complete Beginner-Friendly Guide with Code Examples
Department of AI & Data Sciences
Chandigarh Engineering College Jhanjeri
1. What is Inheritance?
Inheritance is one of the four pillars of Object-Oriented Programming (OOP). It
allows one class (the child or subclass) to acquire the properties and methods of
another class (the parent or superclass). This means you can reuse existing
code without rewriting it.
Note: Real-world analogy: A child inherits features from their parents — eye colour,
height, etc. Similarly, a subclass inherits fields and methods from its parent class.
The child can also have additional features of its own.
Why Use Inheritance?
• Code Reusability — write once, use in many subclasses
• Method Overriding — subclasses can change parent behaviour
• Hierarchical classification — organise code logically
• Extensibility — add new features without changing existing code
Basic Inheritance Syntax
// Parent class (Superclass)
class Animal {
String name;
void eat() {
[Link](name + " is eating.");
}
}
// Child class (Subclass) — 'extends' keyword creates inheritance
class Dog extends Animal {
void bark() {
[Link](name + " says: Woof!");
}
}
public class InheritanceBasic {
public static void main(String[] args) {
Dog d = new Dog();
[Link] = "Tommy";
[Link](); // inherited from Animal
[Link](); // Dog's own method
}
}
Output:
Tommy is eating.
Tommy says: Woof!
2. Types of Inheritance in Java
Java supports several types of inheritance. However, Java does NOT support
multiple inheritance through classes (to avoid the 'Diamond Problem'), but it does
support it through interfaces.
Type Description Java Support?
Single One child extends one YES
parent
Multilevel Chain: A → B → C (B YES
extends A, C extends B)
Hierarchical Multiple children extend one YES
parent
Multiple One child extends two NO (via classes) — YES via
parents interfaces
Hybrid Combination of multiple YES via interfaces only
types
2.1 Single Inheritance
One class inherits from exactly one parent class.
class Vehicle {
void start() { [Link]("Vehicle started."); }
}
class Car extends Vehicle { // Single inheritance
void horn() { [Link]("Car beeps!"); }
}
public class SingleInherit {
public static void main(String[] args) {
Car c = new Car();
[Link](); // from Vehicle
[Link](); // Car's own
}
}
Output:
Vehicle started.
Car beeps!
2.2 Multilevel Inheritance
Class B inherits from A, and Class C inherits from B — forming a chain.
class Animal {
void breathe() { [Link]("Breathing..."); }
}
class Mammal extends Animal { // Level 2
void walk() { [Link]("Walking on 4 legs."); }
}
class Dog extends Mammal { // Level 3
void bark() { [Link]("Barking!"); }
}
public class MultilevelInherit {
public static void main(String[] args) {
Dog d = new Dog();
[Link](); // from Animal (grandparent)
[Link](); // from Mammal (parent)
[Link](); // Dog's own
}
}
Output:
Breathing...
Walking on 4 legs.
Barking!
2.3 Hierarchical Inheritance
Multiple subclasses all extend the same parent class.
class Shape {
void draw() { [Link]("Drawing a shape."); }
}
class Circle extends Shape {
void area() { [Link]("Area = pi * r * r"); }
}
class Rectangle extends Shape {
void area() { [Link]("Area = length * breadth"); }
}
public class HierarchicalInherit {
public static void main(String[] args) {
Circle c = new Circle();
[Link](); // from Shape
[Link]();
Rectangle r = new Rectangle();
[Link](); // from Shape
[Link]();
}
}
Output:
Drawing a shape.
Area = pi * r * r
Drawing a shape.
Area = length * breadth
3. The super Keyword
The super keyword is used inside a subclass to refer to its parent (superclass). It
has three main uses:
Use of super What it does
[Link] Access a parent class field that is hidden by
a child field
[Link]() Call a parent class method that has been
overridden in the child
super() Call the parent class constructor from the
child's constructor
3.1 super to access parent field and method
class Parent {
int x = 10;
void show() { [Link]("Parent show(): x = " + x); }
}
class Child extends Parent {
int x = 20; // hides parent's x
void display() {
[Link]("Child x = " + x); // child's x
[Link]("Parent x = " + super.x); // parent's
x
[Link](); // parent's
method
}
}
public class SuperDemo {
public static void main(String[] args) {
new Child().display();
}
}
Output:
Child x = 20
Parent x = 10
Parent show(): x = 10
3.2 super() to call parent constructor
class Person {
String name;
Person(String name) {
[Link] = name;
[Link]("Person constructor: " + name);
}
}
class Student extends Person {
int rollNo;
Student(String name, int rollNo) {
super(name); // calls Person(name) constructor
[Link] = rollNo;
[Link]("Student constructor: Roll " + rollNo);
}
}
public class SuperConstructor {
public static void main(String[] args) {
Student s = new Student("Alice", 101);
[Link]("Name: " + [Link] + ", Roll: " +
[Link]);
}
}
Output:
Person constructor: Alice
Student constructor: Roll 101
Name: Alice, Roll: 101
4. Preventing Inheritance: final Classes and Methods
Sometimes you want to stop other classes from inheriting your class, or stop
subclasses from overriding your methods. Java provides the final keyword for
this.
Usage Effect
final class ClassName No other class can extend (inherit from) this
class
final void methodName() No subclass can override this method
final int x = 10; Variable value cannot be changed
(constant)
Note: Java's built-in String class is declared final — that is why you cannot create a
subclass of String. The designers wanted to protect its immutability.
4.1 final Method — Cannot be Overridden
class BankAccount {
private double balance = 1000.0;
// final method — subclasses cannot change this security logic
final void deduct(double amount) {
if (amount > balance) {
[Link]("Insufficient balance!");
} else {
balance -= amount;
[Link]("Deducted " + amount + ". Balance: "
+ balance);
}
}
}
class SavingsAccount extends BankAccount {
// If you tried to override deduct() here, the compiler gives
an ERROR
void greet() { [Link]("Welcome to Savings
Account!"); }
}
public class FinalMethodDemo {
public static void main(String[] args) {
SavingsAccount sa = new SavingsAccount();
[Link]();
[Link](300);
[Link](800);
}
}
Output:
Welcome to Savings Account!
Deducted 300.0. Balance: 700.0
Insufficient balance!
4.2 final Class — Cannot be Extended
// final class — cannot be subclassed
final class MathUtils {
static double square(double n) { return n * n; }
static double cube(double n) { return n * n * n; }
}
// class SubMath extends MathUtils {} // ERROR: cannot extend
final class
public class FinalClassDemo {
public static void main(String[] args) {
[Link]("Square of 4 = " + [Link](4));
[Link]("Cube of 3 = " + [Link](3));
}
}
Output:
Square of 4 = 16.0
Cube of 3 = 27.0
5. What is Polymorphism?
Polymorphism means 'many forms'. In Java, one method name can behave
differently depending on the situation. It is achieved in two ways:
Type When it happens Also called
Method Overloading Compile-time — same Compile-time / Static
method name, different Polymorphism
parameters
Method Overriding Runtime — subclass Runtime / Dynamic
redefines a parent method Polymorphism
6. Method Overloading
Method overloading means having multiple methods in the SAME class with the
SAME name but DIFFERENT parameters (different number, type, or order of
parameters).
Note: The compiler decides which method to call at compile time based on the
arguments you pass. This is why it is called Compile-time Polymorphism.
How to Overload — 3 Ways
Method How it differs
add(int a, int b) 2 int parameters
add(int a, int b, int c) 3 int parameters
add(double a, double b) 2 double parameters
public class Calculator {
// Version 1: add two ints
int add(int a, int b) {
return a + b;
}
// Version 2: add three ints (different number of params)
int add(int a, int b, int c) {
return a + b + c;
}
// Version 3: add two doubles (different type)
double add(double a, double b) {
return a + b;
}
// Version 4: concatenate two Strings
String add(String a, String b) {
return a + b;
}
public static void main(String[] args) {
Calculator calc = new Calculator();
[Link]([Link](5, 3)); // calls
version 1
[Link]([Link](5, 3, 2)); // calls
version 2
[Link]([Link](5.5, 3.5)); // calls
version 3
[Link]([Link]("Hello ", "World")); // calls
version 4
}
}
Output:
8
10
9.0
Hello World
7. Method Overriding
Method overriding means a subclass provides its own implementation of a
method that already exists in the parent class. The method signature (name +
parameters) must be EXACTLY the same.
Note: The JVM decides which version to run at RUNTIME based on the actual
object type — that is why it is called Runtime Polymorphism.
Rules for Method Overriding
1. Same method name as in the parent
2. Same parameters (type and number)
3. Same or wider return type
4. Access modifier cannot be more restrictive than parent
5. Use @Override annotation (recommended — compiler checks it for you)
class Animal {
void sound() {
[Link]("Animal makes a sound.");
}
}
class Dog extends Animal {
@Override
void sound() { // overrides Animal's sound()
[Link]("Dog says: Woof!");
}
}
class Cat extends Animal {
@Override
void sound() { // overrides Animal's sound()
[Link]("Cat says: Meow!");
}
}
public class OverrideDemo {
public static void main(String[] args) {
Animal a; // Parent reference
a = new Animal();
[Link](); // calls Animal's version
a = new Dog(); // parent reference pointing to Dog object
[Link](); // calls Dog's version (Runtime
Polymorphism!)
a = new Cat();
[Link](); // calls Cat's version
}
}
Output:
Animal makes a sound.
Dog says: Woof!
Cat says: Meow!
Overloading vs Overriding — Key Differences
Feature Method Overloading Method Overriding
Class Same class Parent and subclass
Parameters Must be different Must be identical
Return type Can be different Must be same or covariant
When resolved Compile-time Runtime
Polymorphism type Static / Compile-time Dynamic / Runtime
@Override needed? No Recommended
8. Abstract Classes and Methods
An abstract class is a class that cannot be instantiated (you cannot create an
object of it directly). It acts as a blueprint or template for subclasses. It can have
both abstract methods (no body) and concrete methods (with body).
Note: Real-world analogy: 'Shape' is an abstract concept. You can't draw a generic
'Shape' — but you CAN draw a Circle or Rectangle. Shape is the abstract class;
Circle and Rectangle are concrete subclasses.
Abstract Class Rules
• Declared with the abstract keyword
• Cannot be instantiated: new Shape() is illegal
• Can have abstract methods (no body — subclass MUST implement them)
• Can also have regular (non-abstract) methods with full implementations
• A subclass must override ALL abstract methods OR be declared abstract
itself
// Abstract class — cannot create an object of this directly
abstract class Shape {
String color;
// Abstract method — no body; subclass MUST implement
abstract double area();
abstract double perimeter();
// Concrete method — has a body; subclasses inherit this
void showColor() {
[Link]("Color: " + color);
}
}
// Concrete subclass — must implement all abstract methods
class Circle extends Shape {
double radius;
Circle(double r, String c) {
[Link] = r;
[Link] = c;
}
@Override
double area() { return [Link] * radius * radius; }
@Override
double perimeter() { return 2 * [Link] * radius; }
}
class Rectangle extends Shape {
double length, breadth;
Rectangle(double l, double b, String c) {
[Link] = l; [Link] = b; [Link] = c;
}
@Override
double area() { return length * breadth; }
@Override
double perimeter() { return 2 * (length + breadth); }
}
public class AbstractDemo {
public static void main(String[] args) {
// Shape s = new Shape(); // ERROR — cannot instantiate
abstract class
Circle c = new Circle(5.0, "Red");
[Link]();
[Link]("Circle Area: %.2f%n", [Link]());
[Link]("Circle Perimeter: %.2f%n",
[Link]());
[Link]();
Rectangle r = new Rectangle(4, 6, "Blue");
[Link]();
[Link]("Rectangle Area: %.2f%n", [Link]());
[Link]("Rectangle Perimeter: %.2f%n",
[Link]());
}
}
Output:
Color: Red
Circle Area: 78.54
Circle Perimeter: 31.42
Color: Blue
Rectangle Area: 24.00
Rectangle Perimeter: 20.00
9. Interfaces
An interface in Java is a completely abstract contract. It defines what a class
CAN DO without saying how to do it. A class that agrees to fulfil the contract
must implement all the methods in the interface.
Note: Real-world analogy: A USB port is an interface. Any device (pendrive,
mouse, phone) can plug in as long as it follows the USB standard. The interface
defines the rules; the devices implement them differently.
Key Facts about Interfaces
• All methods in an interface are public and abstract by default
• All variables are public, static, and final by default (constants)
• A class implements an interface using the implements keyword
• A class can implement MULTIPLE interfaces (Java's answer to multiple
inheritance)
• An interface can extend another interface
• Since Java 8, interfaces can have default and static methods with bodies
9.1 Defining an Interface
// Defining an interface
interface Printable {
int MAX_SIZE = 100; // implicitly: public static final int
MAX_SIZE = 100
void print(); // implicitly: public abstract void
print()
void preview();
}
9.2 Implementing an Interface
interface Drawable {
void draw(); // abstract — must be implemented
void resize();
}
// Class implements the interface — must provide all method bodies
class Circle implements Drawable {
@Override
public void draw() {
[Link]("Drawing a Circle");
}
@Override
public void resize() {
[Link]("Resizing Circle");
}
}
class Square implements Drawable {
@Override
public void draw() {
[Link]("Drawing a Square");
}
@Override
public void resize() {
[Link]("Resizing Square");
}
}
public class InterfaceImplDemo {
public static void main(String[] args) {
Circle c = new Circle();
[Link]();
[Link]();
Square s = new Square();
[Link]();
[Link]();
}
}
Output:
Drawing a Circle
Resizing Circle
Drawing a Square
Resizing Square
10. Accessing Implementations Through Interface
References
Just like you can use a parent class reference to point to a child object, you can
use an INTERFACE reference to point to any object of a class that implements
that interface. This is very powerful — it lets you write code that works with ANY
class that implements the interface.
interface Animal {
void sound();
void move();
}
class Dog implements Animal {
public void sound() { [Link]("Woof!"); }
public void move() { [Link]("Dog runs on 4
legs."); }
}
class Bird implements Animal {
public void sound() { [Link]("Tweet!"); }
public void move() { [Link]("Bird flies with
wings."); }
}
public class InterfaceRefDemo {
public static void main(String[] args) {
// Interface reference pointing to different
implementations
Animal a;
a = new Dog(); // interface ref → Dog object
[Link]();
[Link]();
[Link]();
a = new Bird(); // same ref now → Bird object
[Link]();
[Link]();
}
}
Output:
Woof!
Dog runs on 4 legs.
Tweet!
Bird flies with wings.
11. Implementing Multiple Interfaces
A Java class can only extend ONE class, but it can implement MULTIPLE
interfaces. This is how Java achieves multiple inheritance safely.
interface Flyable {
void fly();
}
interface Swimmable {
void swim();
}
interface Runnable {
void run();
}
// Duck implements THREE interfaces — multiple inheritance!
class Duck implements Flyable, Swimmable, Runnable {
public void fly() { [Link]("Duck is flying!"); }
public void swim() { [Link]("Duck is swimming!"); }
public void run() { [Link]("Duck is running!"); }
}
public class MultiInterfaceDemo {
public static void main(String[] args) {
Duck duck = new Duck();
[Link]();
[Link]();
[Link]();
}
}
Output:
Duck is flying!
Duck is swimming!
Duck is running!
12. Extending Interfaces
An interface can extend another interface (just like classes extend classes). The
child interface inherits all abstract methods from the parent interface. A class
implementing the child interface must implement ALL methods from both.
// Parent interface
interface Vehicle {
void start();
void stop();
}
// Child interface extends parent — adds more methods
interface ElectricVehicle extends Vehicle {
void charge();
void showBattery();
}
// Class must implement ALL methods from BOTH interfaces
class Tesla implements ElectricVehicle {
public void start() { [Link]("Tesla silently
starts."); }
public void stop() { [Link]("Tesla stops.");
}
public void charge() { [Link]("Tesla charging
at supercharger."); }
public void showBattery() { [Link]("Battery: 85%");
}
}
public class ExtendInterfaceDemo {
public static void main(String[] args) {
Tesla t = new Tesla();
[Link]();
[Link]();
[Link]();
[Link]();
}
}
Output:
Tesla silently starts.
Tesla charging at supercharger.
Battery: 85%
Tesla stops.
Interface vs Abstract Class — Key Differences
Feature Interface Abstract Class
Keyword interface abstract class
Method bodies Only default/static methods Can have both abstract and
(Java 8+); rest abstract concrete methods
Variables public static final only Can have any type of
(constants) variables
Constructor Not allowed Allowed (not directly
instantiated though)
Multiple inheritance YES — class can implement NO — class can extend only
many interfaces one
Access modifiers Methods are public by Methods can be any access
default modifier
When to use Define a contract/capability Provide a partial
(can fly, can swim) implementation as a base
13. Inner Classes
An inner class is a class defined inside another class. Java supports 4 types of
inner classes:
Type Where defined Special feature
Member Inner Class Inside outer class, outside Can access all outer class
any method members
Static Nested Class Inside outer class with static Can only access static
keyword members of outer class
Local Inner Class Inside a method Defined and used within that
method only
Anonymous Inner Class Inline, without a name Used to implement
interface/extend class in one
shot
13.1 Member Inner Class
class Outer {
private String message = "Hello from Outer!";
class Inner { // member inner class
void display() {
[Link](message); // accesses outer's
private field
}
}
}
public class InnerClassDemo {
public static void main(String[] args) {
Outer outer = new Outer();
[Link] inner = [Link] Inner(); // special syntax
[Link]();
}
}
Output:
Hello from Outer!
13.2 Static Nested Class
class Computer {
static String brand = "TechBrand";
static class Processor { // static nested class
void info() {
[Link]("Processor inside " + brand);
}
}
}
public class StaticNestedDemo {
public static void main(String[] args) {
// No need to create Outer object for static nested class
[Link] p = new [Link]();
[Link]();
}
}
Output:
Processor inside TechBrand
13.3 Anonymous Inner Class
An anonymous inner class lets you implement an interface or extend a class in
one go, without writing a separate named class. Very useful for event handling
and quick callbacks.
interface Greeting {
void greet(String name);
}
public class AnonymousDemo {
public static void main(String[] args) {
// Anonymous inner class implements Greeting without a
separate class
Greeting formal = new Greeting() {
@Override
public void greet(String name) {
[Link]("Good morning, " + name + "!");
}
};
Greeting casual = new Greeting() {
@Override
public void greet(String name) {
[Link]("Hey " + name + "! What's up?");
}
};
[Link]("Dr. Smith");
[Link]("Alice");
}
}
Output:
Good morning, Dr. Smith!
Hey Alice! What's up?
14. Packages
A package in Java is like a folder that groups related classes and interfaces
together. This helps organise code, avoid name conflicts, and control access.
Note: Real-world analogy: Think of packages like departments in a company (HR,
Finance, Engineering). Each department has its own files and people. A class in
one package can access another through the proper channel (import).
Types of Packages
Type Description Examples
Built-in Packages Java's own standard library [Link], [Link], [Link],
packages [Link], [Link]
User-defined Packages Packages you create for [Link],
your own project [Link]
14.1 Defining (Creating) a Package
Use the package keyword as the FIRST statement in a Java file:
// File: com/college/[Link]
package [Link]; // declare the package
public class Student {
private String name;
private int rollNo;
public Student(String name, int rollNo) {
[Link] = name;
[Link] = rollNo;
}
public void display() {
[Link]("Roll: " + rollNo + ", Name: " + name);
}
}
14.2 Accessing a Package — Using import
To use a class from another package, you use the import statement. There are
two forms:
// Import a specific class
import [Link];
// Import ALL classes in a package (wildcard)
import [Link].*;
// Example — using an imported class
import [Link];
public class CollegeApp {
public static void main(String[] args) {
Student s1 = new Student("Alice", 101);
Student s2 = new Student("Bob", 102);
[Link]();
[Link]();
}
}
Output:
Roll: 101, Name: Alice
Roll: 102, Name: Bob
14.3 Built-in Package Examples
import [Link]; // specific class from [Link]
import [Link];
import [Link].*; // ALL classes from [Link]
import [Link].*; // ALL classes from [Link]
public class BuiltInPackageDemo {
public static void main(String[] args) {
// Using [Link]
ArrayList<String> fruits = new ArrayList<>();
[Link]("Mango");
[Link]("Apple");
[Link]("Banana");
[Link]("Fruits: " + fruits);
// Using [Link] (auto-imported — no import needed!)
[Link]("Max of 10, 25: " + [Link](10, 25));
[Link]("Sqrt of 144: " + [Link](144));
}
}
Output:
Fruits: [Mango, Apple, Banana]
Max of 10, 25: 25
Sqrt of 144: 12.0
14.4 Package Directory Structure
For package [Link], the file structure is:
project/
└── src/
└── com/
└── college/
└── student/
├── [Link]
├── [Link]
└── [Link]
Compilation command (from project root):
javac src/com/college/student/[Link]
Running (from project root):
java [Link]
14.5 Access Modifiers with Packages
Modifier Same Class Same Subclass (diff Anywhere
Package pkg)
public YES YES YES YES
protected YES YES YES NO
default (none) YES YES NO NO
private YES NO NO NO
Quick Reference Summary – Unit 2
Topic Key Keyword / Concept One-Line Summary
Inheritance extends Child class reuses parent
class code
Single Inheritance class B extends A One child, one parent
Multilevel Inheritance A → B → C chain Grandparent, parent, child
chain
Hierarchical Inheritance Multiple subclasses, one Many children share one
parent parent
super (field/method) super.x, [Link]() Access parent's hidden field
or overridden method
super (constructor) super(args) Call parent constructor from
child constructor
final method final void method() Subclass CANNOT override
this method
final class final class Name Class CANNOT be
subclassed at all
Polymorphism Many forms One interface, multiple
implementations
Method Overloading Same name, diff params, Compile-time polymorphism
same class
Method Overriding @Override, same Runtime polymorphism
name+params, subclass
Abstract class abstract class / abstract void Blueprint — cannot
m() instantiate directly
Interface interface / implements Contract — defines what a
class must do
Multiple interfaces implements A, B, C Java's safe answer to
multiple inheritance
Interface extends interface B extends A Child interface inherits
parent interface
Interface reference Animal a = new Dog() Reference type is interface,
object is implementing class
Inner class class Inside {} Class defined inside another
class
Anonymous class new Interface() { ... } Inline implementation
without naming a class
Package define package [Link]; First line of file — declares
its package
Package import import [Link]; Bring a class from another
package into scope
Wildcard import import [Link].*; Import all classes from a
package
[Link] (auto-imported) String, Math, System —
always available