polymorphism
polymorphism
class BaseClass {
void Display() {
System.out.println("\nThis is Display() method of BaseClass");
}
void Show() {
System.out.println("\nThis is Show() method of BaseClass");
}
}
class B extends A
{
// overriding m1()
void m1()
{
System.out.println("Inside B's m1 method");
}
}
class C extends A
{
// overriding m1()
void m1()
{
System.out.println("Inside C's m1 method");
}
}
// Driver class
class Dispatch
{
public static void main(String args[])
{
// object of type A
A a = new A();
// object of type B
B b = new B();
// object of type C
C c = new C();
ref = a;
Output:
class Shape {
protected int width, height;
}
}
// Classify Category
Shape shape = rec;
shape.area(); // Calls Rectangle's area() function
shape = tri;
shape.area(); // Calls Triangle's area() function
}
}
Output: (Also Analyze the Code and Explain in which category it falls Late or Early Binding)
Task 1: Create a Java program that demonstrates function overriding. Define a base class called
"Animal" with a virtual function makeSound(). Create two derived classes from "Animal"
called "Dog" and "Cat".In each derived class, override the makeSound() function to provide a
different sound. For example, the Dog class may make a barking sound, and the Cat class may
make a meowing sound. In the main function, create objects of both the "Dog" and "Cat"
classes and call the makeSound() function for each object.
class Animal {
public void makeSound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Dog barks");
}
}
Output:
Task 2: Write a Java program that demonstrates dynamic method dispatch using hierarchical
inheritance in a simple banking system.
a. Create a superclass Account with properties accountNumber and balance, and methods
deposit(double amount), withdraw(double amount), and displayAccountDetails().
b. The deposit method should add the specified amount to the balance.
c. The withdraw method should deduct the specified amount from the balance if sufficient
funds are available.
d. The displayAccountDetails method should display the account type, account number, and
current balance.
e. Implement two subclasses: SavingsAccount and CheckingAccount, which inherit from
Account.
f. SavingsAccount should have an additional property interestRate and override the
withdraw method to apply a penalty fee if the withdrawal amount exceeds the balance.
g. CheckingAccount should have an additional property overdraftLimit and override the
withdraw method to allow overdrafts up to a certain limit.
h. In the Dispatch class (the driver class): Create objects of type Account, SavingsAccount,
and CheckingAccount. Demonstrate dynamic method dispatch by calling the
displayAccountDetails() method through a reference of type Account.
class Account {
protected int accountNumber;
protected double balance;
public void deposit(double amount){
balance=balance + amount;
}
public Account(int accountNumber, double balance) {
this.accountNumber = accountNumber;
this.balance = balance;
}
public void withdraw(double amount){
if (balance>=amount){
balance=balance-amount;
System.out.println("Withdraw successful!!");
}
else{
System.out.println("Insufficient funds");
}
}
@Override
public void displayAccountDetails() {
System.out.println("Account Type: Savings Account");
System.out.println("Account Number: " + accountNumber);
System.out.println("Balance: " + balance);
System.out.println("Interest Rate: " + interestRate);
}
}
class CheckingAccount extends Account {
private double overdraftLimit;
@Override
public void withdraw(double amount) {
if (balance + overdraftLimit >= amount) {
balance = balance + amount;
System.out.println("Withdraw successful");
} else {
@Override
public void displayAccountDetails() {
System.out.println("Account Type: Checking Account");
System.out.println("Account Number: " + accountNumber);
System.out.println("Balance: " + balance);
System.out.println("Overdraft Limit: " + overdraftLimit);
}
}
A.withdraw(4000);
A.deposit(2000);
A.displayAccountDetails();
System.out.println();
SA.withdraw(4000);
SA.deposit(2000);
SA.displayAccountDetails();
System.out.println();
CA.withdraw(4000);
CA.deposit(2000);
CA.displayAccountDetails();
}
}
Output:
Task 3: Design a superclass Device with a non-static method turnOn() that prints "Device
turned on" and a static method getManufacturer() that returns "Unknown Manufacturer".
Implement a subclass Television that extends Device. Override the turnOn() and
getManufacturer() method in Television. In the Main class, demonstrate the usage of both
methods by creating instances of Device and Television and invoking the appropriate methods.
Discuss the concept of method hiding and observe its effect in this scenario
class Device{
public void turnOn(){
System.out.println("Device turned on");
}
public static String getManufacturer(){
return "Unknown Manufacturer";
}
}
class Television extends Device{
@Override
public void turnOn(){
System.out.println("Television turned on");
}
d1.turnOn();
t1.turnOn();
System.out.println(Device.getManufacturer());
System.out.println(Television.getManufacturer());
Device dt1 = new Television();
dt1.turnOn();
}
}
Output:
Task 4: Consider a superclass Vehicle with a method drive() that prints "Driving a vehicle".
Implement two subclasses: Car and Motorcycle, both of which extend Vehicle. Override the
drive() method in both subclasses to print "Driving a car" and "Driving a motorcycle"
respectively. In the Main class, create objects of type Car and Motorcycle, assign them to
Vehicle references, and call the drive() method. Discuss whether early binding or late binding
occurs in this scenario, and why.
class Vehicle{
public void drive(){
System.out.println("Driving a vehicle");
}
}
car.drive();
motorcycle.drive();
}
}
Output: