Quiz 2

Abstract Classes & Interfaces

1244 words
6 min read
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

# Abstract Classes & Interfaces ## 🎯 Learning Objectives - Define abstract classes and methods - Implement interfaces and understand their role - Use default and static methods in interfaces - Choose between abstract classes and interfaces - Implement `Comparable` and `Comparator` ## 1. Abstract Classes — Partial I...

Abstract Classes & Interfaces

🎯 Learning Objectives

  • Define abstract classes and methods
  • Implement interfaces and understand their role
  • Use default and static methods in interfaces
  • Choose between abstract classes and interfaces
  • Implement Comparable and Comparator

1. Abstract Classes — Partial Implementation

1.1 Intuition

An abstract class is like a partially-built house: it has completed rooms (concrete methods) and empty rooms (abstract methods) that the builder must finish. You cannot move into a partially-built house — you can't instantiate an abstract class.

1.2 Syntax

java
public abstract class Shape {
    protected String color;
    public Shape(String color) { this.color = color; }
    // Concrete method — shared implementation
    public String getColor() { return color; }
    // Abstract method — subclass MUST implement
    public abstract double getArea();
}
public class Circle extends Shape {
    private double radius;
    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }
    @Override
    public double getArea() { return Math.PI * radius * radius; }
}
Key rules:
  • Abstract class: declared with abstract
  • Abstract method: abstract returnType methodName(params); (no body)
  • Any class with an abstract method MUST be declared abstract
  • Subclass must implement all abstract methods, or be declared abstract itself
  • Abstract classes CAN have constructors (called via super())
  • Abstract classes CAN have fields, concrete methods, static methods

1.3 Why Use Abstract Classes?

java
// WITHOUT abstract: forget to implement getArea() — compiles but wrong
// WITH abstract: compiler ENFORCES implementation
public abstract class Shape {
    public abstract double getArea();
}
Abstract classes are contracts — they guarantee that every subclass has certain methods.

2. Interfaces — Pure Contracts

2.1 Intuition

An interface is like a menu at a restaurant. The menu lists what dishes you can order (method signatures), but doesn't tell you how they're cooked. Different restaurants can implement the same menu differently.

2.2 Syntax (Traditional — Java 8 and earlier)

java
public interface Drawable {
    // All methods were implicitly public abstract
    void draw();
    void resize(int factor);
}
// Implementing class
public class Circle implements Drawable {
    @Override
    public void draw() { System.out.println("Drawing circle"); }
    @Override
    public void resize(int factor) { System.out.println("Resizing by " + factor); }
}

2.3 Modern Interfaces (Java 8+)

java
public interface Vehicle {
    // Abstract method (must implement)
    void start();
    // Default method (optional override)
    default void honk() {
        System.out.println("Beep beep!");
    }
    // Static method
    static boolean isValid(Vehicle v) {
        return v != null;
    }
    // Constants (implicitly public static final)
    int MAX_SPEED = 200;
}

2.4 Multiple Interface Implementation

java
public class Car implements Vehicle, Drawable, Comparable<Car> {
    // Must implement ALL abstract methods from ALL interfaces
    @Override
    public void start() { /* ... */ }
    @Override
    public void draw() { /* ... */ }
    @Override
    public int compareTo(Car other) { /* ... */ }
}

2.5 Default Method Conflict Resolution

If two interfaces provide default methods with the same signature:
java
interface A { default void foo() { System.out.println("A"); } }
interface B { default void foo() { System.out.println("B"); } }
class C implements A, B {
    // Must OVERRIDE to resolve conflict
    @Override
    public void foo() {
        A.super.foo();  // Can call specific interface's version
    }
}

3. Abstract Class vs Interface

FeatureAbstract ClassInterface
InstantiationCannot instantiateCannot instantiate
MethodsAbstract + concreteAbstract + default + static
FieldsAny fieldspublic static final only
ConstructorsYesNo
InheritanceSingle (extends)Multiple (implements)
extendsclass B extends Ainterface B extends A
AccessAll access modifiersAll methods public
When to use"Is-a" with shared state"Can-do" capability
Rule of thumb: Use abstract classes for related classes with shared code. Use interfaces for unrelated classes that share capabilities (e.g., both a Duck and a Rocket can be Flyable).

