Tính đa hình trong OOP

Đa hình ( polymorphism ) nghĩa là có nhiều hình thái khác nhau. Tiêu biểu là, đa hình Open khi có một cấu trúc cấp bậc của những lớp và chúng tương quan với nhau bởi tính thừa kế .

Bạn hãy thử tưởng tượng nếu bạn yêu cầu những người sau thực hiện hành động “cắt”:

  • Bác sĩ phẫu thuật
  • Nhà tạo mẫu tóc
  • Diễn viên

Khi đó, chuyện gì sẽ xảy ra ?

  • Bác sĩ phẫu thuật sẽ bắt đầu rạch dao mổ.
  • Nhà tạo mẫu sẽ bắt đầu cắt tóc cho một ai đó.
  • Nam diễn viên sẽ ngừng diễn cảnh hiện tại, chờ đạo diễn hướng dẫn.

Ví dụ trên cho thấy bản chất của Tính đa hình. Nó tượng trưng cho việc cùng một tên gọi nhưng hành vi thì khác nhau.

Bạn đang đọc: Tính đa hình trong OOP

Tính đa hình (Polymorphism) trong lập trình hướng đối tượng

Tính đa hình là một hành vi hoàn toàn có thể được triển khai bằng nhiều cách khác nhau. Đây lại là một đặc thù hoàn toàn có thể nói là tiềm ẩn hầu hết sức mạnh của lập trình hướng đối tượng người dùng .
Hiểu một cách đơn thuần hơn : Đa hình là khái niệm mà hai hoặc nhiều lớp có những phương pháp giống nhau nhưng hoàn toàn có thể thực thi theo những phương pháp khác nhau. Một ví dụ về đa hình khác trong trong thực tiễn đó là ta có 2 con vật : chó, mèo. Cả 2 con vật này đều là lớp động vật hoang dã. Nhưng khi ta bảo cả 2 động vật hoang dã kêu thì con chó sẽ kêu gâu gâu, con mèo sẽ kêu meo meo .

Các loại đa hình trong lập trình hướng đối tượng

Tính đa hình hầu hết được chia thành hai loại :

  • Đa hình thời gian chạy (Runtime Polymorphism)
  • Đa hình thời gian biên dịch (Compile Time Polymorphism)

image

Đa hình thời gian chạy

Đa hình lúc runtime là quy trình gọi phương pháp đã được ghi đè trong thời hạn thực thi chương trình. Trong quy trình này, một phương pháp được ghi đè được gọi trải qua biến tham chiếu của một lớp cha .
Chúng ta tạo hai lớp Bike và Car. Lớp Bike thừa kế lớp Car và ghi đè phương pháp run ( ) của nó. Chúng ta gọi phương pháp run bởi biến tham chiếu của lớp cha. Khi nó tham chiếu tới đối tượng người tiêu dùng của lớp con và phương pháp lớp con ghi đè phương pháp của lớp cha, phương pháp lớp con được gọi lúc runtime .

class Car {
    void run() {
        System.out.println(" chạy ");
    }
}

public class Bike extends Car {
    void run() {
        System.out.println(" chạy với vận tốc 30 km / h ");
    }

    public static void main(String args[]) {
        Bike b = new Splender();  
        b.run();
    }
}

chạy với tốc độ 30km/h

Một ví dụ khác về tính đa hình

class Shape {
    void draw() {
        System.out.println(" vẽ ... ");
    }
}

class Rectangle extends Shape {
    void draw() {
        System.out.println(" vẽ hình chữ nhật ... ");
    }
}

class Circle extends Shape {
    void draw() {
        System.out.println(" vẽ hình tròn trụ ... ");
    }
}

class Triangle extends Shape {
    void draw() {
        System.out.println(" vẽ hình tam giác ... ");
    }
}

class Main {
    public static void main(String args[]

)

{ Shape s; s = new Rectangle(); s.draw(); s = new Circle(); s.draw(); s = new Triangle(); s.draw(); } }

vẽ hình chữ nhật...
vẽ hình tròn...
vẽ hình tam giác...

Tuy nhiên khi tất cả chúng ta truy vấn thuộc tính của lớp con thì sẽ không bị ghi đè, mà nó sẽ truy vấn thuộc tính của lớp cha .

class Bike{
 int speedlimit = 90;
}

class Honda3 extends Bike {
 int speedlimit = 150;
}

public static void main(String args[]){
  Bike obj=new Honda3();
  System.out.println(obj.speedlimit); 
}

90

Đa hình thời gian biên dịch

Đa hình thời hạn biên dịch sử dụng phương pháp nạp chồng. Do sử dụng chung một cái tên cho nhiều phương pháp, nên ta phải cho java biết cần phải gọi phương pháp nào để thực thi, java dựa vào sự khác nhau về số lượng đối cũng như kiểu tài liệu của những đối này để phân biệt những phương pháp trùng tên đó ..

public class OverloadingOrder {
  static void print(String s, int i) {
    System.out.println(" String : " + s + ", int : " + i);
  }

  static void print(int i, String s) {
    System.out.println(" int : " + i +", String : " + s);
  }

  public static void main(String[] args) {
    print(" String first ", 11);
    print(99, " Int first ");
  

}

}

String: String first, int: 11
int: 99, String: Int first

  • Nếu java không tìm thấy một hàm nạp chồng thích hợp thì nó sẽ đưa ra một thông báo lỗi
  • Ta không thể sử dụng giá trị trả về của hàm để phân biệt sự khác nhau giữa 2 phương thức nạp chồng
  • Không nên quá lạm dụng các phương thức nạp chồng vì trình biên dịch phải mất thời gian phán đoán để tìm ra hàm thích hợp, điều này đôi khi còn dẫn đến sai sót
  • Khi gọi các hàm nạp chồng ta nên có lệnh chuyển kiểu tường minh để trình biên dịch tìm ra hàm phù hợp một cách nhanh nhất