Lập trình hướng đối tượng (OOP) là một phương pháp tiếp cận lập trình mà cấu trúc và hành vi của một chương trình được mô tả thông qua các đối tượng. Java là một trong những ngôn ngữ lập trình phổ biến nhất sử dụng OOP với các nguyên lý cơ bản như lập trình kế thừa (inheritance) và đa hình (polymorphism).
Kế thừa trong OOP với Java
Kế thừa là khái niệm cho phép một lớp (class) kế thừa các thuộc tính và phương thức của một lớp khác. Lớp kế thừa được gọi là lớp con (subclass) hay lớp dẫn xuất (derived class), và lớp mà nó kế thừa được gọi là lớp cha (superclass) hay lớp cơ sở (base class).
Ví dụ:
// Lớp cơ sở
class Animal {
void eat() {
System.out.println("Animal is eating");
}
}
// Lớp dẫn xuất
class Dog extends Animal {
void bark() {
System.out.println("Dog is barking");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); // Kế thừa từ lớp Animal
dog.bark();
}
}
Trong ví dụ trên, lớp Dog
kế thừa các thuộc tính và phương thức của lớp Animal
. Điều này giúp tái sử dụng mã nguồn và giảm thiểu sự trùng lặp.
Loại hình kế thừa
Java hỗ trợ các loại hình kế thừa sau:
- Kế thừa đơn giản (Single Inheritance): một lớp chỉ có thể kế thừa từ một lớp khác.
- Kế thừa bậc thang (Multilevel Inheritance): kế thừa qua nhiều bậc lớp.
- Kế thừa thứ bậc (Hierarchical Inheritance): một lớp cha có nhiều lớp con.
Tuy nhiên, Java không hỗ trợ đa kế thừa (Multiple Inheritance) trực tiếp. Thay vào đó, nó sử dụng interfaces để đạt được điều này.
Đa hình trong OOP với Java
Đa hình là khái niệm cho phép một phương thức có thể thực hiện các hành vi khác nhau dựa trên đối tượng gọi nó. Đa hình trong Java có thể hiểu theo hai cách: đa hình thời gian biên dịch (compile-time polymorphism) và đa hình thời gian chạy (runtime polymorphism).
Đa hình thời gian biên dịch
Đa hình thời gian biên dịch thường được thực hiện thông qua phương thức nạp chồng (method overloading). Một phương thức trong cùng một lớp có thể tồn tại nhiều lần với các tham số khác nhau.
Ví dụ:
class MathOperation {
int add(int a, int b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
}
public class Main {
public static void main(String[] args) {
MathOperation math = new MathOperation();
System.out.println(math.add(2, 3));
System.out.println(math.add(2, 3, 4));
}
}
Trong ví dụ trên, phương thức add
được nạp chồng để có thể xử lý hai trường hợp khác nhau.
Đa hình thời gian chạy
Đa hình thời gian chạy được thực hiện thông qua sự ghi đè phương thức (method overriding). Lớp con có thể ghi đè phương thức của lớp cha để cung cấp một triển khai cụ thể.
Ví dụ:
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
myDog.sound(); // Gọi phương thức của lớp Dog
}
}
Trong ví dụ trên, phương thức sound
của lớp Dog
ghi đè phương thức sound
của lớp Animal
. Khi gọi myDog.sound()
, chương trình sẽ gọi phương thức sound
của lớp Dog
thay vì lớp Animal
.
Kết luận
Sử dụng tính kế thừa và đa hình trong lập trình hướng đối tượng với Java giúp tạo ra các chương trình linh hoạt, dễ bảo trì và tái sử dụng mã nguồn. Hiểu rõ và áp dụng đúng hai nguyên lý này là chìa khóa để trở thành một lập trình viên chuyên nghiệp trong môi trường OOP.
Comments