Advanced OOP Concepts
Course: 4343203 - Java Programming
Inheritance allows a class to inherit properties and methods from another class
// Parent class
class Animal {
String name;
int age;
void eat() {
System.out.println("Animal is eating");
}
void sleep() {
System.out.println("Animal is sleeping");
}
}
// Child class
class Dog extends Animal {
String breed;
void bark() {
System.out.println("Dog is barking");
}
}
public class TestInheritance {
public static void main(String[] args) {
Dog dog = new Dog();
// Inherited properties and methods
dog.name = "Buddy";
dog.age = 3;
dog.eat(); // From Animal
dog.sleep(); // From Animal
// Own properties and methods
dog.breed = "Labrador";
dog.bark(); // Own method
}
}
Java supports single inheritance but achieves multiple inheritance through interfaces
class Vehicle {
int speed;
String fuel;
void start() {
System.out.println("Vehicle started");
}
}
class Car extends Vehicle {
int doors;
void accelerate() {
speed += 10;
System.out.println("Car accelerating");
}
}
class Vehicle {
void start() {
System.out.println("Vehicle started");
}
}
class Car extends Vehicle {
void accelerate() {
System.out.println("Car accelerating");
}
}
class SportsCar extends Car {
void turboBoost() {
System.out.println("Turbo activated!");
}
}
class Animal {
void eat() {
System.out.println("Animal eating");
}
}
class Dog extends Animal {
void bark() {
System.out.println("Dog barking");
}
}
class Cat extends Animal {
void meow() {
System.out.println("Cat meowing");
}
}
class Bird extends Animal {
void fly() {
System.out.println("Bird flying");
}
}
super refers to the immediate parent class object
class Animal {
String name = "Animal";
}
class Dog extends Animal {
String name = "Dog";
void printNames() {
System.out.println(name); // Dog
System.out.println(super.name); // Animal
}
}
class Animal {
void eat() {
System.out.println("Animal eating");
}
}
class Dog extends Animal {
void eat() {
super.eat(); // Call parent method
System.out.println("Dog eating bones");
}
}
class Animal {
String name;
int age;
Animal(String name, int age) {
this.name = name;
this.age = age;
}
}
class Dog extends Animal {
String breed;
Dog(String name, int age, String breed) {
super(name, age); // Must be first statement
this.breed = breed;
}
void displayInfo() {
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("Breed: " + breed);
}
}
Important: super() constructor call must be the first statement in child constructor
Method Overriding allows child class to provide specific implementation of parent method
class Animal {
void makeSound() {
System.out.println("Animal makes sound");
}
void move() {
System.out.println("Animal moves");
}
}
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Dog barks: Woof!");
}
@Override
void move() {
System.out.println("Dog runs on four legs");
}
}
class Cat extends Animal {
@Override
void makeSound() {
System.out.println("Cat meows: Meow!");
}
}
public class TestOverriding {
public static void main(String[] args) {
Animal animal1 = new Dog();
Animal animal2 = new Cat();
animal1.makeSound(); // Dog barks: Woof!
animal1.move(); // Dog runs on four legs
animal2.makeSound(); // Cat meows: Meow!
animal2.move(); // Animal moves
}
}
Polymorphism means "many forms" - one interface, multiple implementations
class Calculator {
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
}
class Shape {
void draw() {
System.out.println("Drawing shape");
}
}
class Circle extends Shape {
@Override
void draw() {
System.out.println("Drawing circle");
}
}
class Rectangle extends Shape {
@Override
void draw() {
System.out.println("Drawing rectangle");
}
}
class Employee {
String name;
double salary;
Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
double calculateBonus() {
return salary * 0.1; // 10% bonus
}
void displayInfo() {
System.out.println("Name: " + name + ", Salary: " + salary);
System.out.println("Bonus: " + calculateBonus());
}
}
class Manager extends Employee {
Manager(String name, double salary) {
super(name, salary);
}
@Override
double calculateBonus() {
return salary * 0.2; // 20% bonus for managers
}
}
class Developer extends Employee {
Developer(String name, double salary) {
super(name, salary);
}
@Override
double calculateBonus() {
return salary * 0.15; // 15% bonus for developers
}
}
public class PolymorphismDemo {
public static void main(String[] args) {
Employee[] employees = {
new Employee("John", 50000),
new Manager("Alice", 80000),
new Developer("Bob", 70000)
};
for (Employee emp : employees) {
emp.displayInfo(); // Different bonus calculations
System.out.println();
}
}
}
Dynamic Method Dispatch is the mechanism by which a call to an overridden method is resolved at runtime
class Animal {
void sound() {
System.out.println("Animal sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Woof!");
}
}
class Cat extends Animal {
@Override
void sound() {
System.out.println("Meow!");
}
}
public class DynamicDispatch {
public static void main(String[] args) {
Animal animal;
animal = new Dog();
animal.sound(); // Woof! (Dog's method)
animal = new Cat();
animal.sound(); // Meow! (Cat's method)
// Array of animals
Animal[] animals = {
new Dog(), new Cat(), new Dog()
};
for (Animal a : animals) {
a.sound(); // Different sounds
}
}
}
| Aspect | Method Overloading | Method Overriding |
|---|---|---|
| Definition | Multiple methods with same name, different parameters | Child class redefines parent class method |
| Inheritance | Not required (same class) | Required (parent-child relationship) |
| Method Signature | Different parameters | Same signature |
| Return Type | Can be different | Must be same or covariant |
| Access Modifier | Can be different | Cannot be more restrictive |
| Binding | Compile-time (Static) | Runtime (Dynamic) |
| Polymorphism | Compile-time polymorphism | Runtime polymorphism |
| Performance | Faster (compile-time) | Slower (runtime resolution) |
final keyword prevents inheritance and method overriding
class Animal {
// Cannot be overridden
final void breathe() {
System.out.println("Animal breathing");
}
// Can be overridden
void move() {
System.out.println("Animal moving");
}
}
class Dog extends Animal {
// This would cause compilation error
// void breathe() { } // Error!
@Override
void move() {
System.out.println("Dog running");
}
}
// Cannot be extended
final class String {
// String class implementation
}
// This would cause compilation error
// class MyString extends String { } // Error!
final class Math {
public static final double PI = 3.14159;
public static double sqrt(double a) {
// Implementation
return 0;
}
}
Next: Interfaces and Abstract Classes
Ready to explore Interfaces and Abstract Classes!