Tớnh đa hỡnh trong Java

Một phần của tài liệu Bài giảng ngôn ngữ lập trình Java doc (Trang 59 - 60)

Tớnh đa hỡnh là một khả năng của OOP cho phộp một phương thức thực thi theo ngữ cảnh lỳc chương trỡnh đang chạy. Cho dựng là cựng một tờn gọi, thậm chớ là cựng danh sỏch tham số, phương thức vẫn được gọi theo đỳng đối tượng sở hữu nú.

Trong khi chỳng ta cài đặt tớnh chất thừa kế của OOP, cơ sở của tớnh đa hỡnh cũng đó được cài đặt. Trong vớ dụ trờn, phương thức getLuong() được định nghĩa ở cả lớp cha và lớp con, chỳng ta sẽ xem nú được gọi như thế nào.

VII.1 Sự ộp kiểu và gỏn tham chiếu đối tượng

Trong quan hệ thừa kế, đụi khi cú sự chuyển đổi vai trũ của cỏc lớp cha và con. Ta cú thể gỏn tham chiếu một đối tượng của lớp con cho một đối tượng của lớp cha. Trường hợp ngược lại là khụng thể. Đõy chớnh là thể hiện tớnh đa hỡnh của đối tượng. Một đối tượng của lớp cha cú thể được gỏn tham chiếu tới bất kỳ lớp con nào dẫn xuất từ nú nhưng khụng ộp kiểu sang lớp con được. Ngược lại, đối tượng lớp con khụng thể được gỏn tham chiếu tới một đối tượng lớp cha nhưng cú thể chuyển kiểu sang lớp cha.

Vớ dụ:

Employee me = new Employee("Nguyen Anh Minh", 50000, 2000, 10, 1); Employee you = new Employee("Nguyen Anh Tai", 52000, 2000, 10, 1); Manager boss = new Manager ("Nguyen Tan Minh", 80000, 1987, 12, 15); boss.setTienThuong(5000);

Manager boss1 = new Manager ("Nguyen Tan Phat", 81000, 1987, 12, 15); boss1.setTienThuong(15000);

boss = me; // khụng gỏn tham chiờu được me=boss1; //OK.

hoặc:

you = (Employee)boss; // Chuyển kiểu OK

boss1 = (Manager) me; // Cha khụng chuyển kiểu sang con được

Thậm chớ một mảng cỏc đối tượng Employee cú thể được gỏn cho một mảng cỏc đối tượng Manager mà khụng cần chuyển kiểu:

Manager[] managers = new Manager[10]; Employee[] staff = managers; // OK

Tuy vậy, sự chuyển đổi này chỉ diễn ra trong thời gian chạy chương trỡnh. Nếu khi lập trỡnh ta viết:

you = boss; // OK

you.setTienThuong(2000);// Khụng được

Lý do là việc chuyển kiểu chỉ xảy ra lỳc chương trỡnh chạy nờn khi biờn dịch “you” vẫn là một đối tượng Employee, nú khụng cú phương thức setTienLuong().

VII.2 Sự ràng buộc động –Dynamic Binding

Xột vớ dụ sau:

// Khai bỏo một đối tượng Manager

Manager boss = new Manager("Phan Thanh Ha", 80000, 1987, 12, 15); boss.setTienThuong(5000);

// Khai bỏo một mảng 3 đối tượng Employee Employee[] staff = new Employee[3]; // Gỏn boss cho đối tượng thứ 0

staff[0] = boss;

// Khởi tạo cho 2 đối tượng cũn lại

staff[1] = new Employee("Nguyen Hai Nam", 50000, 1989, 10, 1); staff[2] = new Employee("Pham Quyet Tan", 40000, 1990, 3, 15); // Dựng vũng lặp để in ra tờn và lương từng người

for (Employee e : staff)

System.out.println(e.getHoVaTen() + " " + e.getLuong()); Kết quả in ra là:

Phan Thanh Ha 85000.0 Nguyen Hai Nam 50000.0 Pham Quyet Tan 40000.0

Ở đõy chỳng ta thấy đối tượng thứ 1 và 2 in ra cỏc giỏ trị vốn cú của nú theo phương thức getLuong() của Employee. Tuy nhiờn đối tượng thứ 0 đó gọi phương thức getLuong() của Manager. Mặt khỏc, nếu viết:

staff[0].setTienThuong(2000); thỡ khụng được phộp khi biờn dịch.

Ta gọi việc getLuong() của Manager được gọi trong tỡnh huống này là sự ràng buộc muộn hay ràng buộc động (Dynamic Binding). Đặc trưng thể hiện tớnh đa hỡnh trong Java.

Để kết thỳc phần này ta sẽ xem xột cơ chế của việc gọi phương thức của một đối tượng trong Java được thực hiện như thế nào:

1. Trỡnh biờn dịch kiểm tra kiểu của đối tượng và tờn của phương thức, giả sử là x.f(param). Trong đú x được khai bỏo là đối tượng của lớp C. Trong lớp C cú thể cú nhiều phương thức cú cựng tờn f nhưng khỏc nhau ở tham số, vớ dụ f(int) và f(String). Trỡnh biờn dịch sẽ liệt kờ tất cả cỏc phương thức tờn f trong lớp C và phương thức tờn f cú mức độ truy cập public trong cỏc lớp cha của C.

2. Tiếp theo, trỡnh biờn dịch sẽ xỏc định kiểu của tham số của phương thức được gọi. Nếu trong danh sỏch phương thức cú tờn f chỉ cú 1 phương thức cú kiểu tham số phự hợp thỡ phương thức này được gọi. Vớ dụ cõu lệnh là x.f(“Chao ban”) thỡ hàm f(String) được gọi chứ khụng phải f(int). Cơ chế này gọi là nạp chồng (overloading). Nếu trỡnh biờn dịch khụng thể tỡm thấy phương thức cú tham số phự hợp hoặc cú nhiều hơn 1 phương thức phự hợp, nú sẽ đưa ra thụng bỏo lỗi.

Bõy giờ, trỡnh biờn dịch đó biết rừ phương thức nào được gọi (tờn và danh sỏch tham số). 3. Nếu phương thức là private, static và final hoặc là một constructor, trỡnh biờn dịch sẽ biết chớnh xỏc phương thức cần phải gọi đú là phương thức f của lớp C. Điều này gọi là ràng buộc tĩnh (static binding). Ngược lại, phương thức được gọi tựy theo kiểu hiện tại của đối tượng, giả sử kiểu hiện tại của x là D, một lớp dẫn xuất từ C (Ban đầu x là một đối tượng lớp C nhưng sau đú được gỏn tham chiếu tới một đối tượng của D). Nếu D cú định nghĩa một phương thức f(String) thỡ phương thức này sẽ được gọi. Nếu lớp D khụng cú, nú sẽ tỡm lờn cỏc lớp cha của D (trong đú cú lớp C). Cơ chế này gọi là ràng buộc động.

Một phần của tài liệu Bài giảng ngôn ngữ lập trình Java doc (Trang 59 - 60)