Bài 5: Abstraction (Trừu tượng hóa) trong Java
I. Định nghĩa và lợi ích của Abstraction
Định nghĩa Abstraction:
Abstraction (Trừu tượng hóa) là quá trình loại bỏ các chi tiết không cần thiết và chỉ tập trung vào các khía cạnh quan trọng của đối tượng hoặc vấn đề cần giải quyết. Trong lập trình hướng đối tượng, abstraction giúp đơn giản hóa các hệ thống phức tạp bằng cách chỉ hiển thị những thông tin cần thiết và ẩn đi các chi tiết triển khai không quan trọng.
Lợi ích của Abstraction:
Ẩn chi tiết cài đặt: Chỉ hiển thị các chức năng quan trọng và ẩn đi các chi tiết cài đặt bên trong.
Giảm sự phức tạp: Làm cho hệ thống dễ hiểu và dễ bảo trì hơn.
Tăng tính bảo trì: Dễ dàng thay đổi và mở rộng mã nguồn mà không ảnh hưởng đến các phần khác của hệ thống.
Tái sử dụng mã nguồn: Các lớp trừu tượng và interface có thể được sử dụng lại trong các hệ thống khác nhau.
II. Abstract Class và Interface
Abstract Class (Lớp trừu tượng):
Lớp trừu tượng là một lớp không thể tạo đối tượng trực tiếp từ nó, mà phải được kế thừa bởi các lớp con.
Lớp trừu tượng có thể chứa các phương thức trừu tượng (không có thân hàm) và các phương thức thông thường (có thân hàm).
Sử dụng từ khóa
abstractđể khai báo một lớp trừu tượng.
Interface:
Interface là một bản thiết kế cho các lớp, định nghĩa các phương thức nhưng không có thân hàm.
Một lớp có thể thực hiện nhiều interface, nhưng chỉ có thể kế thừa từ một lớp trừu tượng.
Sử dụng từ khóa
interfaceđể khai báo một interface.
Khi nào nên sử dụng cái nào:
Sử dụng Abstract Class khi bạn muốn định nghĩa một lớp cơ sở với một số phương thức mặc định hoặc phương thức với thân hàm.
Sử dụng Interface khi bạn muốn định nghĩa một bộ hợp đồng cho các lớp thực hiện mà không quan tâm đến cài đặt cụ thể.
III. Ví dụ cụ thể
Abstract Class:
abstract class Animal {
// Phương thức trừu tượng
abstract void makeSound();
// Phương thức thông thường
void eat() {
System.out.println("This animal eats food.");
}
}
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Bark");
}
}
class Cat extends Animal {
@Override
void makeSound() {
System.out.println("Meow");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
Animal myCat = new Cat();
myDog.makeSound(); // Gọi phương thức makeSound() của Dog
myDog.eat(); // Gọi phương thức eat() từ lớp Animal
myCat.makeSound(); // Gọi phương thức makeSound() của Cat
myCat.eat(); // Gọi phương thức eat() từ lớp Animal
}
}
Interface:
interface Animal {
void makeSound();
void eat();
}
class Dog implements Animal {
@Override
public void makeSound() {
System.out.println("Bark");
}
@Override
public void eat() {
System.out.println("The dog eats food.");
}
}
class Cat implements Animal {
@Override
public void makeSound() {
System.out.println("Meow");
}
@Override
public void eat() {
System.out.println("The cat eats food.");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
Animal myCat = new Cat();
myDog.makeSound(); // Gọi phương thức makeSound() của Dog
myDog.eat(); // Gọi phương thức eat() của Dog
myCat.makeSound(); // Gọi phương thức makeSound() của Cat
myCat.eat(); // Gọi phương thức eat() của Cat
}
}
IV. Bài tập thực hành
Bài tập: Tạo một hệ thống quản lý phương tiện giao thông sử dụng abstraction.
Yêu cầu:
Tạo một lớp trừu tượng
Vehiclevới các thuộc tínhmake,model, và các phương thức trừu tượngstart()vàstop().Tạo các lớp con
CarvàBikekế thừa từ lớpVehiclevà triển khai các phương thức trừu tượng.Tạo một interface
Drivablevới phương thứcdrive().Thực hiện interface
Drivabletrong các lớpCarvàBike.Viết chương trình chính để tạo các đối tượng và gọi các phương thức.
Mã nguồn mẫu:
abstract class Vehicle {
private String make;
private String model;
public Vehicle(String make, String model) {
this.make = make;
this.model = model;
}
public String getMake() {
return make;
}
public String getModel() {
return model;
}
abstract void start();
abstract void stop();
}
interface Drivable {
void drive();
}
class Car extends Vehicle implements Drivable {
public Car(String make, String model) {
super(make, model);
}
@Override
void start() {
System.out.println("Car " + getMake() + " " + getModel() + " is starting.");
}
@Override
void stop() {
System.out.println("Car " + getMake() + " " + getModel() + " is stopping.");
}
@Override
public void drive() {
System.out.println("Car " + getMake() + " " + getModel() + " is being driven.");
}
}
class Bike extends Vehicle implements Drivable {
public Bike(String make, String model) {
super(make, model);
}
@Override
void start() {
System.out.println("Bike " + getMake() + " " + getModel() + " is starting.");
}
@Override
void stop() {
System.out.println("Bike " + getMake() + " " + getModel() + " is stopping.");
}
@Override
public void drive() {
System.out.println("Bike " + getMake() + " " + getModel() + " is being ridden.");
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car("Toyota", "Corolla");
Bike bike = new Bike("Honda", "CBR");
car.start();
car.drive();
car.stop();
bike.start();
bike.drive();
bike.stop();
}
}
Tổng kết
Bài học này cung cấp một cái nhìn chi tiết về Abstraction (Trừu tượng hóa) trong Java, bao gồm định nghĩa, lợi ích, sự khác biệt giữa abstract class và interface, cùng với các ví dụ minh họa cụ thể. Việc nắm vững khái niệm này sẽ giúp bạn xây dựng các hệ thống phần mềm đơn giản hơn, dễ bảo trì và mở rộng, cải thiện hiệu quả phát triển phần mềm.