Discussion

Abstract classes & Interfaces

Abstract Classes: The "Incomplete" Blueprint

1. It's an Idea, Not a Thing:
You can have a Vehicle concept, but you can only drive a Real Car. You cannot "new up" an abstract class.

2. The "Must-Do" List:
Abstract methods are promises. They say: "I don't know HOW this works yet, but any child class MUST figure it out."

3. Shared DNA:
It can still hold common traits (like a color or fuelLevel) so you don't have to rewrite them for every child.


// The Template
public abstract class Vehicle {
    
    // Shared behavior (All vehicles do this the same)
    public void honk() {
        System.out.println("Beep!");
    }

    // The Requirement (Every vehicle does this differently!)
    public abstract void move(); 
}

// The Real Version
public class Car extends Vehicle {
    public void move() {
        System.out.println("Driving on four wheels");
    }
}
            

Why can't we create the object of an abstract class?

  • Abstract class is incomplete
  • It is the process of showing essential details and hiding the implementation
  • There would be no actual implementation of the method to invoke

                    
                        public class AbstractClass  {
                            public void main(String[] args) {
                                Student IS247=new Student();
                            }
                            public abstract class  Student{
                            }
                        }
                        
                       

Understanding Abstract Class

  • Imagine you are designing a program for different animals.
  • All animals make a sound, but the exact sound depends on the animal.

                        

Challenge

  • Modify the previous code to add more animals.
  • Create a Cat class that extends the Animal class and implements the makeSound() method to print "Meow! Meow!"..

                         // Cat class implementing makeSound()
                            class Cat extends Animal {
                                void makeSound() {
                                    System.out.println("Meow! Meow!");
                                }
                            }

                        

The Interface: A "Social Contract"

1. A 100% Empty Template:
Unlike abstract classes, interfaces usually have no code at all—only a list of "promises" (methods).

2. The "All or Nothing" Rule:
If a class signs the contract (implements), it must provide code for every single method listed.

3. Multiple Superpowers:
In Java, a class can only have one parent (class), but it can sign many contracts (interfaces).
e.g., A SmartPhone is a Phone, but it also implements 'Camera', 'GPS', and 'MusicPlayer'.


interface PowerSwitch {
    void turnOn();  // No body, just a promise
}

// Marketing signs the 'Revenue' contract
class Marketing implements Revenue, PowerSwitch {
    public void turnOn() {
        System.out.println("Lights on in Marketing!");
    }
}
            
"Interfaces define behavior (what it can do), not identity (what it is)."

Demo Interface


                           

                        

Demo Abstract Class and Interface

Github code sample Abstract/Interface


                        

challenge


                           
  • Implement the makeSound() method to print "Meow! Meow!"
  • In the Main class, create both Dog and Cat objects and call their makeSound() method.

                         class Cat implements Animal {
                            public void makeSound() {
                                System.out.println("Meow! Meow!");
                            }
                        }
                       
                    
                        
                       

Example Abstract

Github code sample Abstract


                        

Demo Interface

Github code sample Interface


                        

Abstract VS Interface

source:media.geeksforgeeks.org


                    abstract class Shape{}
                    class Circle extends Shape{} 
                                    
                    

                    interface Shape{} 
                    class Circle implements Shape{}
                                    
                    

Abstract Classes VS Interfaces

Feature Abstract Class Interface
DefinitionA class that can have both abstract and concrete methods.A blueprint that only contains abstract methods (until Java 8, which introduced default methods).
Method ImplementationCan have both abstract and fully implemented methods.Only abstract methods (default and static methods were added in Java 8).
VariablesCan have instance variables (fields) with any access modifier.Only public, static, and final variables are allowed.
Access ModifiersMethods can be public, protected, or private.Methods are public by default.
Multiple InheritanceA class can extend only one abstract class.A class can implement multiple interfaces.
ConstructorsCan have constructors.Cannot have constructors.
Use CaseUsed when classes share behavior but also need customization.Used for defining contracts that multiple unrelated classes must follow.

Abstraction

  • Way to arrange the code
  • Suppresses details
  • Interface over Abstract Classes
  • Both abstract class and interface helps in polymorphism

When to choose an Abstract Class?

1. Shared Identity (DNA):
Use it when classes are closely related.
Example: A Person class sharing name, dob, and gender with Student and Employee.

2. The "Semi-Finished" Product:
Use it when you want to provide some working code but leave the rest for the children to finish.

3. Privacy Matters:
Unlike Interfaces, Abstract classes allow private and protected data. This is Encapsulation—keeping the internal "guts" of the family business safe.

