Chuyển tới nội dung chính

📜 Giao Diện - Interfaces

Chào mừng đến với bài học về Interfaces - tiêu chuẩn phục vụ trong Café!

🎯 Món Ăn Hôm Nay

Tưởng tượng bạn đặt tiêu chuẩn cho nhân viên:

  • Tiêu chuẩn Barista → Interface PhaChe
  • Tiêu chuẩn Thu ngân → Interface ThuTien
  • Nhân viên thực hiện → implements interfaces
  • Đa tiêu chuẩn → Một người làm nhiều việc

Đó chính là Interface - hợp đồng phải thực hiện!

📜 Interface Là Gì?

Interface = Hợp đồng (định nghĩa phải làm gì, không nói làm thế nào)

// Định nghĩa interface
public interface PhaChe {
void phaCaPhe(String loai); // Abstract method
void donDepMayPha();
}

// Class implements interface
public class Barista implements PhaChe {
@Override
public void phaCaPhe(String loai) {
System.out.println("☕ Đang pha " + loai);
}

@Override
public void donDepMayPha() {
System.out.println("🧹 Đang dọn dẹp máy pha");
}
}

Ẩn Dụ Café:

  • Interface = Bản mô tả công việc
  • implements = Nhận công việc, cam kết làm
  • Method = Nhiệm vụ phải hoàn thành
  • Đa interface = Một người nhiều vai trò
  • Abstract = Chỉ nói "làm gì", không nói "làm thế nào"

📋 Đặc Điểm Interface

  1. ✅ Tất cả method đều abstract (trước Java 8)
  2. ✅ Tất cả biến đều public static final
  3. ✅ Class có thể implements nhiều interface
  4. ✅ Interface có thể extends nhiều interface
  5. ✅ Không thể tạo object trực tiếp
  6. ✅ Java 8+: default method, static method
public interface TieuChuan {
// Biến: public static final
int GIO_MO_CUA = 7;

// Abstract method: public abstract
void lamViec();

// Default method (Java 8+)
default void nghiGiaiLao() {
System.out.println("☕ Nghỉ 15 phút");
}

// Static method (Java 8+)
static void inQuyDinh() {
System.out.println("📋 Quy định chung");
}
}

👨‍🍳 Câu Chuyện Trong Quán

Tình huống 1: Interface Đơn Giản

// Interface định nghĩa tiêu chuẩn
public interface PhucVu {
void chaoKhach();
void nhanDon();
void mangDoUong();
}

// Class implements interface
public class NhanVienPhucVu implements PhucVu {
private String ten;

public NhanVienPhucVu(String ten) {
this.ten = ten;
}

@Override
public void chaoKhach() {
System.out.println("👋 " + ten + ": Xin chào quý khách!");
}

@Override
public void nhanDon() {
System.out.println("📝 " + ten + ": Cho tôi ghi đơn");
}

@Override
public void mangDoUong() {
System.out.println("☕ " + ten + ": Đồ uống của quý khách đây ạ");
}
}

// Sử dụng
public class TestInterface {
public static void main(String[] args) {
PhucVu nv = new NhanVienPhucVu("Minh");

nv.chaoKhach();
nv.nhanDon();
nv.mangDoUong();
}
}

Output:

👋 Minh: Xin chào quý khách!
📝 Minh: Cho tôi ghi đơn
☕ Minh: Đồ uống của quý khách đây ạ

Tình huống 2: Đa Interface (Multiple Inheritance)

// Interface 1
public interface PhaChe {
void phaCaPhe();
}

// Interface 2
public interface ThuTien {
void tinhTien(int soTien);
}

// Class implements nhiều interface
public class NhanVienDaNang implements PhaChe, ThuTien {
private String ten;

public NhanVienDaNang(String ten) {
this.ten = ten;
}

@Override
public void phaCaPhe() {
System.out.println("☕ " + ten + " pha cà phê");
}

@Override
public void tinhTien(int soTien) {
System.out.printf("💰 %s tính tiền: %,d VND%n", ten, soTien);
}
}

// Sử dụng
public class TestMultiInterface {
public static void main(String[] args) {
NhanVienDaNang nv = new NhanVienDaNang("Lan");

nv.phaCaPhe();
nv.tinhTien(100000);
}
}

Output:

☕ Lan pha cà phê
💰 Lan tính tiền: 100,000 VND

📝 Công Thức Nấu (Code Examples)

Ví Dụ 1: Default Method (Java 8+)

public interface NhanVien {
// Abstract method
void lamViec();

// Default method - có thể override hoặc không
default void diLam() {
System.out.println("🚶 Đi làm lúc 7:00");
}

default void tanLam() {
System.out.println("🏠 Tan làm lúc 17:00");
}
}

public class Barista implements NhanVien {
@Override
public void lamViec() {
System.out.println("☕ Pha cà phê");
}

// Override default method
@Override
public void tanLam() {
System.out.println("🏠 Tan làm lúc 18:00 (ca muộn)");
}

// diLam() không override, dùng default
}

