Professional Documents
Culture Documents
TACN
TACN
5 ● Polymorphism
15.5 ● Tính đa hình
Bomb to create two objects, storing them in an array list named game, and displaying
them. The display is shown in Figure 15.1.
"Dùng Bomb để tạo ra hai đối tượng, lưu trữ chúng trong một danh sách mảng có tên là game, và hiển thị
chúng:
Alien alien = new Alien(20, 20, 100);
Bomb bomb = new Bomb(80, 80, 10);
ArrayList game = new ArrayList();
game.add(alien);
game.add(bomb);
for (int s = 0; s < game.size(); s++) {
Object item = game.get(s);
Sprite sprite = (Sprite) item;
sprite.display(paper);
}
Hình 15.1
Polymorphism is in use here – the method display is called on two occasions with
different results according to which object is in use. You can see that the two calls of
display within the for loop:
sprite.display(paper);
give two different outputs. Two different outputs are displayed because the Java sys-
tem automatically selects the version of display associated with the class of the object.
When method display is first called, the variable sprite contains the object alien
and so the version of display in the class Alien is called. Then the corresponding
thing happens with bomb. This is the essence of polymorphism.
The class of an object is determined when the object is created using new classes,
and stays the same whatever happens to the object. Whatever you do to an object in a
program, it always retains the features it had when it was created. An object can be
assigned to a variable of another class and passed around the program as a parameter,
but it never loses its true identity.
Polymorphism allows us to write a single concise statement, such as:
"Đa hình được áp dụng ở đây - phương thức display được gọi hai lần với kết quả khác nhau tùy thuộc vào
đối tượng nào được sử dụng. Bạn có thể thấy rằng hai lần gọi display trong vòng lặp for:
sprite.display(paper);
cho hai kết quả khác nhau. Điều này xảy ra vì hệ thống Java tự động chọn phiên bản của display liên kết
với lớp của đối tượng.
Khi phương thức display được gọi lần đầu tiên, biến sprite chứa đối tượng alien, do đó phiên bản của
display trong lớp Alien được gọi. Sau đó, điều tương tự xảy ra với bomb. Đây là bản chất của đa hình.
Lớp của một đối tượng được xác định khi đối tượng được tạo bằng cách sử dụng new, và luôn giữ nguyên
bất kể điều gì xảy ra với đối tượng. Bất kỳ thay đổi nào bạn thực hiện trên một đối tượng trong chương
trình, nó luôn giữ nguyên các đặc điểm mà nó có khi nó được tạo. Một đối tượng có thể được gán cho một
biến của một lớp khác và được truyền xuyên suốt chương trình như một tham số, nhưng nó không bao giờ
mất đi danh tính thực sự của nó.
Đa hình cho phép chúng ta viết một câu lệnh ngắn gọn duy nhất, như sau:
sprite.display(paper);
instead of a series of if statements like this:
if (sprite instanceof Alien) {
Alien alien = (Alien) sprite;
alien.display(paper);
}
if (sprite instanceof Bomb) {
Bomb bomb = (Bomb) sprite;
bomb.display(paper);
}
are processed. It is so common that some languages provide a foreach control struc-
ture. In Java, the above for loop can be rewritten more concisely as:
Đa hình 15.5
một phần của mã lập trình mà không linh hoạt và dài dòng. Cụ thể, điều này sử dụng từ khóa instanceof
để hỏi xem một đối tượng có là thành viên của một lớp đã đặt tên hay không. Nếu có một số lượng lớn
các đối tượng đồ họa, sẽ có một số lượng if tương ứng lớn. Tránh sự phức tạp này thể hiện sức mạnh và
tính ngắn gọn của đa hình.
Như chúng ta đã thấy trong ví dụ nhỏ này, đa hình thường làm cho một phần của chương trình trở nên
nhỏ gọn và gọn gàng thông qua việc loại bỏ một loạt các câu lệnh điều kiện `if`. Nhưng thành tựu này
quan trọng hơn nhiều so với vẻ bề ngoài của nó. Điều này có nghĩa là các câu lệnh như:
sprite.display(paper);
không biết gì về các loại đối tượng có thể được sử dụng làm giá trị của `sprite`. Vì vậy, việc ẩn thông tin
(đã tồn tại ở mức lớn trong OOP) được mở rộng. Chúng ta có thể kiểm tra điều này bằng cách đánh giá
xem chúng ta sẽ cần phải thay đổi chương trình này như thế nào để phù hợp với một loại đối tượng đồ họa
mới (một lớp con bổ sung của Sprite), ví dụ như một tia laser. Câu trả lời là chúng ta không cần phải sửa
đổi nó chút nào - chúng ta chỉ cần thêm đối tượng mới. Điều này có nghĩa là chương trình cực kỳ linh
hoạt. Do đó, đa hình tăng cường tính mô đun, khả năng tái sử dụng và khả năng bảo trì.
Nói chung, cách tiếp cận sử dụng đa hình trong một chương trình cụ thể như sau:
1. Xác định bất kỳ sự tương đồng nào (phương thức và biến chung) giữa bất kỳ đối tượng hoặc lớp nào
trong chương trình.
2. Thiết kế một lớp cha mô tả các đặc điểm chung của các lớp.
3. Thiết kế các lớp con mô tả các đặc điểm độc đáo của mỗi lớp, trong khi kế thừa các đặc điểm chung từ
lớp cha.
4. Xác định bất kỳ nơi nào trong chương trình mà cùng một thao tác phải được áp dụng cho bất kỳ đối
tượng tương tự nào. Có thể rất hấp dẫn để sử dụng các câu lệnh điều kiện `if` tại vị trí này. Thay vào đó,
đây là nơi sử dụng đa hình.
5. Đảm bảo rằng lớp cha chứa một phương thức trừu tượng tương ứng với phương thức được sử dụng đa
hình.
Đoạn mã được hiển thị ở trên, với một danh sách mảng và một vòng lặp for, là một ví dụ về tình huống
thường xuyên xảy ra trong phần mềm, nơi toàn bộ nội dung của một bộ sưu tậpđược xử lý. Điều này rất
phổ biến đến mức một số ngôn ngữ cung cấp một cấu trúc điều khiển foreach.
Trong Java, vòng lặp for trên có thể được viết lại một cách ngắn gọn hơn như sau:
for (Object item : game) {
((Sprite) item).display(paper);
}
Each time that the for statement repeats, it obtains the next element from the array
list game.
Mỗi khi câu lệnh for lặp lại, nó lấy phần tử tiếp theo từ danh sách mảng game.
including Java and C#, one role of multiple inheritance has been replaced by the inter-
face facility described in Chapter 16 on programming in the large.
15.6 ● Kế thừa đơn lẻ so với kế thừa đa lớp
Như chúng ta đã thấy, Java hỗ trợ kế thừa đơn lẻ - một lớp chỉ có thể kế thừa từ một lớp cha trực tiếp.
Nhìn như một biểu đồ lớp, các mối quan hệ giữa các lớp xuất hiện như một cây (một cây máy tính, với
gốc ở trên cùng). Smalltalk, Ada, C# và Visual Basic.Net cũng cung cấp kế thừa đơn lẻ.
Tuy nhiên, ngôn ngữ phổ biến được sử dụng rộng rãi là C++ cung cấp kế thừa đa lớp, cũng như Eiffel.
Trong một ngôn ngữ như vậy, một lớp không chỉ kế thừa từ một mà còn từ nhiều lớp cha. Trong cuộc
sống, chúng ta không chỉ là một người, chúng ta cũng thuộc về các danh mục khác nhau, như anh em, con
gái, người yêu bóng đá, động vật ăn thịt. Vì vậy, một lớp đại diện cho một người là một lớp con của tất cả
các lớp cha này, kế thừa các biến và phương thức từ tất cả chúng.
Không có nghi ngờ gì rằng kế thừa đa lớp phức tạp hơn - cả về việc cung cấp trong ngôn ngữ và sử dụng.
C++ thường được coi là một ngôn ngữ quá phức tạp và