Java Inheritance

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

Java Inheritance

Q.1. 1.Define inheritance. What are the benefits of inheritance? How to prevent a clas: from
inheritance in java?
—> Inheritance is a core principle of object-oriented programming (OOP) that allows one class to
inherit the properties and behaviors (methods) of another class. This mechanism creates a
parent-child relationship between classes, where the child class (also known as the derived class
or subclass) inherits attributes and methods from the parent class (also known as the base class
or superclass).

Benefits of Inheritance:

1. Code Reusability: Inheritance promotes the reuse of existing code. Rather than rewriting code
for common functionalities, a subclass can inherit and extend the capabilities of the superclass.
This significantly reduces code duplication and enhances productivity.

2. Method Overriding: Subclasses can provide specific implementations of methods that are
defined in the superclass. This allows for dynamic method resolution, where the method that
gets executed is determined at runtime based on the object's actual class type, enabling
polymorphism.

3. Hierarchical Classification: Inheritance allows for a natural hierarchy in the organization of


classes. This hierarchical structure makes it easier to understand the relationships between
different classes and encapsulate related functionalities.

4. Extensibility: New functionality can be added to existing classes by creating subclasses. This
allows developers to extend the behavior of existing classes without modifying their code,
promoting a more modular approach to software development.

5. Improved Maintainability: Changes made to a superclass are automatically inherited by all


subclasses. This means that if a bug is fixed or a feature is added in the superclass, all
subclasses benefit from this change, which simplifies maintenance and reduces the risk of
introducing new errors.

Preventing a Class from Inheritance:

To prevent a class from being inherited, you can declare it as a final class in languages like Java
or use the sealed keyword in languages like C#. When a class is marked as final or sealed, it
cannot be subclassed, ensuring that its implementation remains unchanged.

For example, in Java, you would declare a final class as follows:


```java
final class MyFinalClass {
// Class implementation
}
```

In this example, `MyFinalClass` cannot be extended by any other class, which helps to maintain
the integrity of its implementation and ensures that its methods and properties are not altered by
subclasses.

In summary, inheritance is a powerful feature that enhances code reusability, maintainability, and
organization in object-oriented programming. However, when necessary, developers can also
prevent inheritance to protect the integrity of certain classes.

Q.2. Write a program to demonstrate hierarchical and multiple inheritance using interfaces in
java.
—> Here’s a detailed explanation of a Java program that demonstrates hierarchical inheritance
and multiple inheritance using interfaces.

### Explanation of Concepts

1. Hierarchical Inheritance: This occurs when multiple subclasses inherit from a single
superclass. In our example, both `Dog` and `Cat` classes inherit from the `Animal` class.

2. Multiple Inheritance: In Java, multiple inheritance is achieved through interfaces. A class can
implement multiple interfaces, allowing it to inherit behavior from more than one source. In our
example, both `Dog` and `Cat` implement the `Pet` interface, while the `Lion` class implements
the `Wild` interface.

### Java Program

```java
// Base class
class Animal {
void eat() {
System.out.println("This animal eats food.");
}
}

// Subclass Dog inheriting from Animal


class Dog extends Animal implements Pet {
@Override
public void play() {
System.out.println("The dog plays fetch.");
}
}

// Subclass Cat inheriting from Animal


class Cat extends Animal implements Pet {
@Override
public void play() {
System.out.println("The cat plays with a ball of yarn.");
}
}

// Interface Pet
interface Pet {
void play();
}

// Interface Wild
interface Wild {
void hunt();
}

// Class Lion demonstrating multiple inheritance through interfaces


class Lion extends Animal implements Wild {
@Override
public void hunt() {
System.out.println("The lion hunts in the jungle.");
}
}

// Main class to test the program


public class InheritanceDemo {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
dog.play();

Cat cat = new Cat();


cat.eat();
cat.play();

Lion lion = new Lion();


lion.eat();
lion.hunt();
}
}
```

### Breakdown of the Program

1. Base Class - Animal:


- The `Animal` class is defined with a method `eat()`, which outputs a generic message about
animals eating food.

2. Subclass - Dog:
- The `Dog` class extends the `Animal` class, inheriting its properties and methods.
- It implements the `Pet` interface, which requires the implementation of the `play()` method.
Here, the `play()` method is overridden to provide a specific behavior for dogs.

3. Subclass - Cat:
- The `Cat` class also extends the `Animal` class and implements the `Pet` interface.
- Similar to `Dog`, it provides its own implementation of the `play()` method, which describes
how a cat plays.

4. Interface - Pet:
- The `Pet` interface declares a method `play()`. Any class implementing this interface must
provide an implementation for this method.

5. Interface - Wild:
- The `Wild` interface declares a method `hunt()`. Classes implementing this interface must
provide their own version of the `hunt()` method.

6. Subclass - Lion:
- The `Lion` class extends the `Animal` class and implements the `Wild` interface.
- It provides its own implementation of the `hunt()` method, describing how a lion hunts.

7. Main Class - InheritanceDemo:


- The `main` method serves as the entry point for the program.
- It creates instances of `Dog`, `Cat`, and `Lion`.
- For each instance, it calls the `eat()` method inherited from `Animal` and the respective
`play()` or `hunt()` methods, demonstrating the functionality of hierarchical and multiple
inheritance.

### Output of the Program

When you run this program, the output will be:

```
This animal eats food.
The dog plays fetch.
This animal eats food.
The cat plays with a ball of yarn.
This animal eats food.
The lion hunts in the jungle.
```

### Conclusion

This program effectively demonstrates hierarchical inheritance through the `Animal`, `Dog`, and
`Cat` classes, and multiple inheritance using the `Pet` and `Wild` interfaces implemented by
`Dog`, `Cat`, and `Lion`. Each class and interface contributes to a clear structure, showcasing
how Java handles inheritance and polymorphism.

Q.3. Define polymorphism in java. Explain run time polymorphism with the help of an example.
—> Polymorphism in Java refers to the ability of a single function or method to operate in
different ways based on the context. It allows methods to do different things based on the object
that it is acting on, which can be achieved through method overriding and method overloading.

Run time polymorphism, also known as dynamic method dispatch, occurs when a method call is
resolved at runtime rather than compile time. This is typically achieved using inheritance and
method overriding.

Here's a simple example to illustrate run time polymorphism:

1. Create a base class (Parent):


```java
class Parent {
void display() {
System.out.println("Display from Parent");
}
}
```

2. Create a subclass (Child):


```java
class Child extends Parent {
void display() {
System.out.println("Display from Child");
}
}
```

3. Create a main class to demonstrate run time polymorphism:


```java
public class TestPolymorphism {
public static void main(String[] args) {
Parent obj; // Declare a reference of Parent type
obj = new Child(); // Create an object of Child class
obj.display(); // Call the display method
}
}
```

In this example:
- We have a base class `Parent` with a method `display()`.
- The `Child` class extends `Parent` and overrides the `display()` method.
- In the `main` method, we declare a reference of type `Parent` but instantiate it with an object
of `Child`.
- When we call `obj.display()`, it invokes the `display()` method of the `Child` class, not the
`Parent` class. This is because the method is resolved at runtime based on the actual object
type (Child) rather than the reference type (Parent).
The output of this program will be:
```
Display from Child
```

This demonstrates run time polymorphism, as the method that gets executed is determined at
runtime based on the object being referred to, rather than the type of the reference variable.

Q.4. Describe the uses of super keywords with respect to inheritance in java.
—> In Java, the `super` keyword plays a crucial role when dealing with inheritance, allowing a
subclass to access members (methods and variables) of its superclass. Here's a detailed
explanation of its uses:

1. Accessing Superclass Methods: When a subclass overrides a method from its superclass, you
can still invoke the original method using `super`. This is particularly useful when you want to
add additional behavior to the existing functionality of the superclass method instead of
completely replacing it. For example:

```java
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}

class Dog extends Animal {


void sound() {
super.sound(); // Calls the sound method from Animal class
System.out.println("Dog barks");
}
}

public class Test {


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

In this example, when `dog.sound()` is called, it first executes the `sound()` method of the
`Animal` class and then executes the additional behavior defined in the `Dog` class. The output
will be:
```
Animal makes a sound
Dog barks
```

2. Accessing Superclass Constructors: The `super()` keyword is used to call a constructor of the
superclass. This is especially important when the superclass has parameters that need to be
initialized. You must call `super()` as the first statement in the subclass constructor. For
example:

```java
class Animal {
Animal(String name) {
System.out.println("Animal name is: " + name);
}
}

