0% found this document useful (0 votes)
15 views

Lab 4

Object Oriented Programming Lab Sheets

Uploaded by

f20220584
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views

Lab 4

Object Oriented Programming Lab Sheets

Uploaded by

f20220584
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 26

BITS, Pilani - Hyderabad Campus

Object-Oriented Programming (CS F213)


Lab Sheet 4
Topics: Inheritance and Polymorphism

Java Inheritance

It is the mechanism in Java by which one class is allowed to inherit the


features (fields and methods) of another class. In Java, Inheritance means
creating new classes based on existing ones. A class that inherits from
another class can reuse the methods and fields of that class. In addition,
you can add new fields and methods to your current class as well.

Types of Inheritance:

1. Single Inheritance :

import java.io.*;
// Base or Super Class

class Employee {
int salary = 60000;
}

// Inherited or Sub Class


class Engineer extends Employee {
int benefits = 10000;
}

class Main {
public static void main(String args[])
{
Engineer E1 = new Engineer();
System.out.println("Salary : " + E1.salary
+ "\nBenefits : " + E1.benefits);
}
//salary is accessible through Engineer class
object as it is the subclass of Employee
}

Super class versus subclass referencing:

Example2:
class employee{
int salary = 6000;
void display(){
System.out.println("display");
}
}

class engineer extends employee{


int benefits = 10000;
void display(){
System.out.println("display1");
}

void show(){
System.out.println("show");
}
}
class main7{
public static void main(String args[]){
//engineer e1 = new engineer();//subclass to
subclass//
//System.out.println("salary:" + e1.salary +
"\nbenefits:" + e1.benefits);

//engineer e2 = new employee();//sublass to


superclass throws error//

// employee e3 = new engineer();//superclass to


subclass cannot access //
// e3.display(); //Calling method in super class
// e3.show(); //but cannot access sub class with
superclass reference

employee e4 = new employee();//superclass to


superclass//
e4.display();
e4.show(); //cannot access sub-class with super
class object
}
}

2. Multilevel Inheritance

When there is a chain of inheritance, it is known as multilevel inheritance. As you


can see in the example given below, BabyDog class inherits the Dog class which
again inherits the Animal class, so there is a multilevel inheritance.

import java.io.*;
class Animal{
void eat(){
System.out.println("eating...");}
}

