Upcasting và downcasting là một phần quan trọng của Java, cho phép chúng ta xây dựng các chương trình phức tạp bằng cú pháp đơn giản và mang lại cho chúng ta những lợi thế lớn, như Đa hình hoặc nhóm các đối tượng khác nhau. Java cho phép một đối tượng của một loại lớp con được coi là một đối tượng của bất kỳ loại siêu lớp nào. Điều này được gọi là u ám. Upcasting được thực hiện tự động, trong khi downcasting phải được lập trình viên thực hiện thủ công và tôi sẽ cố gắng hết sức để giải thích tại sao lại như vậy.
Upcasting và downcasting KHÔNG giống như truyền nguyên thủy từ cái này sang cái khác, và tôi tin rằng đó là điều gây ra nhiều nhầm lẫn, khi lập trình viên bắt đầu học đúc các đối tượng.
Đa hình: Tất cả các phương thức trong java là ảo theo mặc định. Điều đó có nghĩa là bất kỳ phương thức nào cũng có thể bị ghi đè khi được sử dụng trong kế thừa, trừ khi phương thức đó được khai báo là cuối cùng hoặc tĩnh .
Bạn có thể xem ví dụ bên dưới cách getType();
hoạt động theo loại đối tượng (Dog, Pet, Police Dog).
Giả sử bạn có ba con chó
Chó - Đây là siêu hạng.
Pet Dog - Pet Dog kéo dài Dog.
Chó cảnh sát - Chó cảnh sát kéo dài Chó cưng.
public class Dog{
public String getType () {
System.out.println("NormalDog");
return "NormalDog";
}
}
/**
* Pet Dog has an extra method dogName()
*/
public class PetDog extends Dog{
public String getType () {
System.out.println("PetDog");
return "PetDog";
}
public String dogName () {
System.out.println("I don't have Name !!");
return "NO Name";
}
}
/**
* Police Dog has an extra method secretId()
*/
public class PoliceDog extends PetDog{
public String secretId() {
System.out.println("ID");
return "ID";
}
public String getType () {
System.out.println("I am a Police Dog");
return "Police Dog";
}
}
Đa hình: Tất cả các phương thức trong java là ảo theo mặc định. Điều đó có nghĩa là bất kỳ phương thức nào cũng có thể bị ghi đè khi được sử dụng trong kế thừa, trừ khi phương thức đó được khai báo là cuối cùng hoặc tĩnh. (Giải thích thuộc về khái niệm bảng ảo)
Bảng ảo / Bảng điều phối: Bảng điều phối của đối tượng sẽ chứa các địa chỉ của các phương thức ràng buộc động của đối tượng. Các cuộc gọi phương thức được thực hiện bằng cách tìm nạp địa chỉ của phương thức từ bảng điều phối của đối tượng. Bảng điều phối giống nhau cho tất cả các đối tượng thuộc cùng một lớp và do đó thường được chia sẻ giữa chúng.
public static void main (String[] args) {
/**
* Creating the different objects with super class Reference
*/
Dog obj1 = new Dog();
` /**
* Object of Pet Dog is created with Dog Reference since
* Upcasting is done automatically for us we don't have to worry about it
*
*/
Dog obj2 = new PetDog();
` /**
* Object of Police Dog is created with Dog Reference since
* Upcasting is done automatically for us we don't have to worry
* about it here even though we are extending PoliceDog with PetDog
* since PetDog is extending Dog Java automatically upcast for us
*/
Dog obj3 = new PoliceDog();
}
obj1.getType();
Bản in Normal Dog
obj2.getType();
Bản in Pet Dog
obj3.getType();
Bản in Police Dog
Downcasting cần phải được thực hiện bởi các lập trình viên
Khi bạn cố gắng để gọi secretID();
phương pháp trên obj3
được PoliceDog object
nhưng tham chiếu đến Dog
mà là một lớp siêu trong hệ thống phân cấp nó throws lỗi vì obj3
không được tiếp cận với secretId()
phương pháp. Để gọi phương thức đó, bạn cần Downcast mà obj3 thủ công để PoliceDog
( (PoliceDog)obj3).secretID();
mà in ID
Theo cách tương tự để gọi dogName();
phương pháp trong PetDog
lớp học mà bạn cần phải nhìn xuống obj2
để PetDog
từ obj2 được tham chiếu tới Dog
và không được tiếp cận với dogName();
phương pháp
( (PetDog)obj2).dogName();
Tại sao lại như vậy, việc upcasting là tự động, nhưng downcasting phải là thủ công? Vâng, bạn thấy đấy, u ám không bao giờ có thể thất bại. Nhưng nếu bạn có một nhóm các Chó khác nhau và muốn downCast tất cả chúng vào một chủng loại, sau đó có một cơ hội, mà một số trong những Chó thực sự của các loại khác nhau tức là, PetDog
, PoliceDog
, và quá trình thất bại, bởi ném ClassCastException
.
Đây là lý do bạn cần hạ thấp các đối tượng của mình theo cách thủ công nếu bạn đã tham chiếu các đối tượng của mình với loại siêu hạng.
Lưu ý: Ở đây bằng cách tham chiếu có nghĩa là bạn không thay đổi địa chỉ bộ nhớ của các từ chối của bạn khi bạn hạ thấp nó, nó vẫn giống như bạn chỉ nhóm chúng thành loại cụ thể trong trường hợp này Dog
Dog
là mộtAnimal
. Hầu hết thời gian u ám là không cần thiết trừ khi bạn muốn sử dụng một phương thức quá tải nhất định.callme
tồn tại trong cả haiAnimal
vàDog
.callme2
chỉ tồn tại trongDog
, mà bạn đúca
đểDog
làm cho nó làm việc.