2010-01-09 49 views
5

Câu hỏi được chỉnh sửa để phản ánh tốt hơn nhu cầu của tôi.Gọi các phương thức lớp cha mẹ


Lấy ví dụ sau đây:

class Base 
{ 
    public $Text = null; 

    public function __construct() 
    { 
     $this->Text = new Base_Text(); 
    } 
} 

class Base_Text extends Base 
{ 
    public $Is = null; 

    public function __construct() 
    { 
     $this->Is = new Base_Text_Is(); 
    } 

    public function CammelCase($string) 
    { 
     return trim(str_replace(' ', '', ucwords($string))); 
    } 
} 

class Base_Text_Is extends Base_Text 
{ 
    public function CammelCase($string) 
    { 
     return ($string === $this->CammelCase($string)); // doesn't work 
    } 
} 

Làm thế nào tôi có thể sửa chữa phương pháp Base_Text_Is::CammelCase() mà không gọi lớp Base_Text tĩnh (không sử dụng parent:: hoặc Base_Text::)?

Giải pháp duy nhất tôi đã đưa ra cho loại tình huống này là để tạo ra một hàm singleton như thế này:

function Base() 
{ 
    static $instance = null; 

    if (is_null($instance) === true) 
    { 
     $instance = new Base(); 
    } 

    return $instance; 
} 

Và thay đổi phương pháp Base_Text_Is::CammelCase() này:

return ($string === Base()->Text->CammelCase($string)); 

Và để để tránh tạo hai trường hợp đối tượng của lớp Cơ sở, thay vì làm:

$base = new Base(); 
$base->Text->Is->CammelCase('MethodOverloading'); // true 

Tôi chỉ cần làm:

Base()->Text->Is->CammelCase('MethodOverloading'); // true 

Đây có phải là thực tiễn tốt không? Có bất kỳ giải pháp khác?

+0

I don' t nhận được bình luận cuối cùng của bạn trong câu trả lời của Darrell. Bạn không thể truy cập thuộc tính tĩnh của 'Base_Text'? Từ nơi nào bạn muốn gọi cho họ? Tôi nghĩ bạn nên giải thích thêm điều này. –

+0

@Felix: Tôi đang cố gắng giữ ví dụ đơn giản nhất có thể, có những trường hợp khi tôi không thể gọi một phương thức cha mẹ tĩnh bởi vì nó phụ thuộc vào các thuộc tính được tạo nhanh. –

Trả lời

7

Trái tim của câu hỏi của bạn nằm ở đây:

Làm thế nào có thể Sơn :: B() gọi cha :: A() phương pháp không tĩnh (không sử dụng cha mẹ hoặc cha)?

Câu trả lời đơn giản là không thể. Bạn overrode Dad::A() với Son::A(). Khái niệm duy nhất của A() rằng đối tượng Sơn bây giờ có là riêng của nó A(). Bạn sẽ phải gọi phương thức gốc theo cách tĩnh hoặc trên một đối tượng hoàn toàn khác nhau Dad đối tượng.

Điểm mấu chốt là, nếu bạn muốn gọi phương thức cha mẹ A(), tại sao bạn lại bận tâm ghi đè nó ở địa điểm đầu tiên?

Cấu trúc của bạn cũng không có ý nghĩa gì. Tại sao bạn muốn có một cuộc gọi đến số $dad->A() chuyển số điện thoại này tới số $dad->son->A(), lần lượt gọi số $dad->son->B(), sau đó, từ những gì bạn đang yêu cầu, hãy gọi lại $dad->A()? Đó là một vòng lặp vô hạn.

Cách tiếp cận singleton của bạn dường như không mang lại lợi ích thực sự nào ngoài việc đảm bảo bạn không khởi tạo nhiều đối tượng cha, nhưng thực tế là bạn vẫn đang tạo ra một đối tượng hoàn toàn riêng biệt nó phải ở trong lớp và không ở bên ngoài.

Nếu không nhìn thấy logic thực tế và những gì bạn đang cố gắng hoàn thành, thật khó để biết nên giới thiệu gì để tránh sự phụ thuộc vòng tròn này. Tuy nhiên, tôi nghĩ bạn có thể muốn phân tích những gì bạn đang cố gắng làm với các phương pháp này và có lẽ thiết kế lại cách thức hoạt động của kế thừa.

EDIT

Tôi nghĩ rằng bạn đã có quá nhiều thừa kế xảy ra. Không có lý do nào bạn nên làm điều này:

$base = new Base(); 
$base->Text->Is->CammelCase('MethodOverloading'); // true 

Nếu tất cả chức năng nằm trong lớp học, bạn không nên khởi tạo lớp Base. Nó phải là một cái gì đó như thế này:

$text = new Text(); 
$text->isCamelCase('someString'); 

Mã của bạn có thể được đơn giản hóa rất nhiều, với tất cả các phụ huynh/instantiations con tròn loại bỏ và các chức năng cụ thể đẩy xuống các lớp con:

class Base 
{ 
    //don't put anything related to child classes here, 
    //unless it is going to provide specific functionality 
} 

class Text extends Base 
{ 
    public function CamelCase($string) 
    { 
     return trim(str_replace(' ', '', ucwords($string))); 
    } 

    public function isCamelCase($string) 
    { 
     return ($string === $this->CamelCase($string)); 
    } 
} 
+0

Đó là một ví dụ giả định tất nhiên, và tôi biết đó là một vòng lặp vô hạn. Tuy nhiên, tôi đã gặp phải các ứng dụng hữu ích trong thế giới thực cho điều này và tôi đã luôn sử dụng giải pháp mà tôi đã cung cấp trong câu hỏi của mình. Tôi chỉ tự hỏi nếu có thể có bất kỳ sự thay thế nào tốt hơn. –

+0

Tôi đã cập nhật câu hỏi để đưa ra một ví dụ thực tế hơn và giải quyết một số vấn đề bạn đề cập, chẳng hạn như "khởi tạo một đối tượng hoàn toàn riêng biệt". Hy vọng nó làm cho nó một chút rõ ràng hơn bây giờ. –

+0

@zombat: Tôi chỉ muốn hỏi, trong bản chỉnh sửa cuối cùng của tôi, nếu bạn vẫn nghĩ rằng việc thiết kế lại thừa kế là một ý tưởng hay (nếu có, bất kỳ con trỏ nào?) Và nếu sử dụng hàm 'sing()' singleton thực hành không tốt trong kịch bản này. –

1

Tôi không nghĩ rằng có một cách để gọi một phương thức cha mẹ từ đứa trẻ với gọi nó là tĩnh hoặc sử dụng parent::. Mặc dù vậy, tôi có thể hiểu nhầm câu hỏi. Tạo một thể hiện của Son() không tạo ra hai đối tượng. Con trai mở rộng bố nhưng nó vẫn là một vật thể.

Nếu bạn định gọi cho Bố() với một Singleton trong Sơn thì tại sao lại kéo dài từ Sơn?

+0

Tôi đã cập nhật câu hỏi của mình bằng một ví dụ thực tế hơn, vui lòng kiểm tra. –

+0

Tôi vẫn không hiểu sự ác cảm của bạn khi sử dụng 'parent ::'. –

+0

Nó không phải là một sự ác cảm, tôi chỉ không thể sử dụng nó bởi vì nếu tôi làm tôi sẽ không thể truy cập thuộc tính không phải 'Base_Text'. –

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