Có thể có một giao diện có các phương thức riêng tư / được bảo vệ không?


76

Có thể trong PHP 5 có một giao diện có các phương thức riêng tư / được bảo vệ không?

Ngay bây giờ tôi có:

interface iService
{
    private method1();
}

Điều đó gây ra một lỗi:

Lỗi phân tích cú pháp: lỗi cú pháp, T_STRING không mong muốn, mong đợi T_VARIABLE

Tôi chỉ muốn xác nhận rằng đó là trường hợp giao diện chỉ có thể chứa các phương thức công khai.


2
Tôi thấy câu trả lời thật đáng thất vọng. Tôi cũng muốn các giao diện hỗ trợ các phương thức được bảo vệ / riêng tư. Ví dụ: tôi có một lớp, trong đó một phương thức công khai, được triển khai trong phần tóm tắt, dựa trên một phương thức được bảo vệ được thực hiện bởi lớp con. Tôi muốn sử dụng một giao diện để yêu cầu các lớp con triển khai các phương thức được bảo vệ theo yêu cầu của các phương thức công khai trừu tượng.
Stoutie 29/10/12

4
Sử dụng một lớp cơ sở trừu tượng cho mục đích đó. Bạn có thể kết hợp hai cách tiếp cận: phương thức công khai trong giao diện, triển khai các phương thức đó trong một lớp cơ sở trừu tượng định nghĩa (và dựa vào) các phương thức trừu tượng được bảo vệ.
Stijn de Witt

2
Nếu bạn có thể khai báo các phương thức riêng tư hoặc được bảo vệ, thì private function method1 ();không private method1();.
tvanc

Câu trả lời:


130

Các PHP thủ công trang về giao diện một cách rõ ràng rằng:

Tất cả các phương thức được khai báo trong một giao diện phải được công khai; đây là bản chất của một giao diện.

Tôi đoán điều này giải thích lỗi bạn đang gặp phải ;-)


20

Giao diện được sử dụng để mô tả các phương thức công khai của một lớp thực hiện giao diện đó. Bạn không bao giờ có thể có một phương thức riêng tư trong một giao diện. Bất kỳ phương thức nào trong một giao diện được coi là đang được sử dụng và không được thay đổi.

Giao diện là liên kết PHP, nhưng đây là tiêu chuẩn trong lập trình OO.


1
trong các ngôn ngữ khác như java, bạn có thể sử dụng công cụ sửa đổi quyền truy cập trong các giao diện.
Người dùng123456,

9

Nói chung, một giao diện chỉ có thể có các thành viên công khai, vì chức năng duy nhất của một giao diện là được kế thừa.

Từ hướng dẫn PHPfreaks.com:

PHP5 có các giao diện. Không nên nhầm lẫn với các giao diện theo nghĩa chung hơn, từ khóa interface tạo ra một thực thể có thể được sử dụng để thực thi một giao diện chung trên các lớp mà không cần phải mở rộng chúng như với các lớp trừu tượng. Thay vào đó, một giao diện được triển khai.

Các giao diện khác với các lớp trừu tượng. Đối với một, chúng thực sự không phải là lớp học. Chúng không xác định thuộc tính và chúng không xác định bất kỳ hành vi nào. Các phương thức được khai báo trong một giao diện phải được khai báo trong các lớp thực thi nó.

Bởi vì giao diện theo nghĩa chung hơn là định nghĩa về cách một đối tượng tương tác với mã khác, nên tất cả các phương thức phải được khai báo công khai (xem phần về khả năng hiển thị trong chương này). Sử dụng các lớp trừu tượng, một phương thức trừu tượng có thể có bất kỳ khả năng hiển thị nào, nhưng các lớp mở rộng phải có các triển khai của chúng sử dụng cùng một khả năng hiển thị (hoặc yếu hơn). Việc triển khai một giao diện sẽ thêm các phương thức dưới dạng phương thức trừu tượng vào lớp chủ thể, nếu không triển khai nó sẽ dẫn đến lỗi như sau:

Lỗi nghiêm trọng: Lớp SomeConcreteClass chứa n (các) phương thức trừu tượng và do đó phải được khai báo là trừu tượng hoặc triển khai các phương thức còn lại Có, các lớp trừu tượng có thể triển khai các giao diện.


4
Quá tệ. Bởi vì tôi muốn có một phương thức công khai, được yêu cầu bởi giao diện, được triển khai trong một lớp trừu tượng, dựa trên một phương thức được bảo vệ cũng được thực thi bởi giao diện. Bằng cách này, lớp trừu tượng có thể cung cấp giao diện công khai, nhưng tùy thuộc vào các lớp con để triển khai logic cơ bản. Có lý?
Stoutie 29/10/12

