[Java Backend Zero to Hello] BÀI 1.8: ABSTRACT CLASS & INTERFACE
📚 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ếpsealed- Cho phép kế thừa có giới hạnnon-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