JavaRush /Blog Java /Random-VI /Chuyển đổi các kiểu tham chiếu trong Java
Sant9Iga
Mức độ

Chuyển đổi các kiểu tham chiếu trong Java

Xuất bản trong nhóm
Chúc một ngày tốt lành, anh chàng Javarash. Tôi bắt đầu nhận được câu hỏi về việc truyền các kiểu tham chiếu trong Java. Để không phải lần nào cũng kể lại những điều giống nhau, tôi quyết định viết một bài báo ngắn.

Đầu tiên, chúng ta hãy xem kiểu casting là gì.

Truyền kiểu (chuyển đổi kiểu) là chuyển đổi giá trị biến của một loại sang giá trị của loại khác. Chúng ta hãy xem một ví dụ về nó là gì và nó được ăn với cái gì. Chúng tôi có một số hệ thống phân cấp lớp ( xem Hình 1 ). Tại đây bạn có thể thấy tất cả các lớp trong hệ thống phân cấp, ai kế thừa ai và các phương thức của mỗi lớp. Bức tranh 1Có một sự mở rộng và một sự cộng thêm co lại. Chúng ta thấy rằng lớp này Catlà hậu duệ của lớp Pet. Pet, đến lượt nó, là sự kế thừa của lớp Animal. Khi chúng tôi viết:
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
Đây là một diễn viên mở rộng (hoặc một diễn viên tiềm ẩn). Chúng tôi đã mở rộng các liên kết animalCatanimalDog. Họ đề cập đến các đối tượng CatDog. Với cách truyền như vậy, chúng ta không thể animalCat/animalDoggọi các phương thức thông qua một tham chiếu có trong Cat/Dog, nhưng không có trong Animal. Diễn biến thu hẹp (hoặc rõ ràng) xảy ra theo hướng ngược lại:
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
Cat cat =(Cat)animalCat;
YorkshireTerrier dog = (YorkshireTerrier) animalDog;
Chúng tôi đã chỉ rõ loại chúng tôi muốn truyền đối tượng này tới. NHƯNG HÃY CẨN THẬN!!! Nếu bạn làm điều đó như thế này:
Animal animalCat = new Cat();
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
trình biên dịch sẽ bỏ qua mã này. Nhưng RunTimenó sẽ ném ra cho bạn:
Exception in thread "main" java.lang.ClassCastException: Animals.Cat cannot be cast to Animals.YorkshireTerrier
RunTimethấy rằng CatYorkshireTerrierhai lớp khác nhau. Để tránh ClassCastException trong quá trình thu hẹp chuyển đổi, hãy sử dụng instanceof.
Animal animalCat = new Cat();
if (animalCat instanceof YorkshireTerrier)
{
    YorkshireTerrier dog = (YorkshireTerrier) animalCat;
}
Nếu animalCatđúng YorkshireTerrierthì việc chuyển nhượng sẽ diễn ra, nếu không thì sẽ không có gì xảy ra.

Bây giờ tại sao điều này lại cần thiết nếu chúng ta mất phương thức và có thể gặp phải những lỗi như vậy

Chúng ta hãy xem mã mà tôi đã tạo theo sơ đồ trong Hình. 1 . Lớp họcAnimal
public abstract class Animal
{
    String name;
    int age;
    String nameOfClass = getClass().getSimpleName();
    public void eat(){
        System.out.println(nameOfClass + ": Omnomnom");
    }
    public void sleep(){
        System.out.println(nameOfClass + ": Z-z-z-z");
    }
}
Một lớp WildAnimalkế thừa từAnimal
public abstract class WildAnimal extends Animal
{
    public void steelChicken()
    {
        System.out.println(nameOfClass+": Muhaha,I stole a chicken!");
    }
}
Một lớp Petkế thừa từAnimal
public abstract class Pet extends Animal
{
    public void peeInTray(){
        System.out.println(nameOfClass + ": Master, I peed");
    }
}
Một lớp Foxkế thừa từWildAnimal
public class Fox extends WildAnimal
{
    public void eatColobok(){
        System.out.println(nameOfClass + ": I will eat you, Colobok");
    }
}
Một lớp Wolfkế thừa từWildAnimal
public class Wolf extends WildAnimal
{
    public void hawlAtTheMoon(){
        System.out.println(nameOfClass + ": Ouuuuu!!!Ouuuu!!!");
    }
}
Một lớp Catkế thừa từPet
public class Cat extends Pet
{
    public void sleepOnKeyboard(){
        System.out.println(nameOfClass + ": Master, stop working!!I wanna sleep on your keyboard");
    }
}
Một lớp YorkshireTerrierkế thừa từPet
public class YorkshireTerrier extends Pet
{
    public void bark(){
        System.out.println(nameOfClass + ": Meow!!! Meow!!!");
    }
}
Hãy tưởng tượng tình huống này. Chúng ta cần thu thập tất cả các loài động vật vào một danh sách, cho chúng ăn rồi cho chúng đi ngủ. Điều này rất dễ thực hiện nếu chúng ta tạo ArrayListđộng vật ( Animal). Và sau đó chúng ta gọi các phương thức tương ứng cho từng con vật:
public class ZOO
{
    public static void main(String[] args)
    {
        List<Animal> allAnimals = new ArrayList<>();
        allAnimals.add(new Cat());
        allAnimals.add(new Wolf());
        allAnimals.add(new Fox());
        allAnimals.add(new YorkshireTerrier());
        for (Animal animal : allAnimals)
        {
            animal.eat();
            animal.sleep();
        }
    }
}
Tôi không thể animalgọi phương thức bark()hoặc sleepOnKeyboard(). Bởi vì trang tính allAnimalscó một con mèo, một con sói, một con yorick và một con cáo, nhưng chúng được giảm xuống còn Animal. Và họ chỉ có các phương thức có trong Animal. Điều này rất tốt, vì nếu chúng ta có thể gọi được tất cả các phương thức thì tại sao chúng ta lại cần một con sói ngủ trên bàn phím, hay một kẻ yorick đi trộm gà? Cám ơn vì sự quan tâm của bạn. Tôi hy vọng bài viết này sẽ hữu ích cho bạn. Những lời chỉ trích và bình luận đều được chào đón)
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION