📜 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
- ✅ Tất cả method đều abstract (trước Java 8)
- ✅ Tất cả biến đều public static final
- ✅ Class có thể implements nhiều interface
- ✅ Interface có thể extends nhiều interface
- ✅ Không thể tạo object trực tiếp
- ✅ 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
- Interface = Hợp đồng: Cam kết phải làm gì
- Implements tất cả: Phải override hết method
- Đa interface: Class có thể implements nhiều
- Constant uppercase: GIO_MO_CUA, TEN_QUAN
- Default method: Tiện lợi cho backward compatibility
- 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!