// Sử dụng
public class TestDefault {
public static void main(String[] args) {
Barista b = new Barista();

b.diLam(); // Default method
b.lamViec(); // Override
b.tanLam(); // Override
}
}

Output:

🚶 Đi làm lúc 7:00
☕ Pha cà phê
🏠 Tan làm lúc 18:00 (ca muộn)

Ví Dụ 2: Static Method (Java 8+)

public interface Helper {
static void inQuyDinh() {
System.out.println("📋 QUY ĐỊNH:");
System.out.println(" 1. Đúng giờ");
System.out.println(" 2. Thái độ tốt");
System.out.println(" 3. Vệ sinh sạch sẽ");
}

static int tinhLuong(int ngayCong) {
return ngayCong * 200000;
}
}

// Sử dụng
public class TestStatic {
public static void main(String[] args) {
// Gọi static method qua tên interface
Helper.inQuyDinh();

int luong = Helper.tinhLuong(25);
System.out.printf("%n💵 Lương: %,d VND%n", luong);
}
}

Output:

📋 QUY ĐỊNH:
1. Đúng giờ
2. Thái độ tốt
3. Vệ sinh sạch sẽ

💵 Lương: 5,000,000 VND

Ví Dụ 3: Interface Extends Interface

// Interface cơ bản
public interface NhanVienCoBan {
void diLam();
void tanLam();
}

// Interface mở rộng
public interface NhanVienQuanLy extends NhanVienCoBan {
void phanCongCongViec();
void kiemTraNhanVien();
}

// Class implements
public class QuanLy implements NhanVienQuanLy {
@Override
public void diLam() {
System.out.println("🚶 Quản lý đi làm");
}

@Override
public void tanLam() {
System.out.println("🏠 Quản lý tan làm");
}

@Override
public void phanCongCongViec() {
System.out.println("📋 Phân công công việc");
}

@Override
public void kiemTraNhanVien() {
System.out.println("✅ Kiểm tra nhân viên");
}
}

Ví Dụ 4: Constants Trong Interface

public interface CauHinh {
// public static final (mặc định)
int GIO_MO_CUA = 7;
int GIO_DONG_CUA = 22;
String TEN_QUAN = "Java Café";
double TY_LE_GIAM_GIA_VIP = 0.2;
}

public class QuanCafe implements CauHinh {
public void hienThiGioMoCua() {
System.out.println("🏪 " + TEN_QUAN);
System.out.println("⏰ Mở cửa: " + GIO_MO_CUA + ":00");
System.out.println("🔒 Đóng cửa: " + GIO_DONG_CUA + ":00");
}

public int tinhGiamGiaVIP(int tongTien) {
return (int) (tongTien * TY_LE_GIAM_GIA_VIP);
}
}

// Sử dụng
public class TestConstants {
public static void main(String[] args) {
QuanCafe quan = new QuanCafe();
quan.hienThiGioMoCua();

int giamGia = quan.tinhGiamGiaVIP(100000);
System.out.printf("%n🎁 Giảm giá VIP: %,d VND%n", giamGia);
}
}

Ví Dụ 5: Polymorphism Với Interface

public interface ThanhToan {
void thanhToan(int soTien);
}

public class ThanhToanTienMat implements ThanhToan {
@Override
public void thanhToan(int soTien) {
System.out.printf("💵 Thanh toán tiền mặt: %,d VND%n", soTien);
}
}

public class ThanhToanThe implements ThanhToan {
@Override
public void thanhToan(int soTien) {
System.out.printf("💳 Thanh toán bằng thẻ: %,d VND%n", soTien);
}
}

public class ThanhToanViDienTu implements ThanhToan {
@Override
public void thanhToan(int soTien) {
System.out.printf("📱 Thanh toán ví điện tử: %,d VND%n", soTien);
}
}

// Sử dụng
public class TestPolymorphism {
public static void xuLyThanhToan(ThanhToan phuongThuc, int soTien) {
phuongThuc.thanhToan(soTien);
}

public static void main(String[] args) {
ThanhToan[] cacPhuongThuc = {
new ThanhToanTienMat(),
new ThanhToanThe(),
new ThanhToanViDienTu()
};

System.out.println("💰 CÁC PHƯƠNG THỨC THANH TOÁN:\n");

for (ThanhToan pt : cacPhuongThuc) {
xuLyThanhToan(pt, 150000);
}
}
}

Output:

💰 CÁC PHƯƠNG THỨC THANH TOÁN:

💵 Thanh toán tiền mặt: 150,000 VND
💳 Thanh toán bằng thẻ: 150,000 VND
📱 Thanh toán ví điện tử: 150,000 VND

Ví Dụ 6: Functional Interface (Java 8+)

@FunctionalInterface
public interface TinhToan {
int tinh(int a, int b); // Chỉ 1 abstract method
}

// Sử dụng với Lambda
public class TestFunctional {
public static void main(String[] args) {
// Lambda expression
TinhToan cong = (a, b) -> a + b;
TinhToan tru = (a, b) -> a - b;
TinhToan nhan = (a, b) -> a * b;

System.out.println("Cộng: " + cong.tinh(10, 5));
System.out.println("Trừ: " + tru.tinh(10, 5));
System.out.println("Nhân: " + nhan.tinh(10, 5));
}
}

Output:

Cộng: 15
Trừ: 5
Nhân: 50

🔥 Thực Hành Trong Quán

Bài Tập 1: Hệ Thống Đồ Uống

public interface DoUong {
String layTen();
int layGia();
void pha();
}

public class CaPhe implements DoUong {
private String ten;
private int gia;

public CaPhe(String ten, int gia) {
this.ten = ten;
this.gia = gia;
}

@Override
public String layTen() {
return ten;
}

@Override
public int layGia() {
return gia;
}

@Override
public void pha() {
System.out.println("☕ Pha cà phê " + ten);
}
}

public class TraSua implements DoUong {
private String ten;
private int gia;

public TraSua(String ten, int gia) {
this.ten = ten;
this.gia = gia;
}

@Override
public String layTen() {
return ten;
}

@Override
public int layGia() {
return gia;
}

@Override
public void pha() {
System.out.println("🧋 Pha trà sữa " + ten);
}
}

// Test
public class TestDoUong {
public static void main(String[] args) {
DoUong[] menu = {
new CaPhe("Latte", 50000),
new CaPhe("Mocha", 60000),
new TraSua("Trân châu", 45000)
};

System.out.println("☕ MENU:\n");

for (DoUong d : menu) {
System.out.printf("%-15s: %,d VND%n", d.layTen(), d.layGia());
}

System.out.println("\n🔥 PHA MÓN:\n");

for (DoUong d : menu) {
d.pha();
}
}
}

Bài Tập 2: Comparable Interface

public class SanPham implements Comparable<SanPham> {
private String ten;
private int gia;

public SanPham(String ten, int gia) {
this.ten = ten;
this.gia = gia;
}

@Override
public int compareTo(SanPham other) {
return this.gia - other.gia; // Sắp xếp theo giá
}

@Override
public String toString() {
return String.format("%-15s: %,d VND", ten, gia);
}

public static void main(String[] args) {
SanPham[] danhSach = {
new SanPham("Mocha", 60000),
new SanPham("Espresso", 45000),
new SanPham("Latte", 50000)
};

System.out.println("TRƯỚC KHI SẮP XẾP:\n");
for (SanPham sp : danhSach) {
System.out.println(sp);
}

java.util.Arrays.sort(danhSach);

System.out.println("\nSAU KHI SẮP XẾP:\n");
for (SanPham sp : danhSach) {
System.out.println(sp);
}
}
}

⚠️ Lỗi Thường Gặp

Lỗi 1: Không Implement Tất Cả Method

public interface PhucVu {
void chaoKhach();
void nhanDon();
void mangMon();
}

// ❌ SAI: Thiếu method
public class NhanVien implements PhucVu {
@Override
public void chaoKhach() {
System.out.println("Xin chào");
}
// ❌ Thiếu nhanDon() và mangMon()
}

// ✅ ĐÚNG: Implement đủ
public class NhanVien implements PhucVu {
@Override
public void chaoKhach() {}

@Override
public void nhanDon() {}

@Override
public void mangMon() {}
}

Lỗi 2: Tạo Object Interface

public interface DoUong {
void pha();
}

// ❌ SAI: Không thể new interface
DoUong d = new DoUong(); // ❌ Lỗi!

// ✅ ĐÚNG: new class implements interface
DoUong d = new CaPhe(); // ✅ OK

Lỗi 3: Sửa Constant

public interface CauHinh {
int GIO_MO_CUA = 7; // final
}

public class Quan implements CauHinh {
public void sua() {
// GIO_MO_CUA = 8; // ❌ Lỗi! final không sửa được
}
}

Lỗi 4: Access Modifier Trong Interface

// ❌ SAI: Dùng private trong interface
public interface Test {
private void method(); // ❌ Lỗi! (trước Java 9)
}

// ✅ ĐÚNG: Method mặc định public abstract
public interface Test {
void method(); // public abstract
}

💡 Bí Quyết Của Barista

  1. Interface = Hợp đồng: Cam kết phải làm gì
  2. Implements tất cả: Phải override hết method
  3. Đa interface: Class có thể implements nhiều
  4. Constant uppercase: GIO_MO_CUA, TEN_QUAN
  5. Default method: Tiện lợi cho backward compatibility
  6. Polymorphism: Dùng interface type cho linh hoạt

🎓 Bạn Đã Học Được

  • Interface = Hợp đồng định nghĩa method
  • implements = Class thực hiện interface
  • ✅ Tất cả method abstract (mặc định)
  • ✅ Constant: public static final
  • Đa interface: implements nhiều interface
  • Default method (Java 8+)
  • Static method (Java 8+)
  • ✅ Interface extends interface

☕ Món Tiếp Theo

Đã biết interface! Giờ học về abstract class:

👉 Abstract Classes - Lớp Trừu Tượng


💡 Lời Khuyên Cuối: Interface như bản mô tả công việc - nói rõ phải làm gì, nhân viên tự quyết định làm thế nào!