The Template Rule

"If you can say 'Subclass IS A Parent' and they share actual attributes (not just behaviors), go Abstract."



// --- THE IDENTITY (Abstract Class) ---
// Use this for "Shared DNA"
abstract class Animal {
    String name;

    Animal(String name) { this.name = name; }

    // All animals breathe the same way (Implemented)
    void breathe() {
        System.out.println(name + " takes a breath...");
    }

    // Every animal makes a different sound (Abstract)
    abstract void makeNoise();
}

// --- THE SKILLSETS (Interfaces) ---
// Use these for "Extra Abilities"
interface Pet {
    void play(); // Only some animals are pets
}

interface Flyable {
    void fly();  // Only some animals fly
}

// --- THE CONCRETE REALITY ---

// A Dog IS-AN Animal and CAN-BE a Pet
class Dog extends Animal implements Pet {
    Dog(String name) { super(name); }

    @Override
    void makeNoise() { System.out.println("Woof!"); }

    @Override
    public void play() { System.out.println(name + " fetches the ball."); }
}

// An Eagle IS-AN Animal and CAN-FLY
class Eagle extends Animal implements Flyable {
    Eagle(String name) { super(name); }

    @Override
    void makeNoise() { System.out.println("Screech!"); }

    @Override
    public void fly() { System.out.println(name + " soars through the clouds."); }
}
            

Consider Using Interface

  • You want to specify the behavior of a particular data type, but not concerned about who implements its behavior
  • Use an interface when a role needs to be defined for other classes, regardless of the inheritance tree of these classes
  • You want to take advantage of multiple inheritance of type

Demo Abstract Class

Github code sample Abstract

                        
                        

Built in Interface

  • Interface Comparable
  • This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class's natural ordering, and the class's compareTo method is referred to as its natural comparison method
  • Any class can implement Comparable to provide a mechanism for comparing objects of that type
  • Java docs Comparable Interface
  • Github code CompareableBuiltInInterface.java

Open-Closed Principle (OCP)

  • The Open-Closed Principle (OCP)
  • Classes should be open for extension but closed for modification.
  • Open for Extension: Add new behavior by deriving from a base class and overriding methods.
  • Closed for Modification: Keep existing code unchanged to avoid introducing new bugs in the base class.
  • Allow clients to interact with your code through interfaces rather than specific implementations.
  • GitHub code sample: OCP Example

OCP Problem Challenge


                    
  • What’s Wrong?
  • Every time a new medium (e.g., WhatsApp, Twitter, Instagram) is added, we need to modify the sendOTP method.
  • This violates OCP because we are modifying the existing class instead of extending it.

OCP Solution


                    
  • Challenge
  • Extend the functionality: Create a new class for SMSNotification.
source Notebook LLM

Liskov Substitution Principle(LSP) Problem

  • Objects of a superclass should be replaceable with objects of its subclasses without breaking the application.
  • A subclass should be able to substitute its superclass without breaking functionality.
  • If you have a class A and a subclass B, you should be able to pass an instance of B into any method that expects an A, and the program should still behave correctly.
  • Github code sample LSP
                    
                    
  • What’s Wrong?
  • The Penguin class overrides fly() but throws an exception because penguins cannot fly.
  • This means the subclass does not behave like its superclass, breaking the principle..

Liskov Substitution Principle(LSP) Solution


                    
  • Challenge
  • 🛠️ Your Task: 1️⃣ Create a new class Ostrich that follows LSP correctly. 2️⃣ Ensure Ostrich does not implement fly() since it can't fly. 3️⃣ Test your solution by creating an Ostrich object and calling its eat() method.

Interface Segregation Principle (ISP)

  • A class should not be forced to implement interfaces it does not use.
  • The interfaces should split into smaller one
  • Do not force the client to use the methods that they do not want to use
  • Github code sample ISP

                    

    What is wrong?

  • Cash Payments don’t need payByCard(), payByMobile(), or payByQR().
  • Card Payments don’t need payCash().
  • Some payment types may not offer Cashback.
  • A class like "OnlinePayment" would be forced to implement payCash(), which makes no sense.

Interface Segregation Principle Solution


                    
  • Challenge
  • 🛠️ Your Task: Create a new interface for crypto payments. Implement a CryptoPayment class that follows ISP. Ensure that the CryptoPayment class is not forced to implement unnecessary methods like payCash() or payByCard(). Modify the main method to test crypto payments along with other payment methods.

Interface Segregation Principle Challenge Solution


                    

Thank you