class Dog extends Animal {


Dog(String name) {
super(name); // Calls the constructor of Animal class
System.out.println("Dog created");
}
}

public class Test {


public static void main(String[] args) {
Dog dog = new Dog("Buddy");
}
}
```

Here, when you create a `Dog` object with `new Dog("Buddy")`, it first calls the constructor of
the `Animal` class with the name "Buddy", and then it continues to the `Dog` constructor. The
output will be:
```
Animal name is: Buddy
Dog created
```

3. Accessing Superclass Variables: If a subclass has a field with the same name as a field in its
superclass, using `super` allows you to refer to the superclass field, avoiding ambiguity. For
instance:

```java
class Animal {
String type = "Animal";
}

class Dog extends Animal {


String type = "Dog";

void printType() {
System.out.println("Type from superclass: " + super.type); // Accesses Animal's type
System.out.println("Type from subclass: " + this.type); // Accesses Dog's type
}
}

public class Test {


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

In this case, when `printType()` is called, it prints the `type` variable from both the superclass
and subclass. The output will be:
```
Type from superclass: Animal
Type from subclass: Dog
```

4. Calling Superclass Methods with Parameters: You can also use `super` to call methods from
the superclass that take parameters. This allows you to leverage existing functionality while
providing specific data. For example:

```java
class Animal {
void eat(String food) {
System.out.println("Animal eats: " + food);
}
}

class Dog extends Animal {


void eat(String food) {
super.eat(food); // Calls the eat method from Animal class
System.out.println("Dog enjoys eating: " + food);
}
}

public class Test {


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

The output will be:


```
Animal eats: meat
Dog enjoys eating: meat
```

In summary, the `super` keyword in Java is a powerful tool in inheritance. It allows subclasses to
access and extend the functionality of their superclasses by calling methods, accessing
variables, and invoking constructors, thus promoting code reuse and organization.
Q.5.Explain the concept of multilevel inheritance using a simple java program.
—> Multilevel inheritance is a type of inheritance in object-oriented programming where a class
derives from another class, forming a chain of classes. In this structure, a derived class can
inherit from a base class, and then another class can inherit from that derived class, creating
multiple levels.

Here's a simple Java program illustrating multilevel inheritance:

```java
// Base class
class Animal {
void eat() {
System.out.println("This animal eats food.");
}
}

// Derived class 1
class Mammal extends Animal {
void walk() {
System.out.println("This mammal walks on land.");
}
}

// Derived class 2
class Dog extends Mammal {
void bark() {
System.out.println("The dog barks.");
}
}

// Main class to test the multilevel inheritance


public class MultilevelInheritanceExample {
public static void main(String[] args) {
Dog dog = new Dog();

// Calling methods from different levels of inheritance


dog.eat(); // Inherited from Animal class
dog.walk(); // Inherited from Mammal class
dog.bark(); // Method from Dog class
}
}
```

In this example:

1. The `Animal` class is the base class with a method `eat()`.


2. The `Mammal` class extends `Animal`, inheriting its properties and methods, and adds its
own method `walk()`.
3. The `Dog` class extends `Mammal`, inheriting both `eat()` and `walk()` methods, and adds
its own method `bark()`.

When we create an object of the `Dog` class and call its methods, it can access methods from
both the `Animal` and `Mammal` classes due to multilevel inheritance. The output of the
program will be:

```
This animal eats food.
This mammal walks on land.
The dog barks.
```

This demonstrates how multilevel inheritance allows a class to inherit features from multiple
levels of its hierarchy.

Q.6.What is an abstract class in java? What is an interface? List the rules to create an interface in
java with example.
—> An abstract class in Java is a class that cannot be instantiated on its own and is meant to be
subclassed. It can contain abstract methods (methods without a body) as well as concrete
methods (methods with a body). Abstract classes are used when you want to define a template
for other classes to follow, allowing for shared functionality while enforcing certain methods to
be implemented by subclasses.

An interface, on the other hand, is a reference type in Java that is similar to a class but can only
contain abstract methods (prior to Java 8) and constants. Interfaces are used to define a
contract that classes can implement, allowing for multiple inheritance of type. A class that
implements an interface must provide implementations for all of its methods.

### Rules to Create an Interface in Java:

1. Declaration: Use the `interface` keyword to declare an interface.


2. Abstract Methods: All methods in an interface are implicitly abstract (unless they are static or
default methods introduced in Java 8).
3. No Constructors: Interfaces cannot have constructors because they cannot be instantiated.
4. Public and Static: All variables in an interface are implicitly public, static, and final (constants).
5. Multiple Inheritance: A class can implement multiple interfaces, allowing for a form of multiple
inheritance.

### Example of an Interface:

```java
// Interface declaration
interface Animal {
// Abstract method
void sound(); // No body, must be implemented by the class
}

// Class implementing the interface


class Dog implements Animal {
// Providing implementation for the abstract method
public void sound() {
System.out.println("The dog barks.");
}
}

class Cat implements Animal {


// Providing implementation for the abstract method
public void sound() {
System.out.println("The cat meows.");
}
}

// Main class to test the interface


public class InterfaceExample {
public static void main(String[] args) {
Animal dog = new Dog();
Animal cat = new Cat();

dog.sound(); // Output: The dog barks.


cat.sound(); // Output: The cat meows.
}
}
```

In this example:

- The `Animal` interface defines an abstract method `sound()`.


- The `Dog` and `Cat` classes implement the `Animal` interface and provide their own versions
of the `sound()` method.
- The main class demonstrates how to use the interface to call the `sound()` method on different
animal objects.

This illustrates how interfaces can be used to enforce a contract for classes, allowing for
polymorphism and flexibility in your code.

Q.7. What are the benefits of inheritance? Explain the various forms of inheritance with suitable
code segments.
—> Inheritance is a fundamental concept in object-oriented programming (OOP) that allows a
new class to inherit properties and behaviors (methods) from an existing class. Here are some
benefits of inheritance:

1. Code Reusability: Inheritance promotes reusability of code. You can create a new class based
on an existing class, which allows you to reuse the code without rewriting it.

2. Method Overriding: Subclasses can provide specific implementations of methods that are
already defined in their parent class, allowing for dynamic behavior.

3. Hierarchical Classification: Inheritance helps in organizing classes in a hierarchical manner,


which can make the system easier to understand and manage.

4. Polymorphism: Inheritance supports polymorphism, which allows methods to be used in


different ways depending on the object that is calling them.

5. Extensibility: It is easier to extend an existing class with new features without modifying the
original class.

Now, let's look at the various forms of inheritance in Java:

1. Single Inheritance: A class inherits from one superclass.

```java
class Animal {
void eat() {
System.out.println("Eating...");
}
}

class Dog extends Animal {


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

2. Multilevel Inheritance: A class can inherit from another class, which in turn inherits from
another class.

```java
class Animal {
void eat() {
System.out.println("Eating...");
}
}

class Dog extends Animal {


void bark() {
System.out.println("Barking...");
}
}
class Puppy extends Dog {
void weep() {
System.out.println("Weeping...");
}
}
```

3. Hierarchical Inheritance: Multiple classes inherit from a single superclass.

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

4. Multiple Inheritance (through Interfaces): Java does not support multiple inheritance with
classes to avoid ambiguity, but it can be achieved using interfaces.

```java
interface CanRun {
void run();
}

interface CanBark {
void bark();
}
class Dog implements CanRun, CanBark {
public void run() {
System.out.println("Dog is running...");
}

public void bark() {


System.out.println("Dog is barking...");
}
}
```

In summary, inheritance in Java provides a way to create a new class from an existing class,
allowing for code reuse, method overriding, and a structured approach to class organization.
Each form of inheritance serves different design needs and can be utilized to create flexible and
maintainable code.

Q. 8.Describe the uses of final and super keywords with respect to inheritance.
—> In Java, the `final` and `super` keywords play important roles in the context of inheritance.
Here’s an explanation of their uses:

### `final` Keyword

1. Final Class: When a class is declared as `final`, it cannot be subclassed. This is useful when
you want to prevent inheritance for security reasons or to maintain the integrity of the class.

```java
final class FinalClass {
void display() {
System.out.println("This is a final class.");
}
}
// The following code will produce an error
// class SubClass extends FinalClass { } // Error: Cannot inherit from final 'FinalClass'
```

2. Final Method: A method declared as `final` cannot be overridden by subclasses. This is useful
when you want to ensure that the behavior of a method remains unchanged in derived classes.

```java
class Parent {
final void show() {
System.out.println("This method cannot be overridden.");
}
}

class Child extends Parent {


// The following code will produce an error
// void show() { } // Error: Cannot override the final method from Parent
}
```

3. Final Variable: A variable declared as `final` cannot be reassigned once it has been initialized.
This is useful for defining constants.

```java
class Example {
final int constantValue = 10;

void display() {
// constantValue = 20; // Error: Cannot assign a value to final variable constantValue
System.out.println("Constant Value: " + constantValue);
}
}
```

### `super` Keyword

1. Accessing Parent Class Members: The `super` keyword is used to refer to the immediate
parent class. It can be used to access methods and variables of the parent class that are hidden
by the subclass.

```java
class Parent {
void display() {
System.out.println("Display from Parent class.");
}
}

class Child extends Parent {


void display() {
super.display(); // Calls the display method of Parent class
System.out.println("Display from Child class.");
}
}
```

2. Calling Parent Class Constructor: The `super()` constructor can be used to call the
constructor of the parent class. This is often done to initialize inherited attributes.

```java
class Parent {
Parent() {
System.out.println("Parent constructor called.");
}
}

class Child extends Parent {


Child() {
super(); // Calls the Parent constructor
System.out.println("Child constructor called.");
}
}
```

In summary, the `final` keyword is used to restrict inheritance and modification of classes,
methods, and variables, while the `super` keyword is utilized to access members of the parent
class and to invoke the parent class constructor. These keywords help in controlling the behavior
of classes and their relationships in inheritance hierarchies.
Q.9.Design an interface called Shape with methods draw() and getArea().
Further design two classes called Circle and Rectangle that implements Shape interface to
compute area of respective shapes. Use appropriate getter and setter methods. Write a java
program for the same.
—> Here's a complete Java program that defines an interface called `Shape`, and two classes
`Circle` and `Rectangle` that implement this interface. The program includes methods to
calculate the area of each shape and uses appropriate getter and setter methods.

```java
// Define the Shape interface
interface Shape {
void draw(); // Method to draw the shape
double getArea(); // Method to calculate the area
}

// Circle class implementing Shape interface


class Circle implements Shape {
private double radius;

// Constructor
public Circle(double radius) {
this.radius = radius;
}

// Getter for radius


public double getRadius() {
return radius;
}

// Setter for radius


public void setRadius(double radius) {
this.radius = radius;
}

// Implementation of draw method


@Override
public void draw() {
System.out.println("Drawing a Circle with radius: " + radius);
}

// Implementation of getArea method


@Override
public double getArea() {
return Math.PI * radius * radius; // Area = π * r²
}
}

// Rectangle class implementing Shape interface


class Rectangle implements Shape {
private double length;
private double width;

// Constructor
public Rectangle(double length, double width) {
this.length = length;
this.width = width;
}

// Getter for length


public double getLength() {
return length;
}

// Setter for length


public void setLength(double length) {
this.length = length;
}

// Getter for width


public double getWidth() {
return width;
}

// Setter for width


public void setWidth(double width) {
this.width = width;
}

// Implementation of draw method


@Override
public void draw() {
System.out.println("Drawing a Rectangle with length: " + length + " and width: " + width);
}

// Implementation of getArea method


@Override
public double getArea() {
return length * width; // Area = length * width
}
}

// Main class to test the implementation


public class ShapeTest {
public static void main(String[] args) {
// Create a Circle object
Circle circle = new Circle(5);
circle.draw();
System.out.println("Area of Circle: " + circle.getArea());

// Create a Rectangle object


Rectangle rectangle = new Rectangle(4, 6);
rectangle.draw();
System.out.println("Area of Rectangle: " + rectangle.getArea());
}
}
```

In this program:
1. The `Shape` interface declares two methods: `draw()` and `getArea()`.
2. The `Circle` class implements the `Shape` interface, providing definitions for the `draw()`
and `getArea()` methods. It also has getter and setter methods for the radius.
3. The `Rectangle` class also implements the `Shape` interface, providing its own
implementations for the methods, along with getter and setter methods for length and width.
4. The `ShapeTest` class contains the `main` method to create instances of `Circle` and
`Rectangle`, draw them, and print their areas.

You can run this program in any Java environment.

You might also like