Nội dung bài viết
Trương Diễm Hương Chuyển kiểu là một trong những phạm trù cơ bản cần biết khi tìm hiểu bất cứ ngôn ngữ lập trình nào. Đối với ngôn ngữ lập trình Java, chuyển kiểu được thực hiện như thế nào? Bài viết dưới đây sẽ trả lời câu hỏi phía trên.

Giới thiệu

Chuyển kiểu là một trong những phạm trù cơ bản cần biết khi tìm hiểu bất cứ ngôn ngữ lập trình nào. Đối với ngôn ngữ lập trình Java, chuyển kiểu được thực hiện như thế nào? Bài viết dưới đây sẽ trả lời câu hỏi phía trên.

Tiền đề bài viết

Bài viết nằm trong chuỗi bài viết về Chủ đề JAVA.

Đối tượng hướng đến

Bài viết hướng đến những lập trình viên đang tìm hiểu mức độ cơ bản về ngôn ngữ Java.

Chuyển kiểu

Thông thường chuyển kiểu được chia làm 2 loại:

  • Chuyển kiểu ngầm định
  • Chuyển kiểu tường minh.

Tuy nhiên, để thuận tiện cho việc trình bày cũng như đọc hiểu, tôi sẽ trình bày cả hai loại chuyển kiểu trên theo kiểu dữ liệu là kiểu dữ liệu cơ bản và kiểu dữ liệu tham chiếu.

Chuyển kiểu đối với kiểu dữ liệu cơ bản

Đối với những kiểu dữ liệu cơ bản trong Java, nguyên lý chuyển kiểu hoàn toàn tương tự như trong ngôn ngữ C. Tham khảo tại: Cơ Bản Về Chuyển Kiểu Trong C :: www.stdio.vn/articles/read/90/co-ban-ve-chuyen-kieu-trong-c.

Chuyển kiểu với kiểu dữ liệu tham chiếu

Quan sát ví dụ sau:

class Monster {
       public void eat(){
              System.out.println("Eat something");
       }
}
class Dragon extends Monster {
       public void fly(){
              System.out.println("Dragon can fly");
       }
}

Xây dựng 2 lớp Monster và Dragon có quan hệ kế thừa.

Upcast

Upcast được hiểu là chuyển kiểu chuyển một đối tượng là một thể hiện của lớp con lên thành đối tượng là thể hiện của lớp cha trong quan hệ kế thừa.

Từ ví dụ phía trên ta hiện thực hàm main như sau:

public static void main(String []args) {
      Dragon obj1   = new Dragon();
      Monster obj2  = obj1;              // Upcast with no explicit cast
      Monster obj3  = (Monster)obj1;     // Upcast with an explicit cast
             
      obj2.eat();
      obj3.eat();
}

Kết quả

              Eat something

              Eat something

Với nội dung hàm main như trên, tôi đã thực hiện upcast tại hai dòng 4 và 5 khi gán đối tượng obj1 thuộc lớp Dragon cho đối tượng obj2 obj3 thuộc lớp Monster. Đối với upcast, lập trình viên 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ỏ rằng: Mọi phương thức của lớp Monster hoàn toàn có thể gọi qua 1 đối tượng thuộc lớp Dragon do giữa Monster và Dragon 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 Monster tại lớp Dragon thì trong quá trình Runtime hàm được gọi sẽ là hàm của lớp Dragon. Quay trở lại ví dụ phía trên. Nếu trong lớp Dragon, thực hiện override hàm eat như sau:

public void eat() {
       System.out.print("Eat meat");
}

Kết quả

              Eat meat

              Eat meat

Downcast

Khác với upcast, downcast 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:

Monster obj = new Dragon();

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

Hiện thực downcast trong hàm main của ví dụ trên như sau:

public static void main(String []args) {
       Monster obj = new Dragon();
       Dragon obj1 = (Dragon)obj;

       obj1.fly();
}

Ta thấy, fly là phương thức chỉ có ở lớp Dragon. Tuy nhiên, thông qua downcast tại dòng 4 ta hoàn toàn có thể gọi ra phương thức đó thông qua đối tượng obj1 mà không cần new Dragon bằng việc downcast đối tượng obj có kiểu Monster mà không xảy ra vấn đề trong quá trình biên dịch và runtime.

THẢO LUẬN
ĐÓNG