Cơ chế Upcasting và Downcasting trong java

Trong bài Ép kiểu trong Java tôi đã giới thiệu với các bạn chuyển kiểu đối với kiểu dữ liệu cơ bản. Trong bài này, tôi sẽ giới thiệu với các bạn cơ chế Upcasting và Downcasting trong java. Đây là cơ chế được sử dụng để chuyển kiểu đối với kiểu dữ liệu tham chiếu.

Ví dụ chương trình sau:

class Animal {
    public void eat() {
        System.out.println("eating...");
    }
}
 
public class Cat extends Animal {
    public void meow() {
        System.out.println("meowing...");
    }
}

1. Upcasting

Khi biến tham chiếu của lớp cha tham chiếu tới đối tượng của lớp con, thì đó là Upcasting.

Ví dụ:

public class Upcasting {
 
    public static void main(String[] args) {
        Cat cat = new Cat();
        Animal animal1 = cat; // Chuyển kiểu không tường minh
        Animal animal2 = (Animal) cat; // Chuyển kiểu tường minh
 
        cat.eat();
        cat.meow();
        animal1.eat();
        animal2.eat();
        // animal2.meow(); // Không thể gọi phương thức meow()
    }
 
}

Kết quả thực thi chương trình trên:

eating...
meowing...
eating...
eating...

Với nội dung hàm main như trên, tôi đã thực hiện upcasting khi gán đối tượng cat thuộc lớp Cat cho đối tượng animal1 và animal2 thuộc lớp Animal.

Đối với upcasting, chúng ta hoàn toàn có thể sử dụng chuyển kiểu tường mình hoặc không tường minh, cả hai cách đều được chấp nhận.

Một lưu ý nhỏ: Mọi phương thức của lớp Animal hoàn toàn có thể gọi qua 1 đối tượng thuộc lớp Cat do giữa Animal và Cat có quan hệ IS_A. Tuy nhiên, nếu thực hiện override bất kỳ phương thức nào của lớp Animal tại lớp Cat thì trong quá trình runtime hàm được gọi sẽ là hàm của lớp Cat .

Quay trở lại ví dụ phía trên. Nếu trong lớp Cat, thực hiện override hàm eat như sau:

public class Cat extends Animal {
 
    @Override
    public void eat() {
        System.out.println("Eat meat");
    }
 
    public void meow() {
        System.out.println("meowing...");
    }
     
}

Kết quả thực thi lại chương trình trên như sau:

Eat meat
meowing...
Eat meat
Eat meat

2. Downcasting

Khác với upcasting, Downcasting là dạng chuyển kiểu chuyển 1 đối tượng là một thể hiện của lớp cha xuống thành đối tượng là thể hiện của lớp con trong quan hệ kế thừa.

Thông thường, khi thực hiện dòng mã nguồn:

Animal cat = new Cat();

Ta hoàn toàn có thể gọi những phương thức đã được override của lớp Animal tại lớp Cat qua đối tượng animal. Tuy nhiên, vấn đề phát sinh khi ta muốn gọi mọi phương thức của lớp Cat thông qua việc ép kiểu đối tượng thuộc lớp Animal. Khi đó, ta sử dụng downcasting .

Ví dụ:

public class Downcating {
 
    public static void main(String[] args) {
        Animal animal = new Cat();
        Cat cat = (Cat) animal; // downcasting
        cat.meow();
    }
 
}

Ta thấy, meow() là phương thức chỉ có ở lớp Cat. Tuy nhiên, thông qua downcasting ta hoàn toàn có thể gọi ra phương thức đó thông qua đối tượng cat mà không cần new Cat() bằng việc downcasting đối tượng animal có kiểu Animal mà không xảy ra vấn đề trong quá trình biên dịch (compile) và thực thi (runtime).

Lưu ý: khi thực hiện downcasting có thể sẽ gặp lỗi ClassCastException nếu không thể thực hiện downcassting được. Để an toàn chúng ta nên kiểm tra một đối tượng có phải là thể hiện của một kiểu dữ liệu cụ thể không trước khi thực hiện downcasting. Xem thêm hướng dẫn ở bài viết Toán tử instanceof trong java.

Related posts:

Guide to the Java Clock Class
Lớp TreeMap trong Java
Java Program to Describe the Representation of Graph using Adjacency Matrix
Hướng dẫn Java Design Pattern – Singleton
Interface trong Java 8 – Default method và Static method
Different Ways to Capture Java Heap Dumps
A Guide to the ViewResolver in Spring MVC
Java Program to Find kth Smallest Element by the Method of Partitioning the Array
Jackson Unmarshalling JSON with Unknown Properties
Java Program to Apply DFS to Perform the Topological Sorting of a Directed Acyclic Graph
Guide to java.util.Formatter
Java Program to Generate All Possible Subsets with Exactly k Elements in Each Subset
Java Program to Check if a Given Graph Contain Hamiltonian Cycle or Not
Java Program to Implement LinkedBlockingQueue API
Java Optional as Return Type
A Guide to @RepeatedTest in Junit 5
Java InputStream to Byte Array and ByteBuffer
A Guide to TreeMap in Java
StringBuilder vs StringBuffer in Java
Java Program to Perform Preorder Non-Recursive Traversal of a Given Binary Tree
Guide to Java 8 groupingBy Collector
Collection trong java
A Guide to Java 9 Modularity
Java Program to Implement Counting Sort
Java String Conversions
Java Program to Permute All Letters of an Input String
Apache Commons Collections BidiMap
Java Program to Implement LinkedBlockingDeque API
Java Program to Find Second Smallest of n Elements with Given Complexity Constraint
String Joiner trong Java 8
Java Web Services – Jersey JAX-RS – REST và sử dụng REST API testing tools với Postman
Jackson – Change Name of Field