Session 18 - Inheritance - Part 2
Session 18 - Inheritance - Part 2
THROUGH JAVA
UNIT - III
Introduction
In Java, the keyword super is used to refer to the superclass (parent class) of the current
object. It provides a way to access superclass methods and constructors, and to resolve
ambiguities between superclass and subclass members. The super keyword can be used in
several scenarios including calling superclass constructors, accessing superclass methods, and
accessing superclass fields.
Syntax
1. Calling Superclass Constructor:
super(arguments);
2. Accessing Superclass Method:
super.methodName(arguments);
3. Accessing Superclass Field:
super.fieldName;
Examples
class Animal {
String name;
Animal(String name) {
this.name = name;
}
}
void display() {
System.out.println("Dog's name is: " + name);
}
}
class Parent {
void show() {
System.out.println("Parent class method");
}
}
class Parent {
int x = 10;
}
void display() {
System.out.println("Parent x: " + super.x); // Accesses x from Parent
System.out.println("Child x: " + x); // Accesses x from Child
}
}
Parent x: 10
Child x: 20
Explanation
● Calling Superclass Constructor: The super keyword can be used to invoke a
constructor of the superclass. This is essential when the superclass constructor requires
parameters to initialize its fields.
● Accessing Superclass Field: When a subclass declares a field with the same name as
a field in the superclass, super allows accessing the superclass field to avoid ambiguity.
The super keyword is a fundamental feature in Java that helps manage class hierarchies by
providing access to superclass members. Understanding how to use super effectively is crucial
for leveraging inheritance in Java and ensuring that subclass instances correctly interact with
their superclass elements.
Do It Yourself
1. Implement a base class Vehicle with a parameterized constructor. Create a derived
class Car that uses super() to call the constructor of Vehicle. Add additional
attributes and methods in Car.
2. Define a class Shape with a method draw(). Create a subclass Circle that overrides
draw() and uses super.draw() to call the method in Shape.
3. Implement a base class Animal with a field age. Create a derived class Cat that hides
the age field and use super.age to access the field in Animal.
4. Create a class hierarchy with Base, Intermediate, and Final classes. Use super to
call methods and constructors across the hierarchy.
Quiz
class A {
void display() {
System.out.println("Class A");
}
}
class B extends A {
void display() {
super.display();
System.out.println("Class B");
}
}
Answer: B) super
class A {
int x = 10;
}
class B extends A {
int x = 20;
void show() {
System.out.println(super.x);
}
}
Answer: A) 10
Introduction
In Java, constructors are special methods used to initialize objects. They are called when an
instance of a class is created. Constructors play a crucial role in inheritance by ensuring that the
superclass is properly initialized before the subclass is instantiated. This document explores the
role of constructors in inheritance, including their syntax, examples, explanations, and practical
applications.
Syntax
1. Constructor Declaration:
ClassName(parameters) {
// constructor body
}
2. Calling Superclass Constructor:
super(arguments);
Examples
class Animal {
Animal() {
System.out.println("Animal constructor");
}
}
Animal constructor
Dog constructor
class Animal {
String name;
Animal(String name) {
this.name = name;
}
}
Dog constructor
Dog's name: Buddy
class Animal {
String name;
Animal() {
this.name = "Unknown";
}
Animal(String name) {
this.name = name;
}
}
Dog() {
super(); // Calls Animal()
this.age = 0;
}
Explanation
- Superclass Constructor Call: When a subclass object is created, the constructor of the
superclass is called first. This ensures that the superclass is properly initialized before
the subclass starts its initialization.
Practice Programs
1. Shape Hierarchy: Create a base class Shape with a no-argument constructor and a
parameterized constructor. Extend it with Circle and Rectangle classes that use
both constructors to initialize their properties.
3. Vehicle System: Implement a base class Vehicle with constructors to set make and
model. Extend it with Car and Bike classes that use the superclass constructors and
initialize additional attributes.
4. Person and Student: Create a base class Person with a parameterized constructor.
Extend it with Student that initializes additional attributes using super() and
demonstrates constructor chaining.
5. Library Items: Develop a base class LibraryItem with constructors for item ID and
title. Extend it with Book and Magazine classes that initialize additional properties and
demonstrate constructor overloading.
Understanding constructors and their role in inheritance is essential for managing class
hierarchies in Java. Constructors ensure proper initialization of objects and facilitate the
inheritance mechanism by setting up superclass properties before subclass-specific
initialization. This knowledge is crucial for writing efficient and maintainable Java code.
Do It Yourself
1. Implement a base class Employee with a constructor that initializes name and ID.
Extend it with Manager and Intern classes that use super() to initialize the base
class fields and add additional attributes.
2. Define a base class Animal with a parameterized constructor for setting name and age.
Create a subclass Bird that uses constructor chaining to initialize both the base class
and its own fields.
3. Create a class Person with multiple constructors for name and age. Extend it with
Student and Teacher classes that use different constructors to initialize their fields.
4. Design a class hierarchy with Vehicle as the base class, and Car and Truck as
subclasses. Implement overloaded constructors in each class to handle different
initialization scenarios.
5. Write a program that demonstrates the use of both no-argument and parameterized
constructors in a class hierarchy where Parent and Child classes are involved.
Quiz
Answer: B) super
class A {
A(int x) {
System.out.println("A constructor with value: " + x);
}
}
class B extends A {
B() {
super(10);
System.out.println("B constructor");
}
}
class Parent {
Parent() {
System.out.println("Parent constructor");
}
}
3. Method Overriding
Introduction
Method overriding is a fundamental concept in Java's object-oriented programming that allows a
subclass to provide a specific implementation of a method that is already defined in its
superclass. This concept is pivotal for achieving runtime polymorphism, which enables a
program to choose the appropriate method implementation based on the object's runtime type.
Syntax
class Superclass {
void methodName() {
// Superclass method implementation
}
}
Examples
class Animal {
void display() {
System.out.println("This is an animal.");
}
}
class Dog extends Animal {
@Override
void display() {
System.out.println("This is a dog.");
}
}
This is an animal.
This is a dog.
class Vehicle {
void start(String type) {
System.out.println("Starting " + type);
}
}
Starting engine
Car is starting with electricity
class Animal {
Animal getAnimal() {
return this;
}
}
This is a dog.
Explanation
● Method Signature: To override a method, the method signature in the subclass must
exactly match the method signature in the superclass. This includes the method name,
return type, and parameter list.
● Access Modifiers: The overridden method in the subclass can have the same or more
permissive access modifier than the method in the superclass. For example, if the
superclass method is protected, the subclass method can be protected or public,
but not private.
● @Override Annotation: This annotation helps to ensure that the method is correctly
overriding a superclass method and not overloading it. It also improves code readability
and maintainability.
Method overriding is a critical feature in Java that allows subclasses to provide specific
implementations of methods defined in their superclasses. This mechanism supports runtime
polymorphism, enabling flexible and dynamic method invocation. Understanding method
overriding helps in designing robust and maintainable object-oriented systems.
Do It Yourself
1. Implement a base class Vehicle with a method accelerate(). Create a subclass
Bike that overrides accelerate() and demonstrate the use of the overridden method.
2. Write a base class Printer with a method print(String document). Extend it with
LaserPrinter and InkjetPrinter classes that override print() to provide
specific printing implementations.
3. Create a base class Building with a method getType(). Extend it with House and
Skyscraper classes that override getType() to return more specific types.
4. Define a base class Person with a protected method getDetails(). Extend it with
Student and Teacher classes that override getDetails() to provide detailed
information.
Quiz
1. Which annotation is used to indicate that a method is overriding a superclass
method?
A) @Override
B) @OverrideMethod
C) @Overriding
D) @OverrideMethod
Answer: A) @Override
Answer: B) The method in the subclass must have the same return type or a subtype.
class Animal {
void sound() {
System.out.println("Animal sound");
}
}
class Base {
void show() {
System.out.println("Base class");
}
}
Introduction
Dynamic Method Dispatch is a core concept in Java that supports runtime polymorphism. It
allows a method to be called based on the actual object type, rather than the reference type, at
runtime. This capability is fundamental to the concept of polymorphism and method overriding in
Java.
Syntax
Dynamic Method Dispatch involves the following key elements:
class Superclass {
void display() {
System.out.println("Superclass display");
}
}
Explanation
- Upcasting: Refers to the process of assigning a subclass object to a superclass
reference. This is essential for dynamic method dispatch.
- Method Overriding: Allows a subclass to provide a specific implementation of a method
already defined in its superclass.
- Runtime Method Resolution: The actual method that gets called is determined at
runtime based on the object's type, not the reference type.
Examples
Bark
Meow
Practice Programs
1. Shape Drawing: Create a base class Shape with a method draw(). Derive Circle,
Rectangle, and Triangle classes from it. Override the draw() method in each
derived class. Use dynamic method dispatch to call the draw() method on various
shape objects.
3. Vehicle System: Implement a base class Vehicle with a method start(). Extend it
with Car, Bike, and Truck classes. Override start() in each subclass. Use dynamic
method dispatch to start different vehicle objects.
4. Media Playback: Define a base class Media with a method play(). Derive Audio and
Video classes from it. Override play() in each subclass. Use dynamic method
dispatch to play different media types.
Dynamic Method Dispatch is a powerful feature of Java that supports runtime polymorphism,
allowing for flexible and adaptable code. Understanding and applying this concept is crucial for
designing robust and maintainable object-oriented systems.
Do It Yourself
1. Write a program with a base class Animal and derived classes Dog and Cat. Override
the makeSound() method in each derived class. Use dynamic method dispatch to
invoke the makeSound() method.
2. Design a class hierarchy with a base class Vehicle and subclasses Car, Truck, and
Motorcycle. Each subclass should override a method startEngine(). Demonstrate
dynamic method dispatch.
3. Implement a base class Calculator with overloaded add() methods. Extend it with
ScientificCalculator that overrides one of the add() methods. Use dynamic
method dispatch to invoke the overridden method.
5. Define a base class Book with a method getDetails(). Extend it with EBook and
PrintedBook classes. Override getDetails() in each subclass and demonstrate
dynamic method dispatch.
Quiz
class Animal {
void makeSound() {
System.out.println("Animal sound");
}
}
5. Abstract Classes
Introduction
Abstract classes in Java are classes that cannot be instantiated on their own and are intended
to be subclasses. They provide a way to define methods that must be implemented by
subclasses and can also contain concrete methods with implementations. Abstract classes are
a key part of Java's abstraction mechanism and are used to define a common interface for a
group of related classes.
Syntax
1. Declaration: An abstract class is declared using the abstract keyword.
2. Abstract Methods: Methods declared without an implementation using the abstract
keyword.
3. Concrete Methods: Regular methods with an implementation can also be included.
Syntax Example:
Key Points
- Abstract Methods: Must be implemented by subclasses.
- Concrete Methods: Can have implementations.
- Abstract Class Instantiation: Cannot be instantiated directly.
- Subclassing: Subclasses must implement all abstract methods to be concrete.
Examples
1. Basic Example
abstract class Animal {
abstract void makeSound(); // Abstract method
Shape(String color) {
this.color = color;
}
void displayColor() {
System.out.println("Color: " + color);
}
}
@Override
void draw() {
System.out.println("Drawing Circle");
}
}
Drawing Circle
Color: Red
Practice Programs
1. Vehicle Hierarchy: Create an abstract class Vehicle with an abstract method
start(). Extend it with Car and Bike classes that implement the start() method.
Demonstrate the use of abstract class and method overriding.
3. Shape Drawing: Define an abstract class Shape with an abstract method draw().
Derive Rectangle, Triangle, and Circle classes from it. Implement the draw()
method in each subclass and use an array of Shape to invoke the draw() method.
Abstract classes in Java are a fundamental feature for creating a common interface for a group
of related classes, enforcing a structure that subclasses must follow. They allow for the
definition of abstract methods that must be implemented by subclasses while providing the
flexibility to include concrete methods with implementations. Understanding and utilizing
abstract classes is crucial for designing flexible and maintainable object-oriented systems.
Do It Yourself
1. Write a program with an abstract class Appliance that has an abstract method
turnOn(). Create two subclasses, Fan and Light, that implement the turnOn()
method. Display the output of both.
2. Create an abstract class Calculator with an abstract method add(). Implement the
method in a subclass ScientificCalculator with method overloading. Provide
different implementations for adding integers and floating-point numbers.
Quiz
Answer: A) abstract
Answer: C) Meow
Answer: B) An abstract class can have both abstract and concrete methods
6. Interfaces and Inheritance
Introduction
In Java, interfaces and inheritance are two fundamental concepts that support polymorphism
and abstraction. While inheritance allows a class to inherit properties and methods from another
class, interfaces provide a way to define a contract that classes can implement. Understanding
how to use both effectively can lead to more flexible and maintainable code.
Interfaces in Java
Syntax
1. Declaration: An interface is declared using the interface keyword.
2. Methods: All methods in an interface are implicitly public and abstract.
3. Fields: Fields in an interface are implicitly public, static, and final.
Syntax Example:
interface Drawable {
void draw(); // Abstract method
}
Key Points
● Methods: Cannot have a body; must be implemented by classes.
● Fields: Can only be constants (i.e., static and final).
● Inheritance: A class can implement multiple interfaces.
● Default Methods: Interfaces can have default methods with a body, introduced in Java
8.
Examples
Bark
Meow
Eating...
Inheritance in Java
Syntax
1. Class Inheritance: Use the extends keyword to inherit from a superclass.
2. Method Overriding: A subclass can override methods of the superclass using the
@Override annotation.
Syntax Example:
class Animal {
void eat() {
System.out.println("Eating...");
}
}
Key Points
● Single Inheritance: A class can inherit from only one superclass.
● Method Overriding: Allows a subclass to provide a specific implementation of a method
that is already defined in its superclass.
● Super Keyword: Used to access superclass methods and constructors.
Examples
1. Basic Inheritance
class Animal {
void makeSound() {
System.out.println("Some sound");
}
}
Bark
Eating...
Dog is eating...
Example
interface Flyable {
void fly();
}
@Override
void makeSound() {
System.out.println("Tweet");
}
}
Tweet
Flying...
Interfaces and inheritance are powerful features in Java that enable polymorphism and
abstraction. Interfaces allow classes to define a contract that must be fulfilled, while inheritance
facilitates code reuse and extension. Mastering both concepts will help in designing robust and
scalable object-oriented systems.
Do It Yourself
1. Create an interface Shape with an abstract method draw(). Implement this interface in
Circle and Square classes. Show how to create objects of these classes and call their
draw() methods.
2. Write a program with a superclass Vehicle and a subclass Car. The Car class should
override a method startEngine() from Vehicle. Demonstrate the usage of the Car
class.
3. Define two interfaces Readable and Writable with methods read() and write()
respectively. Create a class Document that implements both interfaces. Show how to
use this class to read from and write to a document.
Quiz
Answer: A) implements
interface A {
void display();
}
class B implements A {
public void display() {
System.out.println("Display from B");
}
}
References
End of Session - 18