4. Comparable vs Comparator

4.1 Comparable — Natural Ordering

java
public class Student implements Comparable<Student> {
    private int rollNo;
    private String name;
    @Override
    public int compareTo(Student other) {
        return this.rollNo - other.rollNo;  // Ascending by roll number
    }
}
// Usage:
Arrays.sort(students);  // Uses compareTo

4.2 Comparator — Custom Ordering (External)

java
// Ascending by name
Comparator<Student> byName = new Comparator<Student>() {
    @Override
    public int compare(Student a, Student b) {
        return a.getName().compareTo(b.getName());
    }
};
// Lambda (Java 8+):
Comparator<Student> byName = (a, b) -> a.getName().compareTo(b.getName());
// Usage:
Arrays.sort(students, byName);
FeatureComparableComparator
Packagejava.langjava.util
MethodcompareTo(T o)compare(T a, T b)
Called onThe object itselfSeparately
SortingCollections.sort(list)Collections.sort(list, comparator)
Multiple sortsOnly one natural orderMany custom orders

5. Common Pitfalls

Pitfall 1: Abstract Class Mistakenly Instantiated

Shape s = new Shape("red"); — Compile error! Cannot instantiate abstract class.

Pitfall 2: Interface Method Without public

java
interface A { void foo(); }
class B implements A {
    void foo() { }  // ERROR: weaker access (package-private < public)
}
Fix: Interface methods are implicitly public; implementation must be public too.

Pitfall 3: CompareTo Violating Contract

return a - b; — overflow risk! If a = 2,147,483,647 and b = -1, result overflows. Fix: return Integer.compare(a, b);

Pitfall 4: Forgetting @Override for Interface Methods

Without @Override, if you mis-spell the method name (e.g., draw() instead of draw()), you've created a new method, not implemented the interface. The compiler won't warn if the interface method is left unimplemented (error: class must be abstract).

6. Practice Questions

Q1: Can an abstract class have a constructor?
Answer: Yes, abstract classes can have constructors. They are called when a subclass is instantiated (via super()). The constructor initializes the abstract class's fields. Q2: Can you create an interface with only abstract methods? Can you have constants?
Answer: Yes. Before Java 8, all interfaces were purely abstract. Yes, interfaces can have public static final constants (e.g., int MAX = 100;). Q3: What is the output?
java
interface I { void m1(); }
abstract class A { abstract void m2(); }
class C extends A implements I {
    public void m1() { System.out.println("m1"); }
    void m2() { System.out.println("m2"); }
}
Answer: No output (just compiles). Note: m1 must be public (interface requirement), m2 is package-private (OK, A doesn't enforce public). Q4: How do you resolve conflicting default methods?
Answer: Override the method in the implementing class and use InterfaceName.super.methodName() to call specific interface versions. Q5: When would you choose an abstract class over an interface?
Answer: Choose abstract class when classes share state (fields), constructors, or partial implementation. Choose interface when representing a capability that unrelated classes can implement (e.g., Serializable, Comparable, Runnable). Q6: Write a Comparator to sort strings by length.
java
Comparator<String> byLength = (a, b) -> Integer.compare(a.length(), b.length());
// Or: Comparator<String> byLength = Comparator.comparingInt(String::length);
Q7: Can a class implement multiple interfaces with the same default method?
Answer: Yes, but the class must override the conflicting method to resolve the ambiguity. It can delegate to one of the interfaces using InterfaceName.super.methodName(). Q8: Can an abstract class implement an interface without implementing all methods?
Answer: Yes. An abstract class can leave some interface methods unimplemented (they become implicitly abstract).

📐 Key Concepts

ConceptKeywordPurpose
Abstract methodabstractContract without implementation
Abstract classabstract classPartial implementation (can have state)
InterfaceinterfacePure contract (capability)
Default methoddefaultOptional implementation in interface
ComparablecompareTo()Natural ordering
Comparatorcompare()Custom ordering

🔗 Cross-References

Document outline

Keep your place and jump directly to a heading.

Table of Contents
System Normal // Awaiting Context

Intelligence Hub

Navigate the knowledge graph to generate context. The Hub adapts dynamically to surface backlinks, related notes, and metadata insights.