CodeGym /Blog Java /Ngẫu nhiên /Ghi đè phương thức trong Java

Ghi đè phương thức trong Java

Xuất bản trong nhóm
CHÀO! Bạn đã sử dụng các phương thức Java và biết rất nhiều về chúng. Chắc hẳn bạn đã từng đối mặt với tình huống trong đó một lớp có nhiều phương thức có cùng tên nhưng khác tham số. Bạn sẽ nhớ lại rằng trong những trường hợp đó, chúng tôi đã sử dụng nạp chồng phương thức. Hôm nay chúng ta đang xem xét một tình huống khác. Hãy tưởng tượng rằng chúng ta có một phương thức được chia sẻ duy nhất, nhưng nó phải làm những việc khác nhau trong các lớp khác nhau. Làm thế nào để chúng tôi thực hiện hành vi này? Để hiểu, chúng ta hãy xem xét một lớp Animal cha, đại diện cho các loài động vật và chúng ta sẽ tạo một phương thức speak trong đó:

public class Animal {

   public void speak() {

       System.out.println("Hello!");
   }
}
Mặc dù chúng tôi chỉ mới bắt đầu viết chương trình, nhưng bạn có thể thấy một vấn đề tiềm ẩn: có rất nhiều loài động vật trên thế giới và tất cả chúng đều 'nói' khác nhau: mèo kêu, vịt kêu và rắn rít. Cách ghi đè phương thức hoạt động - 2Mục tiêu của chúng tôi rất đơn giản: tránh tạo ra vô số phương pháp nói. Thay vì tạo phương thức catSpeak() để kêu meo meo, phương thức SnakeSpeak() để rít, v.v., chúng ta muốn gọi phương thức speak()phương pháp và có tiếng rắn rít, tiếng mèo kêu và tiếng chó sủa. Chúng ta có thể dễ dàng đạt được điều này bằng cách ghi đè phương thức. Wikipedia đưa ra lời giải thích sau đây về thuật ngữ 'ghi đè': Ghi đè phương thức, trong lập trình hướng đối tượng, là một tính năng ngôn ngữ cho phép một lớp con hoặc lớp con cung cấp một triển khai cụ thể của một phương thức đã được cung cấp bởi một trong các lớp cha hoặc lớp con của nó. các lớp cha Điều đó về cơ bản là đúng. Ghi đè phương thức cho phép bạn sử dụng một số phương thức của lớp cha và viết cách triển khai của riêng bạn trong mỗi lớp con. Việc triển khai mới 'thay thế' việc triển khai của cha mẹ trong lớp con. Hãy xem nó trông như thế nào trong một ví dụ. Tạo 4 lớp kế thừa lớp Animal của chúng ta :

public class Bear extends Animal {
   @Override
   public void speak() {
       System.out.println("Growl!");
   }
}
public class Cat extends Animal {

   @Override
   public void speak() {
       System.out.println("Meow!");
   }
}

public class Dog extends Animal {

   @Override
   public void speak() {
       System.out.println("Woof!");
   }
}


public class Snake extends Animal {

   @Override
   public void speak() {
       System.out.println("Hiss!");
   }
}
"Đây là một mẹo nhỏ cho tương lai: để ghi đè các phương thức của lớp cha, hãy chuyển đến mã của lớp con trong IntelliJ IDE, Nhấp vào Ctrl+O và chọn "Ghi đè các phương thức..." trong menu. Làm quen với việc sử dụng các phím nóng ngay từ đầu — nó sẽ giúp bạn viết chương trình nhanh hơn!
  1. Trong mỗi lớp con, chúng ta tạo một phương thức có cùng tên với phương thức của lớp cha.

  2. Chúng tôi đã nói với trình biên dịch rằng việc đặt tên phương thức giống như trong lớp cha không phải là ngẫu nhiên: chúng tôi muốn ghi đè lên hành vi của nó. Để giao tiếp điều này với trình biên dịch, chúng tôi đặt chú thích @Override phía trên phương thức.
    Khi được đặt phía trên một phương thức, chú thích @Override sẽ thông báo cho trình biên dịch (cũng như các lập trình viên đang đọc mã của bạn): 'Mọi thứ đều ổn. Đây không phải là một sai lầm. Tôi không phải là người hay quên. Tôi biết rằng một phương thức như vậy đã tồn tại và tôi muốn ghi đè lên nó'.

  3. Chúng tôi đã viết phần triển khai mà chúng tôi cần cho mỗi lớp con. Khi phương thức speak() được gọi, một con rắn sẽ rít lên, một con gấu sẽ gầm gừ, v.v.
Hãy xem cách nó hoạt động trong một chương trình:

public class Main {

   public static void main(String[] args) {

       Animal animal1 = new Dog();
       Animal animal2 = new Cat();
       Animal animal3 = new Bear();
       Animal animal4 = new Snake();

       animal1.speak();
       animal2.speak();
       animal3.speak();
       animal4.speak();
   }
}
Đầu ra bảng điều khiển:
Woof!
Meow!
Growl!
Hiss!
Xuất sắc! Tất cả mọi thứ hoạt động như nó nên! Chúng tôi đã tạo 4 biến tham chiếu lưu trữ các đối tượng của lớp cha Animal và chúng tôi đã gán các thể hiện của 4 lớp con khác nhau cho chúng. Kết quả là, mỗi đối tượng thể hiện hành vi riêng của mình. Đối với mỗi lớp con, phương thức speak() được ghi đè đã thay thế phương thức speak() 'gốc' trong lớp Animal (chỉ hiển thị 'Xin chào!'). Cách ghi đè phương thức hoạt động - 3Ghi đè có một số hạn chế:
  1. Phương thức được ghi đè phải có cùng tham số với phương thức gốc.

    Nếu phương thức speak của lớp cha có tham số Chuỗi , thì phương thức được ghi đè trong lớp con cũng phải có tham số Chuỗi . Nếu không, trình biên dịch sẽ báo lỗi:

    
    public class Animal {
    
       public void speak(String s) {
    
           System.out.println("Hello! " + s);
       }
    }
    
    public class Cat extends Animal {
    
       @Override // Error!
       public void speak() {
           System.out.println("Meow!");
       }
    }
    

  2. Phương thức bị ghi đè phải có cùng kiểu trả về với phương thức cha.

    Nếu không, chúng ta sẽ gặp lỗi trình biên dịch:

    
    public class Animal {
    
       public void speak() {
    
           System.out.println("Hello!");
       }
    }
    
    
    public class Cat extends Animal {
    
       @Override
       public String speak() {         // Error!
           System.out.println("Meow!");
           return "Meow!";
       }
    }
    

  3. Công cụ sửa đổi truy cập trên phương thức bị ghi đè cũng phải giống với phương thức 'gốc':

    
    public class Animal {
    	
          public void speak() {
    	
                System.out.println("Hello!");
          }
    }
    
    public class Cat extends Animal {
    
           @Override
           private void speak() {      // Error!
               System.out.println("Meow!");
           }
    }
    
Ghi đè phương thức trong Java là một cách để thực hiện tính đa hình (nguyên tắc của OOP mà chúng ta đã mô tả trong bài học trước). Điều này có nghĩa là ưu điểm chính của nó là tính linh hoạt giống như chúng ta đã thảo luận trước đây. Chúng ta có thể xây dựng một hệ thống các lớp đơn giản và hợp lý, mỗi lớp có một hành vi cụ thể (chó sủa, mèo kêu), với một giao diện chung — một phương thức speak() duy nhất cho tất cả chúng thay vì vô số phương thức, ví dụ: dogSpeak() , speakCat ( ) , v.v.
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION