Nạp chồng phương thức
Thuộc phần Lập trình hướng đối tượng trong hành trình C# của Coddy. Bài học 50 trên 70.
Nạp chồng phương thức (method overloading) cho phép bạn định nghĩa nhiều phương thức có cùng tên nhưng có danh sách tham số khác nhau. Trình biên dịch xác định phiên bản cần gọi dựa trên các đối số bạn cung cấp.
Mỗi phương thức nạp chồng phải có chữ ký riêng biệt, với số lượng tham số hoặc kiểu tham số khác nhau:
public static void Print(string message)
{
Console.WriteLine(message);
}
public static void Print(string message, int times)
{
for (int i = 0; i < times; i++)
Console.WriteLine(message);
}
public static void Print(int number)
{
Console.WriteLine(number);
}// Trình biên dịch chọn phiên bản phù hợp
Print("Hello"); // Gọi Print(string)
Print("Hi", 3); // Gọi Print(string, int)
Print(42); // Gọi Print(int)Nạp chồng khác với tham số tùy chọn ở một điểm quan trọng. Với tham số tùy chọn, bạn có một phương thức xử lý nhiều trường hợp. Với nạp chồng, bạn có các phương thức riêng biệt, mỗi phương thức có thể chứa logic hoàn toàn khác nhau cho từng trường hợp.
Lưu ý rằng chỉ khác kiểu dữ liệu trả về thì chưa đủ để các phương thức trở nên khác nhau, bạn không thể có hai phương thức chỉ khác nhau ở giá trị mà chúng trả về. Danh sách tham số phải khác nhau. Nạp chồng phương thức (method overloading) là một dạng đa hình tại thời điểm biên dịch, trong đó quyết định gọi phương thức nào được đưa ra khi biên dịch code, chứ không phải khi chạy code.
Thử thách
DễHãy xây dựng một lớp máy tính đa năng để minh họa sức mạnh của việc nạp chồng phương thức. Bạn sẽ tạo nhiều phiên bản của các phương thức tính toán để xử lý những tình huống khác nhau, từ phép tính đơn giản với hai số đến phép tính phức tạp hơn, tất cả đều dùng chung tên phương thức dễ hiểu.
Bạn sẽ sắp xếp code trong hai tệp:
Calculator.cs: Tạo lớpCalculatortrong không gian tênMathTools, với các phương thức được nạp chồng có cùng tên nhưng nhận các tham số khác nhau:Multiply: Tạo ba phiên bản được nạp chồng:- Một phiên bản nhận hai tham số
intvà trả về tích của chúng dưới dạngint - Một phiên bản nhận ba tham số
intvà trả về tích của chúng dưới dạngint - Một phiên bản nhận hai tham số
doublevà trả về tích của chúng dưới dạngdouble
- Một phiên bản nhận hai tham số
Describe: Tạo hai phiên bản được nạp chồng:- Một phiên bản nhận một
intvà trả về"Integer: {value}" - Một phiên bản nhận một
doublevà trả về"Double: {value}"
- Một phiên bản nhận một
Program.cs: Trong tệp chính, hãy tạo một đối tượngCalculatorvà minh họa cách trình biên dịch tự động chọn phương thức được nạp chồng phù hợp dựa trên các đối số bạn cung cấp.
Bạn sẽ nhận bốn đầu vào:
- Số nguyên thứ nhất (ví dụ:
5) - Số nguyên thứ hai (ví dụ:
4) - Số nguyên thứ ba (ví dụ:
3) - Một số thập phân (ví dụ:
2.5)
Dùng máy tính của bạn để thực hiện các phép tính sau và in từng kết quả trên một dòng riêng:
- Nhân hai số nguyên đầu tiên (dùng phiên bản nhận hai số nguyên)
- Nhân cả ba số nguyên (dùng phiên bản nhận ba số nguyên)
- Nhân số nguyên đầu tiên với số thập phân (dùng phiên bản nhận hai số thực)
- Mô tả số nguyên đầu tiên (dùng phiên bản nhận
int) - Mô tả số thập phân (dùng phiên bản nhận
double)
Ví dụ: nếu đầu vào là 5, 4, 3 và 2.5, đầu ra sẽ là:
20
60
12.5
Integer: 5
Double: 2.5Hãy để ý cách bạn gọi Multiply và Describe với các kiểu và số lượng đối số khác nhau, nhưng trình biên dịch vẫn biết chính xác phiên bản nào cần dùng mỗi lần. Đây là tính đa hình tại thời điểm biên dịch: quyết định được đưa ra khi code của bạn được biên dịch, chứ không phải khi code chạy!
Tự làm thử
using System;
using MathTools;
class Program
{
public static void Main(string[] args)
{
// Đọc các giá trị đầu vào
int firstInt = Convert.ToInt32(Console.ReadLine());
int secondInt = Convert.ToInt32(Console.ReadLine());
int thirdInt = Convert.ToInt32(Console.ReadLine());
double decimalNum = Convert.ToDouble(Console.ReadLine());
// TODO: Tạo một instance của Calculator
// TODO: Gọi Multiply với hai số nguyên và in ra kết quả
// TODO: Gọi Multiply với ba số nguyên và in ra kết quả
// TODO: Gọi Multiply với số nguyên đầu tiên và số thập phân, rồi in ra kết quả
// TODO: Gọi Describe với số nguyên đầu tiên và in ra kết quả
// TODO: Gọi Describe với số thập phân và in ra kết quả
}
}
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Các khái niệm cơ bản về lập trình hướng đối tượng
Tệp bên ngoàiKhông gian tên và chỉ thịGiới thiệu về lớp và đối tượngTừ khóa thisPhương thức và tham sốTrường và thuộc tínhHàm khởi tạoKhởi tạo đối tượngÔn tập: Máy tính đơn giản4Kế thừa
Cú pháp kế thừa cơ bản (:)Từ khóa 'base'Từ khóa virtual và overrideLớp sealedLớp cơ sở 'object'Ôn tập: hệ phân cấp nhân viên7Tính năng nâng cao
Nạp chồng toán tửBộ lập chỉ mục (this[])Ghi đè ToString()Phương thức mở rộngÔn tập: Danh sách tùy chỉnh10Các mẫu thiết kế phần 1
Giới thiệu về mẫu thiết kếSingleton an toàn với luồngMẫu FactoryMẫu Observer (sự kiện)Mẫu Strategy2Thuộc tính và thành viên tĩnh
Thuộc tính tự độngThuộc tính chỉ đọc hoặc chỉ ghiTrường và phương thức tĩnhLớp tĩnhThành viên có thân biểu thức5Đa hình và interface
Đa hình lúc biên dịch và lúc chạyInterface và lớp trừu tượngNhiều interfaceInterface tường minhUpcasting và downcastingÔn tập: bộ tính toán hình học8Các khái niệm OOP nâng cao
Ưu tiên composition hơn kế thừaGenerics (lớp và phương thức)Delegate và sự kiệnAttribute và reflectionGiao diện IDisposable và câu lệnh usingKiến thức cơ bản về dependency injection11Các mẫu thiết kế phần 2
Mẫu lệnhMẫu bộ chuyển đổiMẫu trang tríMẫu phương thức khuôn mẫuMẫu trạng tháiMẫu tổ hợpTự luyện tập: Trình biên dịch C# online