Fymsc (CS) 2024-2025 Seminar Report: Roll No
Fymsc (CS) 2024-2025 Seminar Report: Roll No
Fymsc (CS) 2024-2025 Seminar Report: Roll No
2024-2025
Seminar Report
Submitted By
Roll no-
Subject
Principles of Programming Languages
Topic
Inheritance and types of Inheritance
1 Inheritance
2 Types of Inheritance
3 Super Keyword
4 Final Keyword
5 Constructor
Inheritance in Java is a mechanism in which one object acquires all the properties and
behaviors of a parent object. It is an important part of OOPs (Object Oriented programming
system). The idea behind inheritance in Java is that you can create new classes that are built
upon existing classes. When you inherit from an existing class, you can reuse methods and
felds of the parent class. Moreover, you can add new methods and felds in your current class
also. Inheritance represents the IS-A relationship which is also known as a parent-child
relationship.
Key Concepts in Inheritance
1. Code Reusability: Inheritance promotes reusability by allowing new classes to use
the properties and methods of existing classes. Instead of writing the same code
multiple times, you can define it once in a base class and reuse it in derived classes.
2. Hierarchical Classification: Inheritance helps in organizing classes into a
hierarchical structure. For example, you can have a general class like Animal and then
more specific classes like Mammal, Bird, etc., that inherit from Animal. This structure
mimics real-world relationships.
3. Overriding: A derived class can modify or extend the functionality of methods
inherited from the base class. This process is called overriding. When a method in a
child class has the same name and parameters as a method in the parent class, the
child class's method will override the parent class's method.
4. Access to Parent Class Members: The derived class has access to the public and
protected members of the base class. This allows the child class to utilize the methods
and properties defined in the base class without needing to rewrite them.
5. Constructors in Inheritance: When a derived class is instantiated, the constructor of
the base class is called first, followed by the constructor of the derived class. This
ensures that the base class is properly initialized before the derived class adds its
specific features.
6. Encapsulation and Inheritance: Inheritance respects encapsulation. Private
members of the base class are not accessible directly by the derived class, maintaining
the integrity of the encapsulation principle.
7. Polymorphism and Inheritance: Inheritance supports polymorphism, where a base
class reference can point to objects of its derived classes. This allows for dynamic
method binding, where the appropriate method is called based on the actual object
type at runtime.
8. Virtual Functions and Abstract Classes: In some programming languages, you can
declare methods in the base class as virtual or abstract. A virtual function allows
derived classes to override it, while an abstract class cannot be instantiated on its own
and requires derived classes to provide implementations for its abstract methods.
9. Method Resolution Order (MRO): When a method is called on an object, the
language determines the order in which classes are searched to find that method. This
is especially important in languages that support multiple inheritance.
10. Inheritance and Relationships: Inheritance represents an "is-a" relationship. For
example, if Car is a derived class of Vehicle, then it can be said that a Car is a
Vehicle. This relationship is key to understanding how classes relate to each other in a
hierarchy.
Inheritance simplifies code maintenance, promotes the reuse of existing code, and helps in
creating a well-structured and organized codebase. However, improper use of inheritance can
lead to complexity and tight coupling between classes, making the code harder to manage and
extend. Therefore, it is essential to use inheritance judiciously and where it logically fits the
problem domain. The existing class is called the parent or base class, while the new class is
referred to as the child or derived class.
1. Single Inheritance
Example in java
class Animal {
void eat() {
System.out.println("Animal is eating");
}
}
class Dog extends Animal {
void bark() {
System.out.println("Dog is barking");
}
}
● Code Reusability: Derived classes can directly use methods and attributes from the
base class, avoiding redundant code.
● Extensibility: Allows for adding new features or modifying existing ones without
affecting the base class.
● Limited Flexibility: If you need to inherit from multiple base classes, single
inheritance becomes insufficient.
● Tight Coupling: Derived classes become tightly coupled to their base class, making
them more difficult to modify or reuse independently.
● Fragile Base Class Problem: Changes to the base class can have unintended
consequences for derived classes.
2. Multiple Inheritance
● However, it can lead to ambiguity and the diamond problem, where a class inherits
the same member from multiple base classes.
interface Colorable {
void color();
}
● Flexibility: Allows for inheriting features from multiple base classes, providing
greater flexibility in class design.
● Code Reusability: Can reuse code from multiple parent classes, reducing code
duplication.
● Diamond Problem: Occurs when a class inherits the same member from multiple
base classes, leading to ambiguity in method resolution.
● Complexity: Can make class hierarchies more complex and difficult to understand
and maintain.
● Tight Coupling: Derived classes can become tightly coupled to multiple base classes,
making them more difficult to modify or reuse independently.
● Fragile Base Class Problem: Changes to a base class can have unintended
consequences for derived classes.
3. Multilevel Inheritance
● A class inherits from a class that itself inherits from another class.
● This creates a hierarchical structure, where a derived class inherits from a derived
class.
Example in Java
class Animal {
void eat() {
System.out.println("Eating");
}
}
● Appropriate When:
● Avoid When:
4. Hierarchical Inheritance
● This creates a tree-like structure, where multiple derived classes share a common
parent.
class Animal {
void eat() {
System.out.println("Eating");
}
}
myDog.eat();
myDog.bark();
myCat.eat();
myCat.meow();
myBird.eat();
myBird.fly();
}
}
Use Cases of Hierarchical Inheritance
1. Modeling Shared Characteristics:
o Hierarchical inheritance is useful when multiple classes share common
features but also have their own unique characteristics. For example, in an
educational system, you might have a base class Person with derived classes
like Student, Teacher, and Administrator. All of these share common traits like
name, age, and ID, but each has additional unique attributes and behaviors.
2. Creating Variants of a Class:
o When you need to create multiple variants of a base class with different
functionalities, hierarchical inheritance is appropriate. For example, in a
banking system, a base class Account might have derived classes
SavingsAccount, CurrentAccount, and FixedDepositAccount, each with
specific features.
3. Implementing a Plugin Architecture:
o Hierarchical inheritance can be used in scenarios where you want to develop a
system with a base class that defines the core functionality, and derived
classes implement various extensions or plugins. For instance, in a graphics
editing software, a base class Tool might have derived classes like BrushTool,
EraserTool, and FillTool, each providing specific behavior.
4. Game Development:
o In game development, hierarchical inheritance is often used to model game
entities. For example, a base class GameObject could have derived classes like
Player, Enemy, and Obstacle, where each derived class has different properties
and behaviors but shares common attributes like position and movement
methods.
Super
The `super` keyword in Java is a reference variable used to refer to the immediate parent
class of an object. It is commonly used in three scenarios:
1. **Accessing Parent Class Variables**: If a child class has a variable with the same name
as a variable in the parent class, the `super` keyword can be used to differentiate between the
two. For example, `super.variableName` accesses the parent class’s variable.
2. **Invoking Parent Class Methods**: When a method in the child class overrides a method
in the parent class, you can use `super.methodName()` to call the method from the parent
class. This is useful when you want to extend or modify the behavior of the parent class's
method rather than completely overriding it.
3. **Calling Parent Class Constructors**: The `super()` keyword is used to invoke the parent
class's constructor. This is particularly important when the parent class constructor has
parameters. The call to `super()` must be the first statement in the child class constructor.
Using the `super` keyword helps in achieving proper encapsulation and allows for more
control over inheritance, especially in complex class hierarchies. It ensures that the child
class can interact with the parent class's properties and behaviors effectively.
class Animal {
String name = "Animal";
Animal() {
System.out.println("Animal constructor");
}
void eat() {
System.out.println("Animal is eating");
}
}
Dog() {
super();
System.out.println("Dog constructor");
}
void eat() {
super.eat();
System.out.println("Dog is eating");
}
void printNames() {
System.out.println("Parent class name: " + super.name);
System.out.println("Child class name: " + this.name);
}
}
Final
The final keyword in Java is used to define constants, prevent method overriding, and prevent
inheritance. It can be applied to variables, methods, and classes with different effects:
1. Final Variables: When a variable is declared as final, its value cannot be changed
once assigned. This makes it a constant. For example, final int MAX_SPEED = 120;
ensures that MAX_SPEED remains constant throughout the program.
2. Final Methods: Declaring a method as final prevents it from being overridden by any
subclasses. This ensures that the method's behavior remains consistent and cannot be
altered by derived classes.
3. Final Classes: A class declared as final cannot be subclassed. This is useful for
creating immutable classes or ensuring that the class's behavior cannot be extended.
Using final enhances the robustness of the code by enforcing certain constraints, which can
help in maintaining the integrity and consistency of the application.
final class Immutable {
final int value;
Immutable(int value) {
this.value = value;
}
Constructor
A constructor in Java is a special method used to initialize objects when they are created.
Constructors play a crucial role in object-oriented programming by ensuring that objects start
their life in a valid state. Here’s a detailed explanation of constructors:
Characteristics of Constructors
1. Name:
o A constructor must have the same name as the class in which it is defined. For
example, if the class is named Person, the constructor must also be named
Person.
2. No Return Type:
o Constructors do not have a return type, not even void. Their sole purpose is to
initialize the newly created object.
3. Automatic Invocation:
o Constructors are automatically called when an object is created using the new
keyword. The constructor initializes the object’s state and sets up any
necessary conditions.
4. Overloading:
o A class can have more than one constructor with different parameters. This is
known as constructor overloading. It allows objects to be initialized in various
ways.
5. Default Constructor:
o If no constructor is explicitly defined in a class, the Java compiler
automatically provides a no-argument constructor, known as the default
constructor. This default constructor initializes all instance variables to their
default values (e.g., null for objects, 0 for integers).
6. Parameterized Constructor:
o Constructors can take parameters, allowing for initialization of objects with
specific values. This is known as a parameterized constructor.
Example in java
class Book {
String title;
String author;
double price;
Book() {
title = "Unknown";
author = "Unknown";
price = 0.0;
}
Book(String title, String author, double price) {
this.title = title;
this.author = author;
this.price = price;
}
void display() {
System.out.println("Title: " + title + ", Author: " + author + ", Price: $" + price);
}
}
Advantages of Constructors
● Initialization: Constructors ensure that objects are initialized with appropriate values
when they are created. This helps prevent errors and inconsistencies in the object's
state.
● Data Validation: Constructors can be used to validate the values passed to the object
during creation. This can help prevent invalid data from being stored in the object.
● Object Creation: Constructors are essential for creating new instances of a class.
Without constructors, it would be difficult or impossible to create objects.
● Overloading: Constructors can be overloaded, meaning that a class can have multiple
constructors with different parameters. This allows for more flexibility in object
creation and initialization.
● Complexity: Constructors can become complex, especially for classes with many
attributes or dependencies. This can make the code harder to read and maintain.
Types of Constructors
1. Default Constructor:
2. Parameterized Constructor:
● Ensure that the values passed to the constructor are valid and within expected ranges.
● Execute necessary actions to set up the object's internal state or establish connections
to external resources.
4. Dependency Injection:
● Inject required dependencies (other objects) into the newly created object.
● Provide control over the creation process, such as setting specific flags or options.