Cơ chế Upcasting và Downcasting trong java

Upcasting là gán object của subclass cho biến tham chiếu supperclass, trong khi Downcasting gán object của supperclass cho biến tham chiếu subclass.

Khi thực hiện downcasting chúng ta cần kiểm tra kiểu dữ liệu của object trước khi gán giá trị để tránh lỗi ClassCastException.

Ví dụ Downcasting và Upcasting

Cho các class theo sơ đồ sau: Food(Interface) -> Fruit -> Apple, Orange.

interface Food {
    float getTotalCalories();

    String getOrigin();
}

abstract class Fruit implements Food {
    abstract protected String getName();
}

class Apple extends Fruit {
    public float getTotalCalories() {
        return 0.40f;
    }

    public String getOrigin() {
        return "AppleCity";
    }

    @Override
    protected String getName() {
        return "Apple";
    }
}

class Orange extends Fruit {
    public float getTotalCalories() {
        return 0.30f;
    }

    public String getOrigin() {
        return "OrangeCity";
    }

    @Override
    protected String getName() {
        return "Orange";
    }
}

Nếu chúng ta gán một Apple object cho biến Fruit gọi là upcasting, vì Fruit class là class cha(supperclass) của Apple.

Fruit fruit = new Apple();
Apple castedApple = (Apple) fruit;

Nếu gấn một Fruit object cho biến Apple gọi là downcasting, trong downcasting chúng ta cần ép kiểu tường minh.

Fruit fruit = new Apple();
Apple apple = (Apple) fruit;

Tuy nhiên đoạn code trên khá nguy hiểm, chúng ta đã bỏ qua bước kiểm tra kiểu dữ liệu của Fruit object trước khi ép kiểu.

Xem ví dụ sau sẽ gây ra ClassCastException

Fruit fruit = new Orange();
Apple apple = (Apple) fruit;

Để tránh exception chúng ta có thể sử dụng từ khoá instanceof để kiểu tra kiểu dữ liệu của Fruit object trước khi ép kiểu.

Fruit fruit = new Orange();
if (fruit instanceof Apple) {
    Apple apple = (Apple) fruit;

} else {
    System.out.println("Can't cast");
}

Tại sao cần Upcasting

Upcasting được sử dụng nhiều trong tính đa hình lập trình hướng đối tượng, một biến kiểu dữ liệu supperclass có thể tham chiếu đến tất cả các object subclass. Sử dụng tính chất này chúng ta không phải khai báo kiểu dữ liệu cụ thể cho các object subclass class.

class test {
    public static void main(String[] agrs) {

        List<Fruit> fruits = new ArrayList<>();
        Fruit fruit = new Orange();
        Fruit fruit1 = new Apple();
        fruits.add(fruit);
        fruits.add(fruit1);
        for (Fruit f : fruits) {
            System.out.println(f.getName());
        }
    }
}

Output:

Orange
Apple

Tại sao cần downcasting

Sử dụng downcasting khi chúng ta cần sử dụng các tính chất riêng của subclass mà ở supperclass không có. 

Ví dụ Orange class định nghĩa thêm 1 method count() trả về số lượng orange còn trong kho.

class Orange extends Fruit { 
   // more code

   public int count() {
        return 100;
    }
}

Khởi tạo printName() method xuất tên của Fruit object từ tham số đầu vào, nếu là Orange thì xuất luôn số lượng.

public static void printName(Fruit fruit) {
    if (fruit instanceof Orange) {
        Orange orange = (Orange)fruit;
        System.out.println(fruit.getName() + " " + orange.count());
    } else {
        System.out.println(fruit.getName());
    }
}

Nguồn tham khảo

https://www.edureka.co/blog/upcasting-and-downcasting-in-java/

 

2.3 3 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x