Khi bắt đầu học lập trình, một trong những thuật ngữ thường được nhắc đến là “abstract” hay “tính trừu tượng”. Tuy nhiên, không phải ai cũng hiểu rõ về ý nghĩa của thuật ngữ này và cách sử dụng trong lập trình. Trong bài viết này, chúng ta sẽ cùng tìm hiểu về abstract là gì và vai trò của nó trong lập trình.
Abstract trong Java
Để hiểu được abstract là gì, ta cần nắm rõ khái niệm của nó trong Java. Trong Java, abstract là một từ khóa (keyword) dùng để khai báo một class hoặc method là abstract. Điều đó có nghĩa là, khi một class hoặc method được khai báo là abstract, nó sẽ không được định nghĩa hoàn chỉnh mà chỉ là một cái tên hoặc một cái hình dạng (shape).
Một class abstract không thể được khởi tạo thành đối tượng (object), chỉ có các class con kế thừa từ nó mới có thể được khởi tạo. Các method abstract cũng không có định nghĩa cụ thể, mà chỉ có sự khai báo (declaration). Việc định nghĩa chi tiết của class và method abstract sẽ được thực hiện trong các class con kế thừa.
Abstract là gì trong Java
Để hiểu rõ hơn về vị trí của abstract trong Java, chúng ta cần phân biệt giữa abstract class và abstract method. Trong đó, abstract class là một class có từ khóa “abstract” và có ít nhất một method abstract, còn abstract method là một method không có định nghĩa cụ thể (body) và được khai báo trong một abstract class.
Một abstract class có thể có cả method abstract và method không phải abstract. Tuy nhiên, nếu một class có ít nhất một method abstract, thì class đó cũng phải được khai báo là abstract. Điều này có nghĩa là, abstract class là một sự kết hợp giữa các tính chất của một class và một interface.
Một điểm quan trọng cần lưu ý là, trong Java, một class chỉ có thể kế thừa từ một class cha duy nhất, nhưng có thể implements nhiều interface. Vì vậy, việc sử dụng abstract class và interface có vai trò quan trọng trong việc thiết kế và phân cấp các class trong một ứng dụng.
Abstract class trong Java
Chúng ta đã biết abstract class là một class có từ khóa “abstract” và có thể chứa cả method abstract và method không phải abstract. Điểm đặc biệt của abstract class là nó không thể được khởi tạo thành đối tượng, mà chỉ có thể dùng để kế thừa và định nghĩa sự giống nhau giữa các class con.
Ví dụ, chúng ta có thể tạo một abstract class mang tên “Shape”, chứa các thuộc tính và method cơ bản của các hình học như diện tích, chu vi, vẽ hình,… Các class con như “Rectangle” hay “Circle” có thể kế thừa từ abstract class này và định nghĩa lại các method cụ thể của mình mà không cần phải khai báo lại các thuộc tính và method đã có trong “Shape”.
Abstract method là gì
Abstract method là một method không có định nghĩa cụ thể (body) và được khai báo trong một abstract class. Mục đích của việc sử dụng abstract method là để yêu cầu các class con phải định nghĩa lại và triển khai các method đó theo cách riêng của mình.
Việc sử dụng abstract method giúp cho việc thiết kế và phân cấp class trở nên linh hoạt và dễ dàng hơn. Chúng ta có thể sử dụng các method đã được định nghĩa trong abstract class mà không cần phải quan tâm đến cách thức triển khai của chúng, và chỉ cần tập trung vào việc định nghĩa lại các method abstract để phù hợp với từng class con.
Sự khác nhau giữa abstract class và interface
Như đã đề cập ở trên, abstract class và interface đều có tính chất trừu tượng và được sử dụng để phân cấp các class. Tuy nhiên, hai khái niệm này vẫn có những điểm khác biệt cơ bản. Dưới đây là những điểm khác nhau giữa abstract class và interface:
- Abstract class có thể chứa cả method abstract và method không phải abstract, trong khi interface chỉ có thể chứa các method abstract.
- Một class có thể kế thừa từ một abstract class duy nhất, nhưng có thể implements nhiều interface.
- Interface không có thuộc tính, chỉ có những method không có định nghĩa cụ thể (method abstract), còn abstract class có thể có các thuộc tính và method không phải abstract.
- Khi kế thừa từ abstract class, các class con phải implement tất cả các method abstract của cha, còn khi implement từ interface, các class chỉ cần triển khai lại các method đã được khai báo trong interface.
Tính trừu tượng trong lập trình
Tính trừu tượng (abstraction) là một khái niệm quan trọng trong lập trình hướng đối tượng. Nó cho phép chúng ta tập trung vào các thuộc tính và method cần thiết để thực hiện một nhiệm vụ cụ thể, mà không cần quan tâm đến các chi tiết bên trong của chúng.
Trong Java, việc sử dụng abstract class và interface góp phần tạo nên tính trừu tượng trong lập trình. Bằng cách này, chúng ta có thể tách biệt các phương diện khác nhau của một ứng dụng và giúp cho việc phát triển và bảo trì mã nguồn dễ dàng hơn.
Ưu điểm của việc sử dụng abstract trong Java
Việc sử dụng abstract trong Java có nhiều ưu điểm, trong đó có những điểm được liệt kê dưới đây:
- Giúp tách biệt các phương diện khác nhau của một ứng dụng và đơn giản hóa việc phát triển và bảo trì mã nguồn.
- Cho phép sử dụng tính đa hình (polymorphism) và đa kế thừa (multiple inheritance) trong lập trình hướng đối tượng.
- Tránh việc lặp lại code và giảm thiểu sự phụ thuộc giữa các class.
- Giúp cho việc thiết kế và cấu trúc ứng dụng trở nên linh hoạt và dễ dàng hơn.
Cách sử dụng abstract trong lập trình
Để khai báo một class là abstract, chúng ta chỉ cần thêm từ khóa “abstract” vào đầu của class declaration:
public abstract class Shape{
// code here
}
Để khai báo một method là abstract, chúng ta chỉ cần thêm từ khóa “abstract” vào đầu của method declaration và không có body để định nghĩa:
public abstract void draw();
Khi một class con kế thừa từ abstract class, nó phải triển khai lại tất cả các method abstract mà cha đã định nghĩa:
// Class con kế thừa từ abstract class
public class Rectangle extends Shape{
public void draw(){
// code here
}
}
Nếu một class không triển khai lại tất cả các method abstract của cha, thì nó cũng phải được khai báo là abstract. Chúng ta cũng không thể khởi tạo đối tượng từ một abstract class:
// Không thể khởi tạo đối tượng từ abstract class
Shape shape = new Shape(); // error
Ví dụ minh họa về abstract trong Java
Để hiểu rõ hơn về cách sử dụng abstract trong Java, chúng ta sẽ xem một ví dụ minh họa đơn giản. Trong ví dụ này, chúng ta sẽ tạo ra một abstract class “Animal” và các class con kế thừa từ nó như “Dog”, “Cat” và “Bird”.
// Abstract class Animal
public abstract class Animal{
// Thuộc tính name
private String name;
// Constructor không có tham số
public Animal(){
this.name = "";
}
// Constructor với tham số name
public Animal(String name){
this.name = name;
}
// Phương thức abstract makeSound()
public abstract void makeSound();
// Phương thức getter cho thuộc tính name
public String getName(){
return this.name;
}
}
// Class con Dog
public class Dog extends Animal{
// Override phương thức makeSound()
public void makeSound(){
System.out.println("Gâu gâu!");
}
}
// Class con Cat
public class Cat extends Animal{
// Override phương thức makeSound()
public void makeSound(){
System.out.println("Meo meo!");
}
}
// Class con Bird
public class Bird extends Animal{
// Override phương thức makeSound()
public void makeSound(){
System.out.println("Chíp chíp!");
}
}
// Chương trình chính
public class Main{
public static void main(String[] args){
// Khởi tạo đối tượng Dog và gọi phương thức makeSound()
Animal dog = new Dog();
dog.makeSound(); // Output: Gâu gâu!
// Khởi tạo đối tượng Cat và gọi phương thức makeSound()
Animal cat = new Cat();
cat.makeSound(); // Output: Meo meo!
// Khởi tạo đối tượng Bird và gọi phương thức makeSound()
Animal bird = new Bird();
bird.makeSound(); // Output: Chíp chíp!
}
}
Trong ví dụ trên, chúng ta đã khai báo một abstract class “Animal” với thuộc tính name và method abstract “makeSound()”. Sau đó, ta tạo ra các class con kế thừa từ “Animal” như “Dog”, “Cat” và “Bird” và override lại phương thức “makeSound()” theo cách riêng của từng class. Cuối cùng, chúng ta khởi tạo các đối tượng từ các class con và gọi phương thức “makeSound()” để kiểm tra kết quả.
Kết luận
Trên đây là những thông tin cơ bản về abstract trong Java. Để sử dụng hiệu quả abstract trong lập trình, chúng ta cần hiểu rõ về khái niệm này và cách áp dụng trong các trường hợp cụ thể. Hy vọng bài viết này sẽ giúp bạn có được một cái nhìn tổng quan và áp dụng abstract trong lập trình Java một cách hiệu quả.