0

[Java Backend Zero to Hello] BÀI 1.8: ABSTRACT CLASS & INTERFACE

Java Backend Zero to Hello

📚 Bài viết thuộc series Java Backend Zero to Hello 📌 Phần: Phase 1: Java Core Cơ Bản | Bài 10/86


BÀI 1.8: ABSTRACT CLASS & INTERFACE

Mục tiêu

  • Phân biệt Abstract Class và Interface
  • Sử dụng interface trong thiết kế
  • Nắm các tính năng mới: default method, static method, functional interface
  • Áp dụng đa kế thừa với interface

1. ABSTRACT CLASS (LỚP TRỪU TƯỢNG)

1.1 Khai báo

public abstract class Animal {
    // Field
    protected String name;

    // Constructor
    public Animal(String name) {
        this.name = name;
    }

    // Abstract method (không có thân)
    public abstract void makeSound();

    // Method thường
    public void sleep() {
        System.out.println(name + " đang ngủ");
    }

    // Static method
    public static void info() {
        System.out.println("Đây là class Animal");
    }
}

1.2 Đặc điểm

  • Khai báo với từ khóa abstract
  • Không thể tạo object: new Animal() ❌
  • Có thể có abstract method và method thường
  • Có thể có field, constructor
  • Class con bắt buộc override abstract method (hoặc cũng khai báo abstract)

1.3 Sử dụng

public class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println("Gâu gâu!");
    }
}

Animal animal = new Dog("Buddy");
animal.makeSound();  // Gâu gâu!
animal.sleep();      // Buddy đang ngủ

2. INTERFACE (GIAO DIỆN)

2.1 Khai báo cơ bản

public interface Drawable {
    // Mặc định là public abstract
    void draw();

    // Hằng số (mặc định là public static final)
    double MAX_SIZE = 100.0;
}

2.2 Class triển khai interface

public class Circle implements Drawable {
    @Override
    public void draw() {
        System.out.println("Vẽ hình tròn");
    }
}

2.3 Đặc điểm Interface (truyền thống)

  • Tất cả method mặc định là public abstract
  • Tất cả field mặc định là public static final
  • Class triển khai dùng implements
  • Một class có thể implement nhiều interface

3. INTERFACE NÂNG CAO (Java 8+)

3.1 Default Method

public interface Vehicle {
    void start();

    // Default method - có thân
    default void honk() {
        System.out.println("Bíp bíp!");
    }

    default void stop() {
        System.out.println("Dừng xe");
    }
}

public class Car implements Vehicle {
    @Override
    public void start() {
        System.out.println("Khởi động xe");
    }
    // honk() và stop() đã có sẵn
}

Car car = new Car();
car.start();  // Khởi động xe
car.honk();   // Bíp bíp!

3.2 Static Method

public interface MathConstants {
    static double PI() {
        return 3.14159;
    }
}

// Gọi
double pi = MathConstants.PI();

3.3 Private Method (Java 9+)

public interface Logger {
    default void logInfo(String msg) {
        log("INFO", msg);
    }

    default void logError(String msg) {
        log("ERROR", msg);
    }

    // Private method - dùng chung cho default methods
    private void log(String level, String msg) {
        System.out.println("[" + level + "] " + msg);
    }
}

4. ĐA KẾ THỪA VỚI INTERFACE

Java không hỗ trợ đa kế thừa class, nhưng interface thì có.

public interface Flyable {
    void fly();
}

public interface Swimmable {
    void swim();
}

public interface Walkable {
    void walk();
}

public class Duck implements Flyable, Swimmable, Walkable {
    @Override
    public void fly() {
        System.out.println("Vịt bay");
    }

    @Override
    public void swim() {
        System.out.println("Vịt bơi");
    }

    @Override
    public void walk() {
        System.out.println("Vịt đi");
    }
}

Giải quyết xung đột khi đa kế thừa

public interface A {
    default void hello() {
        System.out.println("Hello from A");
    }
}

public interface B {
    default void hello() {
        System.out.println("Hello from B");
    }
}

public class C implements A, B {
    // Phải override để giải quyết xung đột
    @Override
    public void hello() {
        A.super.hello();  // Chọn A
        // hoặc B.super.hello();
    }
}

5. INTERFACE KẾ THỪA INTERFACE

public interface Animal {
    void eat();
}

public interface Mammal extends Animal {
    void giveBirth();
}

public class Dog implements Mammal {
    @Override
    public void eat() {
        System.out.println("Ăn");
    }

    @Override
    public void giveBirth() {
        System.out.println("Sinh con");
    }
}

6. FUNCTIONAL INTERFACE

Interface chỉ có đúng 1 abstract method (có thể có nhiều default/static).

