Tổng Quan Về Tính Đa Hình Trong Java
Tính đa hình (Polymorphism) là một trong những khái niệm cốt lõi trong lập trình hướng đối tượng, đặc biệt quan trọng trong ngôn ngữ lập trình Java. Đa hình cho phép các đối tượng thể hiện hành vi khác nhau trong khi sử dụng cùng một giao diện hoặc lớp cơ sở. Java hỗ trợ hai loại đa hình chính: đa hình tại biên dịch (compile-time polymorphism) và đa hình tại runtime (runtime polymorphism).
1. Đa Hình Tại Biên Biên Soạn (Compile-time Polymorphism)
1.1 Nạp Chồng Phương Thức (Method Overloading)
Nạp chồng phương thức là quá trình định nghĩa nhiều phương thức có cùng tên trong một lớp, nhưng khác nhau về số lượng tham số hoặc kiểu dữ liệu của tham số. Ví dụ:
java
class Calculator {
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
}
1.2 Nạp Chồng Toán Tử (Operator Overloading)
Java không hỗ trợ nạp chồng toán tử như một số ngôn ngữ khác như C++. Vì vậy, bạn không thể định nghĩa các toán tử (+, -, *, /) cho các lớp do người dùng tạo.
2. Đa Hình Tại Runtime (Runtime Polymorphism)
2.1 Kế Thừa (Inheritance)
Khi một lớp con kế thừa từ một lớp cha, nó có thể sử dụng các thuộc tính và phương thức của lớp cha. Khi một phương thức trong lớp con ghi đè một phương thức trong lớp cha, hành vi của phương thức sẽ được xác định vào thời điểm chạy (runtime).
java
class Animal {
void makeSound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
void makeSound() {
System.out.println("Dog barks");
}
}
class Cat extends Animal {
void makeSound() {
System.out.println("Cat meows");
}
}
2.2 Ghi Đè Phương Thức (Method Overriding)
Ghi đè phương thức là khi lớp con cung cấp một triển khai mới cho một phương thức đã được định nghĩa trong lớp cha.
Việc sử dụng đa hình giúp bạn thao tác với các đối tượng dựa trên giao diện hoặc lớp cơ sở mà không cần biết chi tiết về loại đối tượng cụ thể. Điều này làm cho mã nguồn trở nên linh hoạt, dễ bảo trì và mở rộng hơn.
Các Ví Dụ Minh Họa
Ví Dụ 1: Đa Hình Tại Runtime Với Lớp Shape
Giả sử bạn xây dựng một lớp Shape
và các lớp con như Circle
và Square
. Mỗi lớp con sẽ ghi đè phương thức calculateArea()
để tính diện tích của hình.
java
class Shape {
public void calculateArea() {
System.out.println("Tính diện tích của hình...");
}
}
class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void calculateArea() {
double area = Math.PI * radius * radius;
System.out.println("Diện tích hình tròn là: " + area);
}
}
class Square extends Shape {
private double side;
public Square(double side) {
this.side = side;
}
@Override
public void calculateArea() {
double area = side * side;
System.out.println("Diện tích hình vuông là: " + area);
}
}
Ví Dụ 2: Hệ Thống Quản Lý Nhân Viên
Trong hệ thống này có các loại nhân viên như Nhân viên bán hàng, Nhân viên quản lý và Nhân viên sản xuất:
java
public abstract class Employee {
private String name;
private int employeeId;
public Employee(String name, int employeeId) {
this.name = name;
this.employeeId = employeeId;
}
public abstract double calculateSalary();
public void displayInfo() {
System.out.println("Employee ID: " + employeeId);
System.out.println("Name: " + name);
}
}
public class SalesEmployee extends Employee {
private double sales;
public SalesEmployee(String name, int employeeId, double sales) {
super(name, employeeId);
this.sales = sales;
}
@Override
public double calculateSalary() {
return 2000 + (0.1 * sales);
}
}
public class ManagerEmployee extends Employee {
private int teamSize;
public ManagerEmployee(String name, int employeeId, int teamSize) {
super(name, employeeId);
this.teamSize = teamSize;
}
@Override
public double calculateSalary() {
return 3000 + (0.05 * teamSize * 1000);
}
}
public class ProductionEmployee extends Employee {
private int hoursWorked;
public ProductionEmployee(String name, int employeeId, int hoursWorked) {
super(name, employeeId);
this.hoursWorked = hoursWorked;
}
@Override
public double calculateSalary() {
return 1500 + (hoursWorked * 20);
}
}
Ví Dụ 3: Ứng Dụng Quản Lý Thư Viện
Xây dựng một ứng dụng với nhiều loại tài liệu như Sách, Tạp chí và Báo:
java
public abstract class Document {
private String title;
public Document(String title) {
this.title = title;
}
public abstract void displayInfo();
}
public class Book extends Document {
private String author;
private int numberOfPages;
public Book(String title, String author, int numberOfPages) {
super(title);
this.author = author;
this.numberOfPages = numberOfPages;
}
@Override
public void displayInfo() {
System.out.println("Book Title: " + title);
System.out.println("Author: " + author);
System.out.println("Number of Pages: " + numberOfPages);
}
}
public class Journal extends Document {
private int issueNumber;
private String publisher;
public Journal(String title, int issueNumber, String publisher) {
super(title);
this.issueNumber = issueNumber;
this.publisher = publisher;
}
@Override
public void displayInfo() {
System.out.println("Journal Title: " + title);
System.out.println("Issue Number: " + issueNumber);
System.out.println("Publisher: " + publisher);
}
}
public class Newspaper extends Document {
private String date;
private String editor;
public Newspaper(String title, String date, String editor) {
super(title);
this.date = date;
this.editor = editor;
}
@Override
public void displayInfo() {
System.out.println("Newspaper Title: " + title);
System.out.println("Date: " + date);
System.out.println("Editor: " + editor);
}
}
Kết Luận
Tính đa hình trong Java là một công cụ mạnh mẽ giúp lập trình viên tạo ra các ứng dụng linh hoạt, dễ bảo trì và mở rộng. Bạn có thể thao tác với các đối tượng thông qua các lớp cơ sở, điều này giúp tăng cường khả năng tái sử dụng mã. Việc áp dụng đa hình còn khuyến khích việc thực hiện các nguyên tắc hướng đối tượng như nguyên lý Liskov, làm cho kiến trúc chương trình trở nên vững chắc và bền vững hơn. Tổng kết lại, tính đa hình là yếu tố quan trọng giúp cho code Java trở nên sống động và hiệu quả hơn.
source: viblo