4
Có vẻ như bạn muốn phương thức được thực thi bởi lớp con là trừu tượng. Sau đó, bất kỳ lớp con nào PHẢI triển khai nó. Nhưng nó không liên quan gì đến giao diện.
Sven

6

các giao diện là các khai báo kiểu. một loại là tập hợp các giá trị, cộng với một tập hợp các hoạt động có thể được thực hiện từ bên ngoài. một phương pháp riêng không phù hợp với hình ảnh này.

interface T {
  public /*int*/ function f(array $a);
}
interface U {
  public /*T*/ function g(T $t);
}

class C implements U {
    public function g(T $t) {
        ...
        $x = $t->f();
        ...
    }
}

giao diện hữu ích vì chúng chỉ ra giao diện của các đối tượng. cách các đối tượng giao tiếp với môi trường của chúng.

bây giờ giả sử T::fcó thể được khai báo riêng tư. làm thế nào điều đó sẽ hữu ích cho các đối tượng khác? nó sẽ không thể được gọi từ bên ngoài, nó sẽ không phải là một phần của giao diện của nó.


Đồng ý ... Nhưng nó có thể được bảo vệ phải không? Vì các lớp trừu tượng cho phép ...
asdfasdfasdf

4

Trong nhiều trường hợp, định nghĩa giao diện giúp các mô-đun khác đảm bảo hành vi và API của một lớp. Trong những trường hợp đó, các phương thức riêng không phải là thứ mà các mô-đun khác có thể truy cập hoặc hiểu được. Đó là lý do tại sao bạn không bao giờ có thể đặt các phương thức riêng tư trên một giao diện.


0

Không lớn , bất kỳ phương thức nào trong Giao diện sẽ không bao giờ có định danh truy cập riêng tư hoặc được bảo vệ.

** Tất cả các phương thức được khai báo trong một giao diện phải là công khai; đây là bản chất của một giao diện.

Một số thông tin thú vị khác về giao diện

Các giao diện có thể được mở rộng như các lớp bằng cách sử dụng toán tử mở rộng. Họ chỉ có thể mở rộng các giao diện khác. (nguồn: https://www.php.net/manual/en/language.oop5.interfaces.php )

Lưu ý rằng có thể khai báo một phương thức khởi tạo trong một giao diện, điều này có thể hữu ích trong một số ngữ cảnh, ví dụ như cho các nhà máy sử dụng. Chữ ký phải giống nhau ở lớp con.

Trong trường hợp của bạn, thậm chí một vấn đề khác là - từ khóa hàm bị thiếu trong khai báo hàm. Nó nên được

interface iService
{
    public function method1();
}

0

Như đã nêu, các giao diện chỉ có thể xác định các phương thức hiển thị công khai. Tôi muốn đưa ra một ví dụ về cách các phương thức được bảo vệ có thể được xử lý. Để áp đặt việc sử dụng các phương thức được bảo vệ cụ thể, có thể tạo một lớp trừu tượng thực hiện giao diện.

Điều này đặc biệt có ý nghĩa nếu lớp trừu tượng đã có thể xử lý một số khối lượng công việc, để đơn giản hóa việc triển khai thực tế. Ví dụ ở đây, một lớp trừu tượng đảm nhiệm việc khởi tạo đối tượng kết quả, đối tượng này luôn cần thiết:

Trước hết, giao diện.

interface iService
{
   /**
    * The method expects an instance of ServiceResult to be returned.
    * @return ServiceResult
    */
    public function doSomething();
}

Sau đó, lớp trừu tượng xác định cấu trúc phương thức bên trong:

abstract class AbstractService implements iService
{
    public function doSomething()
    {
        // prepare the result instance, so extending classes
        // do not have to do it manually themselves.
        $result = new ServiceResult();

        $this->process($result);

        return $result;
    }

   /**
    * Force all classes that extend this to implement
    * this method.
    *
    * @param ServiceResult $result
    */
    abstract protected function process($result);
}

Lớp thực hiện việc triển khai thực tế sẽ tự động kế thừa giao diện từ lớp trừu tượng và chỉ cần triển khai phương thức được bảo vệ.

class ExampleService extends AbstractService
{
    protected function process($result)
    {
         $result->setSuccess('All done');
    }
}

Bằng cách này, giao diện hoàn thành hợp đồng chung và thông qua AbstractServicelớp, hợp đồng nội bộ được thực hiện. Ứng dụng chỉ cần thực thi việc sử dụng AbstractServicelớp ở bất kỳ nơi nào có thể.

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.