Thứ Sáu, 28 tháng 12, 2018

Học lập trình Java - Ghi đè

Trong chương trước, chúng ta đã nói về siêu lớp và các lớp con. Nếu một lớp kế thừa một phương thức từ siêu lớp của nó, thì có khả năng ghi đè phương thức với điều kiện là nó không được đánh dấu cuối cùng.

Lợi ích của việc ghi đè là: khả năng xác định một hành vi dành riêng cho loại lớp con, có nghĩa là một lớp con có thể thực hiện một phương thức lớp cha dựa trên yêu cầu của nó.

Khóa học lập trình Java
Khóa học lập trình Java

Khóa học lập trình Java Theo thuật ngữ hướng đối tượng, ghi đè có nghĩa là ghi đè chức năng của một phương thức hiện có.

Chúng ta hãy xem xét một ví dụ.

class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      System.out.println("Dogs can walk and run");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal a = new Animal();   // Animal reference and object
      Animal b = new Dog();   // Animal reference but Dog object

      a.move();   // runs the method in Animal class
      b.move();   // runs the method in Dog class
   }
}

Điều này sẽ tạo ra kết quả sau


Animals can move
Dogs can walk and run

Trong ví dụ trên, bạn có thể thấy rằng mặc dù b là một loại Động vật, nó vẫn chạy phương thức di chuyển trong lớp Dog. Lý do cho điều này là: 

Trong thời gian biên dịch, kiểm tra được thực hiện trên loại tham chiếu. Tuy nhiên, trong thời gian chạy, JVM chỉ ra loại đối tượng và sẽ chạy phương thức thuộc về đối tượng cụ thể đó.

Khóa học lập trình Java Do đó, trong ví dụ trên, chương trình sẽ biên dịch đúng vì lớp Animal có phương thức di chuyển. Sau đó, tại thời gian chạy, nó chạy phương thức cụ thể cho đối tượng đó.
class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      System.out.println("Dogs can walk and run");
   }
   public void bark() {
      System.out.println("Dogs can bark");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal a = new Animal();   // Animal reference and object
      Animal b = new Dog();   // Animal reference but Dog object

      a.move();   // runs the method in Animal class
      b.move();   // runs the method in Dog class
      b.bark();
   }
}

Điều này sẽ tạo ra kết quả sau

TestDog.java:26: error: cannot find symbol
      b.bark();
       ^
  symbol:   method bark()
  location: variable b of type Animal
1 error

Chương trình này sẽ đưa ra lỗi thời gian biên dịch do kiểu tham chiếu của b Animal không có phương thức bằng tên của vỏ cây.

Quy tắc ghi đè phương thức

Khóa học lập trình Java Danh sách đối số phải giống hệt như phương thức được ghi đè.

Kiểu trả về phải giống hoặc một kiểu con của kiểu trả về được khai báo trong phương thức ghi đè ban đầu trong lớp cha.

Mức truy cập không thể hạn chế hơn mức truy cập của phương thức bị ghi đè. Ví dụ: Nếu phương thức siêu lớp được khai báo công khai thì phương thức ghi đè trong lớp con có thể là riêng tư hoặc được bảo vệ.

Các phương thức sơ thẩm chỉ có thể được ghi đè nếu chúng được kế thừa bởi lớp con.

Một phương thức được tuyên bố cuối cùng không thể được ghi đè.

Một phương thức được khai báo tĩnh không thể bị ghi đè nhưng có thể được khai báo lại.

Nếu một phương thức không thể được kế thừa, thì nó không thể bị ghi đè.

Một lớp con trong cùng một gói như siêu lớp của cá thể có thể ghi đè bất kỳ phương thức siêu lớp nào không được khai báo là riêng tư hoặc cuối cùng.

Khóa học lập trình Java Một lớp con trong một gói khác nhau chỉ có thể ghi đè các phương thức không phải là cuối cùng được khai báo công khai hoặc được bảo vệ.

Một phương thức ghi đè có thể đưa ra bất kỳ ngoại lệ không được kiểm tra nào, bất kể phương thức ghi đè đó có ném ngoại lệ hay không. 

Tuy nhiên, phương thức ghi đè không được đưa ra các ngoại lệ được kiểm tra là mới hoặc rộng hơn so với phương pháp được ghi đè bằng phương thức ghi đè. Phương thức ghi đè có thể đưa ra các ngoại lệ hẹp hơn hoặc ít hơn so với phương thức ghi đè.

Con constructor không thể bị ghi đè.

Sử dụng siêu từ khóa

Khi gọi một phiên bản siêu lớp của một phương thức được ghi đè, siêu từ khóa được sử dụng.
class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      super.move();   // invokes the super class method
      System.out.println("Dogs can walk and run");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal b = new Dog();   // Animal reference but Dog object
      b.move();   // runs the method in Dog class
   }
}

Điều này sẽ tạo ra kết quả sau

Animals can move
Dogs can walk and run

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...