class Dog extends Animal{


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

class BabyDog extends Dog{


void weep(){
System.out.println("weeping...");}
}
class Main{
public static void main(String args[]){
BabyDog d=new BabyDog();
d.weep();
d.bark();
d.eat();
}}

3. Hierarchical Inheritance

When two or more classes inherits a single class, it is known as hierarchical


inheritance. In the example given below, Dog and Cat classes inherits the Animal
class, so there is hierarchical inheritance

import java.io.*;
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 Main{
public static void main(String args[]){
Cat c=new Cat();
c.meow();
c.eat();
}}
but here if we call c.bark(); in Main class then it
would produce the following error:

Main.java:19: error: cannot find symbol


c.bark();
^
symbol: method bark()
location: variable c of type Cat
1 error

This implies Dog and Cat class can inherit the properties of Animal class as they
extend it but they can't access variables and methods of each other as they are not
related to each other.

4. Multiple Inheritance
To reduce the complexity and simplify the language, multiple inheritance is not
supported in java. Consider a scenario where A, B, and C are three classes. The C
class inherits A and B classes. If A and B classes have the same method and you
call it from child class object, there will be ambiguity to call the method of A or B
class.

Java renders compile-time error if you inherit 2


classes

class A{
void msg(){
System.out.println("Hello");}
}
class B{
void msg()
{System.out.println("Welcome");}
}
class C extends A,B{
public static void main(String args[]){
C obj=new C();
obj.msg();
}
}

Output

Main.java:7: error: '{' expected


class C extends A,B {
^
1 error

Java super keyword


The super keyword refers to superclass (parent) objects. It is used to call superclass
methods, and to access the superclass constructor.

The most common use of the super keyword is to eliminate the confusion between
superclasses and subclasses that have methods with the same name.

super can be used with (In below examples it is assumed Main class is created and
an object of subclass is created)

class Vehicle {

int maxSpeed = 120;

class Car extends Vehicle {

void display() {

System.out.println("Maximum Speed: "

+ super.maxSpeed);

Method Overriding in Java

If subclass (child class) has the same method as declared in the parent class, it is known as
method overriding in Java. In other words, If a subclass provides the specific implementation of
the method that has been declared by one of its parent class, it is known as method overriding.

Method overriding occurs only when the names and the type signatures of the
two methods are identical. If they are not, then the two methods are simply
overloaded.

Example
class Vehicle{

//defining a method

void run(){

System.out.println("Vehicle is running");}

//Creating a child class

class Bike2 extends Vehicle{

//defining the same method as in the parent class

void run(){

System.out.println("Bike is running");}

class Main{

public static void main(String args[]){

Bike2 obj = new Bike2();

obj.run();

Output

Bike is running

Java method overriding is mostly used in Runtime Polymorphism

In the above program if we want to print "Vehicle is


running", we can use super.run();

Method overriding forms the basis for one of Java’s most powerful concepts: dynamic
method dispatch. Dynamic method dispatch is the mechanism by which a call to an
overridden method is resolved at run time, rather than compile time. Dynamic method dispatch is
important because this is how Java implements run-time polymorphism.

Interfaces

Another way to achieve abstraction in Java, is with interfaces. An interface is a


completely "abstract class" that is used to group related methods with empty bodies

// interface
interface Animal {
public void animalSound(); // interface method (does
not have a body)
public void run(); // interface method (does not have
a body)
}

To access the interface methods, the interface must be "implemented" (kind of like
inherited) by another class with the implements keyword (instead of extends). The
body of the interface method is provided by the "implement" class

// Interface
interface Animal {
public void animalSound(); // interface method (does
not have a body)
public void sleep(); // interface method (does not
have a body)
}

// Pig "implements" the Animal interface


class Pig implements Animal {
public void animalSound() {
// The body of animalSound() is provided here
System.out.println("The pig says: wee wee");
}
public void sleep() {
// The body of sleep() is provided here
System.out.println("Zzz");
}
}

class Main {
public static void main(String[] args) {
Pig myPig = new Pig(); // Create a Pig object
myPig.animalSound();
myPig.sleep();
}
}

Abstract class: A class in Java can contain both methods and variables. In
some situations, where it's not possible to provide a method's
implementation but only its declaration, the abstract keyword is used.

● When you have an abstract method in a class, the class automatically


becomes an abstract class.
● A class can contain both abstract and non-abstract(concrete)
methods.
● An abstract class cannot be instantiated directly.
● Subclasses of an abstract class must provide implementations of the
abstract methods specified in the abstract class definition.
● Abstract classes can have constructors that initialize fields defined in
the abstract class methods in the abstract class.
Syntax :
public abstract class Vehicle {

//Concrete method
public int getSpeed { return speed; }
public String getManufacturer() {
return manufacturer;
}
//abstract method (only declaration)
public abstract double computeTax();

Example: Create an abstract class called ‘Animal’ . It


has an abstract method, ‘makeSound()’ and a concrete
method, sleep(). Create two sub-classes, Dog and Cat
and define makeSound() method. Create a Main method
where objects of Dog and Cat are created.

abstract public class Animal {


abstract void makeSound(); //abstract method
void sleep(){
System.out.println("Sleeping");
}
}
//sub-class extending abstract class
public class Dog extends Animal{
void makeSound()
{
System.out.println("Bow Bow");
}
}
public class Cat extends Animal{
void makeSound(){
System.out.println("Meow..");
}}

public class MainAbstract {


public static void main(String[] args){
Dog d = new Dog();
Cat c = new Cat();
d.makeSound();
d.sleep();
c.makeSound();
}
}

Final: In Java, the final keyword can be applied to a class, method, or


variable, with different meanings depending on the context. When applied
to a class, it defines a final class.

● A final class is a class that cannot be subclassed. In other words, no


other class can extend a final class.
● The primary purpose of making a class final is to prevent inheritance,
ensuring that the class’s implementation remains unchanged.
Example:

// Final class
public final class FinalClass {

// Method in the final class


public void display() {
System.out.println("This is a method in a final
class.");
}
}

// Uncommenting the following code will cause a


compilation error:
// class SubClass extends FinalClass {
// }

public class Main {


public static void main(String[] args) {
// Create an instance of the final class
FinalClass finalClassInstance = new FinalClass();
finalClassInstance.display();
}
}

Final Method: Prevents a method from being overridden in a subclass.


The method can still be inherited, but it cannot be modified in the subclass.

Example:

class SuperClass {
// Final method
public final void finalMethod() {
System.out.println("This is a final method.");
}

// Non-final method
public void nonFinalMethod() {
System.out.println("This is a non-final method.");
}
}

class SubClass extends SuperClass {


// This will cause a compilation error if
uncommented:
// @Override
// public void finalMethod() {
// System.out.println("Cannot override a final
method.");
// }

@Override
public void nonFinalMethod() {
System.out.println("Overridden non-final method.");
}
}

public class Main {


public static void main(String[] args) {
SubClass subclass = new SubClass();
subclass.finalMethod(); // Calls the final
method from SuperClass
subclass.nonFinalMethod(); // Calls the
overridden method from SubClass
}
}

Nested and Inner classes:

Static Class: In Java, a static class is a class that is nested within another
class and is declared with the static keyword. This concept is specific to
nested classes.

Example:

// Outer class
public class OuterClass {
// Static member of the outer class
private static String staticMember = "Outer static
member";

// Static nested class


public static class StaticNestedClass {
// Method of the static nested class
public void display() {
// Access static member of the outer class
System.out.println("Accessing from
StaticNestedClass: " + staticMember);
}
}
public static void main(String[] args) {
// Instantiate the static nested class
StaticNestedClass nestedClass = new
StaticNestedClass();
nestedClass.display();
}
}

Static Nested Class vs. Inner Class(Non-static):

Static Nested Class:


● Declared with the static keyword.
● Does not have access to the instance members of the outer class.
● Can be instantiated without an instance of the outer class.

Inner Class (Non-static Nested Class):


● Does not use the static keyword.
● Has access to all members (both static and non-static) of the outer
class.
● Requires an instance of the outer class to be instantiated.

Example:

// Outer class
public class OuterClass {
private String instanceMember = "Outer instance
member";

// Inner class
public class InnerClass {
public void display() {
// Access instance member of the outer class
System.out.println("Accessing from InnerClass:
" + instanceMember);
}
}

public static void main(String[] args) {


// Create an instance of the outer class
OuterClass outer = new OuterClass();

// Create an instance of the inner class


InnerClass inner = outer.new InnerClass();
inner.display();
}
}
Anonymous nested class: A nested class that doesn't have any name is
known as an anonymous class.

An anonymous class must be defined inside another class. Hence, it is also


known as an anonymous inner class. Its syntax is:

class outerClass {

// defining anonymous class


object1 = new Type(parameterList) {
// body of the anonymous class
};
}

Example:
class Polygon {
public void display() {
System.out.println("Inside the Polygon class");
}
}

class AnonymousDemo {
public void createClass() {

// creation of anonymous class extending class


Polygon
Polygon p1 = new Polygon() {
public void display() {
System.out.println("Inside an anonymous
class.");
}
};
p1.display();
}
}

class Main {
public static void main(String[] args) {
AnonymousDemo an = new AnonymousDemo();
an.createClass();
}
}

Exercise1: You are required to implement a simple


program for managing vehicles. Create a base class
Vehicle with the following attributes:
make (String) - representing the make of the vehicle
model (String) - representing the model of the vehicle
year (int) - representing the manufacturing year of the
vehicle

Implement a parameterized constructor in the Vehicle


class that initializes these attributes. Also, provide
a method named displayDetails in the Vehicle class that
displays the details of the vehicle.

Now, create a derived class Car that inherits from the


Vehicle class. The Car class should have an additional
attribute:

numDoors (int) - representing the number of doors of


the car Implement a parameterized constructor in the
Car class that initializes both the attributes of the
base class (make, model, year) and the additional
attribute (numDoors). Override the displayDetails
method in the Car class to include information about
the number of doors.

In the main method of the program, create an object of


the Car class, take user input for the make, model,
year, and number of doors, and display the details
using the displayDetails method of the Car class.

Exercise2: Develop a program for managing various


shapes in a geometric application. Implement an
abstract class Shape with the following attributes and
methods:
Attributes: shapeName (String) - representing the name
of the shape. color (String) - representing the color
of the shape.

Methods: abstract double calculateArea() - to be


implemented by the derived classes for calculating the
area of the shape. void displayDetails() - to display
the details of the shape, including its name, color,
and area. Derive two classes, Circle and Rectangle,
from the Shape class.

Circle Class:

Include an additional attribute radius (double) for


representing the radius of the circle. Implement the
calculateArea method to calculate the area of the
circle using the formula: area = π * radius * radius.
Override the displayDetails method to include
information about the radius.

Rectangle Class:

Include additional attributes length and width (both


double) for representing the length and width of the
rectangle. Implement the calculateArea method to
calculate the area of the rectangle using the formula:
area = length * width. Override the displayDetails
method to include information about the length and
width.

In the main method of the program, create objects of


the Circle and Rectangle classes, take user input for
shape details (name, color, and specific dimensions),
and display the details of each shape.

Exercise3: Develop a program to manage a zoo that


houses different types of animals. Implement an
interface named Animal with the following methods:

void eat() - representing the eating behavior of the


animal. void makeSound() - representing the sound the
animal makes.

Now, create two default interfaces, Swim and Fly, with


the following methods:

void swim() - representing swimming behavior. void


fly() - representing flying behavior.

The methods should be implemented inside the interface


only as they are default

Create classes for different types of animals, ensuring


that they implement the Animal interface. Additionally,
some animals may implement the Swim or Fly interfaces
based on their characteristics.

Fish Class:

Implement the Animal and Swim interfaces. Include an


additional method breatheUnderwater() to represent the
characteristic of breathing underwater.

Bird Class:
Implement the Animal and Fly interfaces. Include an
additional method layEggs() to represent the
characteristic of laying eggs.

In the main method of the program, create objects of


different animal classes, call their respective
methods, and demonstrate their behaviors. Ensure that
the program showcases the usage of interfaces, their
implementation in classes, and multiple inheritance
using interfaces.

Take Home Questions...

Q1)Event Handling Application

Develop an Event Handling Application that includes the


following:

● Abstract Class Event:


○ Fields: eventName (String), eventDate (String)
○ Abstract Method: double calculateCost()
○ Method: void printEventDetails() to print event
name and date.
● Class Conference extends Event:
○ Fields: numAttendees (int), costPerAttendee
(double)
○ Implement calculateCost() to return
numAttendees * costPerAttendee
○ Implement printEventDetails() to include number
of attendees and total cost.
● Class Wedding extends Event:
○ Fields: numGuests (int), venueCost (double)
○ Implement calculateCost() to return numGuests *
50 + venueCost
○ Implement printEventDetails() to include number
of guests and total cost.
● Interface Caterable:
○ Method: void setMenu(String menu)
○ Method: String getMenu()
○ Method: double calculateCateringCost()
● Class CateredConference extends Conference and
implements Caterable:
○ Field: menu (String), cateringCostPerPerson
(double)
○ Implement setMenu() and getMenu()
○ Implement calculateCateringCost() to return
numAttendees * cateringCostPerPerson

In the main method:

● Create instances of Conference, Wedding, and


CateredConference.
● Set the menu and print the catering cost for
CateredConference.
● Print the details and costs for all events.

Let’s grill more...

Q2) Library Management System

Problem-Statement: Develop a Library Management System


using Object-Oriented Programming (OOP) concepts such
as interfaces, abstract classes, and nested classes.
The system will manage different types of library
items, including books, magazines, and multimedia
items, and implement borrowing functionalities and
borrowing history tracking.

Requirements:

1.LibraryItem Hierarchy:
○ Create an abstract class LibraryItem that
represents a general library item. It should
contain common attributes like title and year,
and an abstract method displayInfo() for
displaying item-specific details.
2.Book Class:
○ Extend LibraryItem to create a Book class that
includes additional attributes like author,
borrowed (boolean), and borrower (String).
○ Implement the Borrowable interface with methods
borrowItem(), returnItem(), and isBorrowed() to
handle the borrowing functionality.
○ Add logic to apply penalties for late returns.
3.Magazine Class:
○ Extend LibraryItem to create a Magazine class
with an additional attribute issueNumber.
○ Implement the displayInfo() method to showcase
magazine-specific details.
4.Multimedia Items (DVD Class):
○ Extend LibraryItem to create a DVD class,
adding attributes like duration (in minutes).
○ Implement the Borrowable interface to manage
borrowing functionality with specific rules for
multimedia items.
5.Borrowing History Tracking:
○ Inside LibraryItem, create a nested class
BorrowingHistory to track borrowing and return
events. Include details such as borrower name,
borrowing date, and return date.
○ Ensure the borrowing history can be displayed
alongside other item information.
6.Library Management:
○ Create a Library class that maintains a list of
all LibraryItem objects.
○ Implement methods to add, remove, and display
all library items.
○ Include basic search functionality to find
items by title.
7.Librarian Class:
○ Implement a nested Librarian class within
Library to manage library operations, including
adding/removing items and handling
borrowing/returning processes.
8.Main Class:
○ Instantiate LibraryItem objects (Books,
Magazines, DVDs) in the Main class and add them
to the library.
○ Demonstrate borrowing and returning items,
including the application of late return
penalties.
○ Utilize the search functionality to find and
display items based on specific criteria.
○ Ensure the complete history and current status
of all items are printed.
By the end of this question you will have implemented a
functional Library Management System that encapsulates
core OOP concepts. And have gained practical experience
in using interfaces, abstract classes, nested classes,
and handling complex data operations in Java

*******(Great Going. . .)*******

You might also like