2015-10-04 18 views
6

Tôi gặp vấn đề chung với trường hợp sử dụng này: Tôi có một lớp A. Lớp này có phương thức không trừu tượng doStuffCallback() có thể bị ghi đè nhưng không cần thiết cho mọi lớp con. Nhưng: Tôi muốn đảm bảo rằng nếu phương pháp được overriden subclass-method phải gọi phương thức cha mẹ.OOP (PHP) - Buộc phương thức ghi đè để gọi theo phương thức gốc

Ví dụ:

abstract class A { 
    private function doStuff() { 
     $this->doStuffCallback(); 
    } 

    protected function doStuffCallback() { 
     // IMPORTANT CODE HERE 
    } 
} 

class B extends A { 
    protected function doStuffCallback() { 
     parent::doStuffCallback(); // I want to enforce this because the parents method code is important 

     // ALSO IMPORTANT CODE 
    } 
} 

Bởi vì phương pháp ghi đè làm điều tương tự nó sẽ rất xấu xí để xác định hai phương pháp cho trách nhiệm tương tự và một helper-method private trong đó kêu gọi cả hai. Như thế này:

abstract class A { 
    private function doStuff() { 
     $this->callDoStuffCallback(); 
    } 

    private function callDoStuffCallback() { 
     $this->internalDoStuffCallback(); 
     $this->doStuffCallback(); 

     // This is VERY ugly 
    } 

    private function internalDoStuffCallback() { 
     // IMPORTANT CODE HERE 
    } 

    protected function doStuffCallback() {} 
} 

class B extends A { 
    protected function doStuffCallback() { 
     // IMPORTANT CODE 
    } 
} 

Điều này thực sự xấu và mất thời gian. Vì vậy, câu hỏi của tôi: Có cách nào trong PHP để buộc các phương pháp overriden để gọi phương pháp cha mẹ?

Trả lời

6

số Không có tính năng ngôn ngữ như vậy trong PHP; hạn chế này là không thể trong hầu hết các ngôn ngữ subtype-'OO '.

Các chương trình thay thế phải dựa vào các hợp đồng tài liệu rõ ràng; và hy vọng, thử nghiệm đơn vị để đảm bảo sự phù hợp.


vệ cũng có thể được sử dụng như vậy mà, tại một số điểm bằng mọi cách khi một phương thức trên lớp cha mẹ được sử dụng, nó có thể ném một ngoại lệ nếu 'tình trạng hiện thời' không hợp lệ (ví dụ. Như vậy và một phương pháp như vậy vẫn chưa được gọi). Điều này cũng có thể được thực hiện rõ ràng hơn bằng cách làm cho lớp con cần thiết để gọi (như được định nghĩa trong hợp đồng tài liệu) một số phương pháp đặc biệt, thay vì chỉ đơn giản là phương pháp siêu overriden. Tuy nhiên, đó là bên ngoài của bất kỳ loại hệ thống.

Trong khi self:: phạm vi thể được sử dụng (. Ví dụ như gọi phương thức phi overriden trong đó kêu gọi phương pháp overriden), điều này sẽ liên quan đến kỳ diệu hơn nữa để tránh lặp đệ quy vô hạn (ví dụ như một số trạng thái stack.); và sẽ dễ dàng vô tình bỏ qua việc sử dụng.

Khuyến nghị của tôi là gọi phương thức "riêng tư" gọi phương thức 'có thể overriden' này trong mối quan hệ với bất kỳ logic nào được áp dụng, như được hiển thị trong ví dụ (mặc dù hy vọng có nhiều nhiệm vụ cụ thể hơn). Sau đó, phương pháp overriden (được bảo vệ) không được mong đợi hoặc cần thiết để xử lý bất kỳ logic đặc biệt nào; cũng không phải là nó được gọi trực tiếp bên ngoài bối cảnh được thiết lập bởi lớp cha - nó chỉ là những gì nó hiện đang yêu cầu, một cuộc gọi lại đặc biệt.

+0

Cảm ơn câu trả lời của bạn! Tôi nghĩ chính xác như vậy. Tôi tin rằng OOP chúng tôi sử dụng hiện nay chưa hoàn thành. Có rất nhiều khía cạnh còn lại quan trọng nhưng không được xử lý. –

-2

Không, bạn có thể truy cập, bạn có thể sử dụng phương pháp cho phụ huynh, như thế này

<?php 

class A { 

    function s1($p1) { 
     echo 's1: '.$p1; 
    } 
} 


class B extends A { 

    public function callParent($method, $p1) { 
     parent::$method($p1); 
    } 
} 


$b = new B(); 

$b->callParent('s1', 'param1'); 

hoặc thay thế mở rộng về phương pháp kỳ diệu __call và vv https://github.com/StagnantIce/php_extend_magic/blob/master/AExtendClass.php

+0

Cách này giải quyết được sự cố của tôi? Tôi nghĩ rằng đây là một giải pháp ít thông minh hơn là chỉ mong đợi phân lớp thực hiện đúng với tài liệu (gọi phương thức cha mẹ khi ghi đè). Tôi có nghĩa là các ví dụ của bạn yêu cầu MỌI KHÁCH HÀNG của lớp và không chỉ chính lớp đã được triển khai phải gọi phương thức cha mẹ phản xạ khôn ngoan. Đây là phương pháp tiếp cận trực quan và không an toàn nhất mà tôi từng thấy. Không có vi phạm :) –

2

Tôi có xu hướng không đồng ý với "Đây là RẤT xấu xí". Đây là cách tiêu chuẩn để xử lý trường hợp sử dụng này và một biến thể của Template Method Pattern.

Bây giờ tôi chỉ đoán vì bạn không cung cấp một ví dụ thực sự nhưng nếu bạn nói rằng hai phương pháp "làm cùng một điều", có thể có điều gì đó sai với thiết kế của bạn. Nếu họ làm điều tương tự, tại sao lại gọi thực thi cha mẹ cần thiết nếu phân lớp thực hiện điều tương tự theo một cách khác?Đối với tôi, có vẻ như phương pháp thực sự là nhiều hơn một điều và bạn có thể chia nhỏ thành nhiều phần có thể bị ghi đè riêng lẻ (hoặc không, sau đó đặt riêng tư hoặc cuối cùng).

+0

Có, "điều tương tự" không phải là thuật ngữ chính xác ở đây. Các phương thức này có cùng trách nhiệm nhưng phương thức lớp con mở rộng nó cho các yêu cầu bổ sung riêng của nó. –

Các vấn đề liên quan