@FunctionalInterface  // Annotation - kiểm tra
public interface Calculator {
    int calculate(int a, int b);

    // Có thể có default method
    default void info() {
        System.out.println("Calculator");
    }
}

Các Functional Interface phổ biến trong Java

Interface Method Mô tả
Runnable run() Không tham số, không trả về
Callable<T> call() Không tham số, trả về T
Supplier<T> get() Không tham số, trả về T
Consumer<T> accept(T) Có tham số, không trả về
Function<T,R> apply(T) Có tham số T, trả về R
Predicate<T> test(T) Có tham số, trả về boolean
BiFunction<T,U,R> apply(T,U) 2 tham số, trả về R
// Sử dụng với Lambda (sẽ học ở Phase 2)
Runnable r = () -> System.out.println("Hello");
Consumer<String> c = s -> System.out.println(s);
Function<Integer, String> f = n -> "Number: " + n;
Predicate<Integer> p = n -> n > 0;

7. SO SÁNH ABSTRACT CLASS vs INTERFACE

Tiêu chí Abstract Class Interface
Từ khóa abstract class interface
Kế thừa extends (1 class) implements (nhiều interface)
Method Abstract + thường Abstract + default + static
Field Mọi loại public static final
Constructor Có Không
Access modifier Mọi loại public (mặc định)
Khi nào dùng Code chung + có state Hành vi chung, đa kế thừa

Khi nào dùng cái nào?

  • Abstract Class: Khi các class con có quan hệ "is-a" rõ ràng và chia sẻ code/state chung
  • Interface: Khi muốn định nghĩa hành vi mà nhiều class không liên quan có thể có

8. SEALED CLASS (Java 17+)

Giới hạn class nào được kế thừa.

public sealed class Shape
    permits Circle, Rectangle, Triangle {

    public abstract double area();
}

public final class Circle extends Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
}

public final class Rectangle extends Shape {
    private double width, height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    public double area() {
        return width * height;
    }
}

Các từ khóa cho class con:

  • final - Không cho kế thừa tiếp
  • sealed - Cho phép kế thừa có giới hạn
  • non-sealed - Cho phép kế thừa tự do

9. BÀI TẬP THỰC HÀNH

Bài 1: Hệ thống thanh toán

public interface PaymentMethod {
    boolean pay(double amount);
    String getMethodName();
}

public class CreditCard implements PaymentMethod {
    private String cardNumber;

    @Override
    public boolean pay(double amount) {
        System.out.println("Thanh toán " + amount + " qua thẻ tín dụng");
        return true;
    }

    @Override
    public String getMethodName() {
        return "Credit Card";
    }
}

public class Momo implements PaymentMethod {
    private String phone;

    @Override
    public boolean pay(double amount) {
        System.out.println("Thanh toán " + amount + " qua MoMo");
        return true;
    }

    @Override
    public String getMethodName() {
        return "MoMo";
    }
}

Bài 2: Hệ thống nhân viên với nhiều vai trò

public interface Workable {
    void work();
}

public interface Eatable {
    void eat();
}

public interface Sleepable {
    void sleep();
}

public class Human implements Workable, Eatable, Sleepable {
    @Override
    public void work() { System.out.println("Làm việc"); }

    @Override
    public void eat() { System.out.println("Ăn"); }

    @Override
    public void sleep() { System.out.println("Ngủ"); }
}

public class Robot implements Workable {
    @Override
    public void work() { System.out.println("Làm việc tự động"); }
}

Bài 3: Repository pattern với interface

public interface Repository<T, ID> {
    T findById(ID id);
    List<T> findAll();
    T save(T entity);
    void deleteById(ID id);
}

public class UserRepository implements Repository<User, Long> {
    @Override
    public User findById(Long id) { /* ... */ return null; }

    @Override
    public List<User> findAll() { /* ... */ return null; }

    @Override
    public User save(User entity) { /* ... */ return null; }

    @Override
    public void deleteById(Long id) { /* ... */ }
}

10. TÓM TẮT

Khái niệm Điểm chính
Abstract class Có abstract method, không tạo object trực tiếp
Interface Hợp đồng hành vi, đa kế thừa
Default method Interface có method có thân (Java 8+)
Functional interface 1 abstract method, dùng với Lambda
Sealed class Giới hạn class con (Java 17+)

Bài tiếp theo: 1.9 Xử lý ngoại lệ (Exception)


🧭 Điều Hướng Series

⬅️ Bài trước: BÀI 1.7: 4 TÍNH CHẤT CỦA OOP

📋 Lộ trình tổng quan: Xem Toàn Bộ Series

➡️ Bài tiếp theo: BÀI 1.9: XỬ LÝ NGOẠI LỆ (EXCEPTION HANDLING)


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí