Thứ Năm, 30 tháng 8, 2018

Java - Đa hình

Học lập trình java Đa hình là khả năng của một đối tượng có nhiều hình thức. Việc sử dụng phổ biến nhất của đa hình trong OOP xảy ra khi một tham chiếu lớp cha được sử dụng để chỉ một đối tượng lớp con.

Học lập trình java
Bất kỳ đối tượng Java nào có thể vượt qua nhiều thử nghiệm IS-A được coi là đa hình. Trong Java, tất cả các đối tượng Java là đa hình vì bất kỳ đối tượng nào cũng sẽ vượt qua bài kiểm tra IS-A cho kiểu riêng của chúng và cho đối tượng lớp.

Điều quan trọng là phải biết rằng cách duy nhất có thể truy cập một đối tượng là thông qua một biến tham chiếu. Biến tham chiếu chỉ có thể là một loại. Sau khi khai báo, loại biến tham chiếu không thể thay đổi.

Biến tham chiếu có thể được gán lại cho các đối tượng khác miễn là nó không được khai báo cuối cùng. Loại biến tham chiếu sẽ xác định các phương thức mà nó có thể gọi trên đối tượng.

Biến tham chiếu có thể tham chiếu đến bất kỳ đối tượng nào thuộc loại được khai báo của nó hoặc bất kỳ loại con nào thuộc loại được khai báo của nó. Biến tham chiếu có thể được khai báo dưới dạng lớp hoặc loại giao diện.

Thí dụ

Chúng ta hãy xem xét một ví dụ.
public interface Vegetarian{}
public class Animal{}
public class Deer extends Animal implements Vegetarian{}
Bây giờ, lớp Deer được coi là đa hình vì điều này có nhiều thừa kế. Sau đây là đúng cho các ví dụ trên

Một con nai IS-A động vật

A Deer IS-A Vegetarian

Một Deer IS-A Deer

Một đối tượng IS-A Deer

Khi chúng ta áp dụng các sự kiện biến tham chiếu cho tham chiếu đối tượng Deer, các khai báo sau là hợp pháp

Thí dụ
Deer d = new Deer();
Animal a = d;
Vegetarian v = d;
Object o = d;
Tất cả các biến tham chiếu d, a, v, o tham chiếu đến cùng một đối tượng Deer trong heap.

Phương pháp ảo

Trong phần này, tôi sẽ chỉ cho bạn cách hành vi của các phương thức ghi đè trong Java cho phép bạn tận dụng lợi thế của đa hình khi thiết kế các lớp của bạn.

Chúng ta đã thảo luận về phương thức ghi đè, trong đó một lớp con có thể ghi đè lên một phương thức trong phần tử cha của nó. Một phương thức ghi đè về cơ bản là ẩn trong lớp cha và không được gọi trừ khi lớp con sử dụng từ khóa siêu trong phương thức ghi đè.

Thí dụ
/* File name : Employee.java */
public class Employee {
   private String name;
   private String address;
   private int number;

   public Employee(String name, String address, int number) {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }

   public void mailCheck() {
      System.out.println("Mailing a check to " + this.name + " " + this.address);
   }

   public String toString() {
      return name + " " + address + " " + number;
   }

   public String getName() {
      return name;
   }

   public String getAddress() {
      return address;
   }

   public void setAddress(String newAddress) {
      address = newAddress;
   }

   public int getNumber() {
      return number;
   }
}
Bây giờ giả sử chúng ta mở rộng lớp Employee như sau:
/* File name : Salary.java */
public class Salary extends Employee {
   private double salary; // Annual salary
   
   public Salary(String name, String address, int number, double salary) {
      super(name, address, number);
      setSalary(salary);
   }
   
   public void mailCheck() {
      System.out.println("Within mailCheck of Salary class ");
      System.out.println("Mailing check to " + getName()
      + " with salary " + salary);
   }
   
   public double getSalary() {
      return salary;
   }
   
   public void setSalary(double newSalary) {
      if(newSalary >= 0.0) {
         salary = newSalary;
      }
   }
   
   public double computePay() {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
}
Bây giờ, bạn nghiên cứu kỹ chương trình sau đây và cố gắng xác định đầu ra của nó -
/* File name : VirtualDemo.java */
public class VirtualDemo {

   public static void main(String [] args) {
      Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
      Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
      System.out.println("Call mailCheck using Salary reference --");   
      s.mailCheck();
      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
   }
}
Điều này sẽ tạo ra kết quả sau

Đầu ra

Constructing an Employee
Constructing an Employee

Call mailCheck using Salary reference --
Within mailCheck of Salary class
Mailing check to Mohd Mohtashim with salary 3600.0

Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to John Adams with salary 2400.0

Ở đây, chúng ta khởi tạo hai đối tượng Lương. Một sử dụng một tài liệu tham khảo tiền lương s , và một bằng cách sử dụng một tham chiếu nhân viên e .

Trong khi gọi s.mailCheck () , trình biên dịch thấy mailCheck () trong lớp Salary tại thời gian biên dịch, và JVM gọi mailCheck () trong lớp Salary khi chạy.

mailCheck () trên e khá khác nhau vì e là tham chiếu của nhân viên. Khi trình biên dịch thấy e.mailCheck () , trình biên dịch sẽ thấy phương thức mailCheck () trong lớp Employee.

Ở đây, tại thời gian biên dịch, trình biên dịch đã sử dụng mailCheck () trong Employee để xác nhận hợp lệ câu lệnh này. Tuy nhiên, tại thời gian chạy, JVM gọi hàm mailCheck () trong lớp Mức lương.

Hành vi này được gọi là lời gọi phương thức ảo, và các phương thức này được gọi là các phương thức ảo. Một phương thức ghi đè được gọi vào lúc chạy, bất kể kiểu dữ liệu tham chiếu nào được sử dụng trong mã nguồn tại thời gian biên dịch.

Không có nhận xét nào:

Đăng nhận xét

Lập trình Java - Ngoại lệ

Một ngoại lệ (hoặc sự kiện đặc biệt) là một vấn đề phát sinh trong quá trình thực hiện chương trình. Khi xảy ra Ngoại lệ , luồng bình thường...