← Java EnglishChapter 09 of 13

Interfaces and Abstract Classes

## Learning Objectives - Understand abstract classes - Create and implement interfaces - Know when to use each - Master default and static interface methods ## Abstract Classes ### Cannot Be Instantiated ```java public abstract class Shape { String color; public abstract double area(); // Abstract method public void display() { // Concrete method System.out.println("Color: " + color); } } ``` ### Concrete Subclass ```java public class Circle extends Shape { double radius; public Circle(String color, double radius) { this.color = color; this.radius = radius; } @Override public double area() { return Math.PI * radius * radius; } } ``` ### Usage ```java // Shape s = new Shape(); // Error - can't instantiate Shape s = new Circle("Red", 5.0); System.out.println(s.area()); // 78.54... ``` ## Abstract Methods ### No Implementation ```java public abstract class Animal { public abstract void makeSound(); // Must be implemented } ``` ### Implementation Required ```java public class Dog extends Animal { @Override public void makeSound() { System.out.println("Woof!"); } } public class Cat extends Animal { @Override public void makeSound() { System.out.println("Meow!"); } } ``` ## Interfaces ### Reference: Contract ```java public interface Drawable { void draw(); // Abstract by default } ``` ### Implementation: Classes ```java public class Circle implements Drawable { @Override public void draw() { System.out.println("Drawing circle"); } } public class Rectangle implements Drawable { @Override public void draw() { System.out.println("Drawing rectangle"); } } ``` ### Interface Usage ```java Drawable d = new Circle(); d.draw(); // Drawing circle d = new Rectangle(); d.draw(); // Drawing rectangle ``` ## Interface vs Abstract Class | Feature | Abstract Class | Interface | |---------|----------------|----------| | Fields | Any type | Constants only | | Methods | Any | Default, static, abstract | | Constructors | Yes | No | | Multiple inheritance | No | Yes (multiple interfaces) | | Access modifiers | Any | public (implicit) | ## Default Methods (Java 8+) ### Provide Implementation ```java public interface Drawable { void draw(); default void print() { System.out.println("Printing..."); } } ``` ### Why Default? Backward compatibility: ```java public interface Drawable { void draw(); // New method with default implementation default void print() { System.out.println("Default print"); } } // Existing classes don't break - they inherit default ``` ## Static Methods in Interfaces ```java public interface MathUtil { static int add(int a, int b) { return a + b; } static double circleArea(double radius) { return Math.PI * radius * radius; } } // Called like: MathUtil.add(5, 3) ``` ## Multiple Interfaces ### Class Implements Multiple ```java public interface Printable { void print(); } public interface Drawable { void draw(); } public class Document implements Printable, Drawable { @Override public void print() { System.out.println("Printing document"); } @Override public void draw() { System.out.println("Drawing document"); } } ``` ### Interface Extends Interface ```java public interface Readable extends Printable { void read(); } // Class implementing Readable must implement // both read() (from Readable) and print() (from Printable) ``` ## Interface Fields ### Always Constants ```java public interface Constants { int MAX_SIZE = 100; // public static final String DEFAULT_NAME = "Unknown"; // public static final } // Usage int size = Constants.MAX_SIZE; ``` ## Functional Interfaces ### Single Abstract Method ```java @FunctionalInterface public interface Comparator { int compare(T o1, T o2); // equals() is already implemented (from Object) } ``` ### Lambda Expressions ```java import java.util.Arrays; import java.util.Comparator; String[] names = {"Charlie", "Alice", "Bob"}; Arrays.sort(names, (a, b) -> a.compareTo(b)); // or Arrays.sort(names, Comparator.naturalOrder()); ``` ## Polymorphism with Interfaces ```java public interface Shape { double area(); } public class Circle implements Shape { double radius; @Override public double area() { return Math.PI * radius * radius; } } public class Rectangle implements Shape { double width, height; @Override public double area() { return width * height; } } public static double totalArea(Shape[] shapes) { double total = 0; for (Shape s : shapes) { total += s.area(); } return total; } ``` ## Private Methods (Java 9+) ### Code Reuse in Interfaces ```java public interface DataProcessor { default void process(String data) { String cleaned = clean(data); validate(cleaned); save(cleaned); } private String clean(String data) { return data.trim().toLowerCase(); } private void validate(String data) { if (data.isEmpty()) { throw new IllegalArgumentException("Empty data"); } } private void save(String data) { // save implementation } } ``` ## Summary - Abstract classes: partial implementation, single inheritance - Interfaces: contract only (historically), multiple inheritance - `abstract class Shape` - use when related classes share state - `interface Drawable` - use when unrelated classes share behavior - Default methods provide backwards compatibility - Interfaces support multiple inheritance - Functional interfaces can use lambda expressions

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →