Fymsc (CS) 2024-2025 Seminar Report: Roll No

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 22

FYMSC(CS)

2024-2025
Seminar Report

Submitted By
Roll no-
Subject
Principles of Programming Languages

Topic
Inheritance and types of Inheritance

Sr. No. Title

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.

When to Use Inheritance


Inheritance is most effective when:

● There's a clear "is-a" relationship between classes.

● You want to reuse code from an existing class.

● You need to extend the functionality of an existing class.

● You want to model hierarchical relationships between objects.


Types of Inheritance

1. Single Inheritance

● A class inherits from only one base class.

● This is the most common and straightforward type of 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");
}
}

public class InheritanceExample {


public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
dog.bark();
}
}

Advantages of Single Level Inheritance

● Code Reusability: Derived classes can directly use methods and attributes from the
base class, avoiding redundant code.

● Modularity: Encourages the creation of well-defined, reusable components.

● Extensibility: Allows for adding new features or modifying existing ones without
affecting the base class.

● Hierarchical Relationships: Reflects real-world relationships between objects,


providing a natural way to model complex systems.

● Simplicity: Easier to understand and maintain compared to multiple inheritance.

Disadvantages of Single Level Inheritance

● 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

● A class inherits from more than one base class.

● This allows for combining features from multiple parent classes.

● However, it can lead to ambiguity and the diamond problem, where a class inherits
the same member from multiple base classes.

In Java, multiple inheritance is not directly implemented it uses a concept called


interface.
An interface is a blueprint of a class. It defines the methods that a class must
implement, but it doesn't provide the implementation itself. Interfaces are used to
achieve a form of multiple inheritance in Java.
interface Drawable {
void draw();
}

interface Colorable {
void color();
}

class Circle implements Drawable, Colorable {


public void draw() {
System.out.println("Drawing a circle");
}

public void color() {


System.out.println("Coloring the circle");
}
}
Advantages of Multiple Inheritance

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

● Hierarchical Relationships: Can represent complex hierarchical relationships


between objects.

● Polymorphism: Enables objects of different classes to be treated as if they were of


the same type.
Disadvantages of Multiple Inheritance

● 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");
}
}

class Mammal extends Animal {


void walk() {
System.out.println("Walking");
}
}

class Dog extends Mammal {


void bark() {
System.out.println("Barking");
}
}

public class Main {


public static void main(String[] args) {
Dog myDog = new Dog();
myDog.eat();
myDog.walk();
myDog.bark();
}
}
Advantages of Multilevel Inheritance
1. Extensibility:
o You can extend an existing class hierarchy by adding more levels without
modifying existing code. This makes it easier to expand the functionality of a
system as new requirements arise.
2. Logical Hierarchy Representation:
o Multilevel inheritance helps in representing real-world relationships in a
logical hierarchy. For example, Animal → Mammal → Dog mirrors natural
classification, making it intuitive for developers to model complex systems.

Disadvantages of Multilevel Inheritance


1. Increased Complexity:
o As the inheritance chain grows longer, the relationships between classes can
become more complex and harder to manage. Understanding the flow of data
and control across multiple levels can be challenging, especially in large
systems.
2. Tight Coupling:
o Multilevel inheritance can lead to tightly coupled classes. Changes in the base
class can have a ripple effect, potentially breaking functionality in derived
classes that rely on the base class's implementation.
3. Difficulty in Debugging:
o Debugging issues in a multilevel inheritance structure can be difficult. A
problem in a derived class might originate from a base class several levels up
the hierarchy, making it hard to trace and fix the issue.
4. Reduced Flexibility:
o If a derived class needs to inherit only certain behaviors from a base class but
not others, it might be forced to inherit unnecessary functionality, leading to
less flexible and less efficient code.

When to Use Multilevel Inheritance

● Appropriate When:

o You have a clear, logical hierarchy that models real-world relationships.


o Code reuse is a priority, and the class hierarchy is unlikely to change
frequently.

● Avoid When:

o The class hierarchy becomes deep and complex.


o There is a risk of tightly coupling classes, making the system

4. Hierarchical Inheritance

● Multiple classes inherit from the same base class.

● This creates a tree-like structure, where multiple derived classes share a common
parent.
class Animal {
void eat() {
System.out.println("Eating");
}
}

class Dog extends Animal {


void bark() {
System.out.println("Barking");
}
}

class Cat extends Animal {


void meow() {
System.out.println("Meowing");
}
}

class Bird extends Animal {


void fly() {
System.out.println("Flying");
}
}

public class Main {


public static void main(String[] args) {
Dog myDog = new Dog();
Cat myCat = new Cat();
Bird myBird = new Bird();

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");
}
}

class Dog extends Animal {


String name = "Dog";

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);
}
}

public class Main {


public static void main(String[] args) {
Dog myDog = new Dog();
myDog.eat();
myDog.printNames();
}
}

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;
}

final void display() {


System.out.println("Value: " + value);
}
}

public class Main {


public static void main(String[] args) {
Immutable obj = new Immutable(100);
obj.display();
}
}

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);
}
}

public class Main {


public static void main(String[] args) {
Book book1 = new Book();
book1.display();

Book book2 = new Book("1984", "George Orwell", 15.99);


book2.display();
}
}

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.

● Dependency Injection: Constructors can be used to inject dependencies into an


object, making it easier to test and maintain the object.
Disadvantages of Constructors

● Complexity: Constructors can become complex, especially for classes with many
attributes or dependencies. This can make the code harder to read and maintain.

● Performance: Creating objects can be a relatively expensive operation, especially if


the constructor performs complex initialization or validation.

● Limited Control: The constructor is called automatically when an object is created,


which means that you have limited control over when or how the object is initialized.

Types of Constructors
1. Default Constructor:

● A constructor declared without any parameters.

● Automatically generated if no other constructor is defined.

● Initializes member variables to their default values.

2. Parameterized Constructor:

● A constructor that takes parameters to initialize member variables with specific


values.

● Provides flexibility in object creation.

Use Cases of Constructors


1. Initializing Default Values:
● Set default values for object attributes when no specific values are provided during
creation.
2. Validating Input Parameters:

● Ensure that the values passed to the constructor are valid and within expected ranges.

● Prevent invalid data from being stored in the object.

3. Performing Initialization Tasks:

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

● Promote loose coupling and testability.

5. Overloading for Flexibility:

● Create multiple constructors with different parameter lists to accommodate various


initialization scenarios.
6. Customizing Object Creation:

● Provide control over the creation process, such as setting specific flags or options.

You might also like