nhiều cách gọi phương thức cha trong php


90

Lúc đầu, tôi đã nhầm lẫn tại sao cả hai phương thức gọi trong hàm tạo đều hoạt động, nhưng bây giờ tôi nghĩ rằng tôi đã hiểu. Các lớp mở rộng kế thừa các phương thức của lớp cha như thể chúng đã được khai báo trong chính lớp đó, VÀ các phương thức tồn tại trong lớp cha, vì vậy cả hai đều hoạt động.

Bây giờ tôi đang tự hỏi liệu có cách nào được ưu tiên (tức là phương pháp hay nhất) để gọi phương thức (qua parenthoặc this) hay không và liệu đây có phải là những cách thực sự giống hệt nhau để thực thi cùng một mã hay không hoặc có bất kỳ lưu ý nào khi sử dụng một cai khac.

Xin lỗi, có lẽ tôi đang nghĩ quá nhiều về điều này.

abstract class Animal {

    function get_species() {

        echo "test";

    }

}

class Dog extends Animal {

    function __construct(){

        $this->get_species();
        parent::get_species();

    }

}

$spike = new Dog;

Câu trả lời:


120

Có ba tình huống (mà tôi có thể nghĩ đến) nơi bạn sẽ gọi một phương thức trong một lớp con nơi phương thức thoát ra trong lớp cha:

  1. Phương thức không bị ghi đè bởi lớp con, chỉ tồn tại trong lớp cha.

    Điều này giống với ví dụ của bạn, và nói chung tốt hơn là sử dụng $this -> get_species(); Bạn nói đúng rằng trong trường hợp này, cả hai phương thức này hoàn toàn giống nhau, nhưng phương thức đã được kế thừa bởi lớp con, vì vậy không có lý do gì để phân biệt. Bằng cách sử dụng, $thisbạn luôn nhất quán giữa các phương thức kế thừa và các phương thức được khai báo cục bộ.

  2. Phương thức được ghi đè bởi lớp con và có logic hoàn toàn duy nhất từ ​​lớp cha.

    Trong trường hợp này, bạn rõ ràng sẽ muốn sử dụng $this -> get_species();vì bạn không muốn phiên bản gốc của phương thức được thực thi. Một lần nữa, bằng cách sử dụng nhất quán $this, bạn không cần phải lo lắng về sự phân biệt giữa trường hợp này và trường hợp đầu tiên.

  3. Phương thức mở rộng lớp cha, thêm vào những gì phương thức cha đạt được.

    Trong trường hợp này, bạn vẫn muốn sử dụng `$this -> get_species();khi gọi phương thức từ các phương thức khác của lớp con. Một nơi bạn sẽ gọi phương thức mẹ sẽ là từ phương thức đang ghi đè phương thức mẹ. Thí dụ:

    abstract class Animal {
    
        function get_species() {
    
            echo "I am an animal.";
    
        }
    
     }
    
     class Dog extends Animal {
    
         function __construct(){
    
             $this->get_species();
         }
    
         function get_species(){
    
             parent::get_species();
             echo "More specifically, I am a dog.";
         }
    }
    

Kịch bản duy nhất tôi có thể tưởng tượng nơi bạn sẽ cần gọi phương thức cha trực tiếp bên ngoài phương thức ghi đè sẽ là nếu chúng thực hiện hai việc khác nhau và bạn biết rằng bạn cần phiên bản cha của phương thức, không phải cục bộ. Điều này không nên xảy ra, nhưng nếu nó tự xuất hiện, thì cách rõ ràng để tiếp cận điều này là tạo một phương thức mới với tên giống như get_parentSpecies()nơi mà tất cả những gì nó làm là gọi phương thức cha:

function get_parentSpecies(){

     parent::get_species();
}

Một lần nữa, điều này giữ cho mọi thứ tốt đẹp và nhất quán, cho phép thay đổi / sửa đổi phương thức cục bộ thay vì dựa vào phương thức mẹ.


làm thế nào tôi sẽ làm điều đó mà không có "mở rộng"? giống như tôi có một số "chân" mệnh đề bên trong lớp "con người" nhưng tôi không thực sự cần mở rộng nó, vì tôi không cần chức năng "con người" của cha mẹ. bây giờ, nếu tôi tạo một $leg = new leg()bên trong human, tôi sẽ gọi các hàm của con người từ bên trong một cá thể chân như $legthế nào?
user151496,

@ user151496 Chân không phải là lớp con của con người. Một con người có nhiều chân, nhưng một chân không phải là một loại người. Vì vậy, bạn không nên có một loại chân kế thừa từ con người, bởi vì một chân không phải là con người.
Beetle

Bạn có đặt Leg thành một lớp có giao diện của Leggy không? Hay chỉ có lớp Human thực hiện Leggy? Làm thế nào chúng ta có thể xác định rõ nhất rằng một đôi chân không chỉ dành riêng cho con người, mà cả đôi chân của con người cũng là tài sản duy nhất của con người và là tài sản chung của con người?
Anthony

2
paamayim nekudotayim hơi khó hiểu. Thoạt nhìn, có vẻ như bạn đang gọi một phương thức tĩnh. Thay vào đó, nó nên là cha mẹ-> get_species ()
peterchaula

Đã đồng ý. Các cuộc gọi tĩnh rất khó hiểu ở nhiều khía cạnh. Tôi nên cập nhật điều này vào một lúc nào đó.
Anthony

5

Trừ khi tôi hiểu sai câu hỏi, tôi hầu như sẽ luôn sử dụng $ this-> get_species vì ​​lớp con (trong trường hợp này là dog) có thể ghi đè phương thức đó vì nó mở rộng nó. Nếu class dog không xác định lại phương thức thì cả hai cách đều tương đương về mặt chức năng nhưng nếu tại một thời điểm nào đó trong tương lai bạn quyết định muốn phương thức get_species trong dog sẽ in ra "dog" thì bạn sẽ phải quay lại tất cả mã và thay đổi nó.

Khi bạn sử dụng $, nó thực sự là một phần của đối tượng mà bạn đã tạo và vì vậy cũng sẽ luôn được cập nhật mới nhất (nếu thuộc tính đang được sử dụng đã thay đổi bằng cách nào đó trong thời gian tồn tại của đối tượng) trong khi sử dụng lớp cha đang gọi phương thức lớp tĩnh.


đó là một điểm tốt khi sử dụng $ this trong trường hợp tôi muốn ghi đè phương thức. Cảm ơn
jerry
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.