2011-08-19 14 views
8

Tôi có một lớp con cần trả về một lớp con của kiểu trả về của lớp cha của nó. Tôi tin rằng đây được gọi là một kiểu trả về biến đổi. Tôi tự hỏi cách đơn giản nhất để chuyển đổi từ cha mẹ sang lớp con.Cách OO thích hợp để chuyển đổi một đối tượng thành một trong các lớp con của nó (kiểu trả về biến đổi) là gì?

class A { 
} 
class B extends A { 
    function bar() { 
    } 
} 

class Car { 
    function foo() { 
    return new A(); 
    } 
} 

class BrokenCar extends Car { 
    function foo() { 
    $a = parent::foo(); 
    //What is the cleanest way to convert $a to type B ? 
    } 
} 

Trả lời

8

Trong PHP, bạn không thể "chuyển đổi" đối tượng từ loại/lớp A sang B bằng tính năng có sẵn bằng ngôn ngữ.

Tuy nhiên, bạn có thể làm như vậy bằng cách sử dụng tuần tự hóa nếu các đối tượng của bạn hỗ trợ nó (thường là các đối tượng PHP cũ đơn giản hỗ trợ tuần tự hóa). Trong hình thức serailized bạn thay đổi lớp của đối tượng và unserialize nó một lần nữa. A đã biến thành B rồi. Nhưng điều đó không thực sự trôi chảy.

2

Điều này thực sự phải là một nhận xét, nhưng tôi sẽ làm cho một điểm quan trọng.

Lập trình là kỹ thuật và lập trình được thiết kế. Không có cách nào để nói tại sao thiết kế A là tốt hơn so với thiết kế B mà không biết làm thế nào nó sẽ được sử dụng. Hãy hỏi một nhà thiết kế, nút gửi của bạn có phải là màu đỏ hoặc xanh lục không - và cô ấy nói: hmm, ở đâu, trên trang web nào? Yêu cầu một kỹ sư nếu bạn nên sử dụng một chùm hoặc một bánh răng couping - và câu trả lời sẽ là: phụ thuộc vào những gì cho. Vì vậy, điều khiến bạn nghĩ chúng tôi có thể cung cấp cho bạn lời khuyên thiết kế có ý nghĩa, nếu bạn chỉ cho chúng tôi một lớp "BrokenCar" với phương pháp "foo". Hãy cho chúng tôi những gì bạn thực sự muốn đạt được với điều đó, nếu không thì câu trả lời duy nhất tôi có thể đưa ra là

cách tốt nhất để sử dụng foo là thanh

+1

Xin lỗi vì ví dụ mơ hồ ... Tôi đã cố gắng đơn giản hóa những gì tôi đã làm có lẽ quá nhiều. Tôi muốn minh họa rằng 'B' cung cấp các phương thức bổ sung không tồn tại trong 'A'. 'B' cũng ghi đè một số phương thức từ 'A' trong mã thực của tôi. Tôi có thể sao chép logic trong các phương pháp ghi đè và sau đó chỉ cần bỏ gọi phương thức 'foo' của cha mẹ chút nào đó, nhưng đó là rất nhiều sự trùng lặp. –

2

Như hakre tuyên bố, đúc để người dùng định nghĩa loại không natively thể trong PHP (theo như tôi biết).

gì bạn có thể làm là tạo ra một phương pháp trong một trong hai lớp A hoặc B. Một cái gì đó như:

class A 
{ 
    public static function fromB(B $object) 
    { 
     /* your routine to convert an object of class B to an instance of class A */ 
    } 

    /* or */ 

    public static function fromA(A $object) 
    { 
     /* your routine to convert any object that is a subclass of A to a concrete instance of class A */ 
    } 
} 

hoặc

class B 
    extends A 
{ 
    // this method could even be implemented in A already as well actually 
    public function toA() 
    { 
     /* your routine to convert this object to an object of class A */ 
    } 
} 

Trong ví dụ đầu tiên factory method đầu tiên có thể có vấn đề, vì nó yêu cầu A có kiến ​​thức cụ thể về một lớp con cụ thể. Bạn cần phải xác định xem điều này là mong muốn trong tình huống của bạn. Có lẽ bạn có thể tóm tắt điều này để phương thức factory chấp nhận đối tượng kế thừa từ A, giống như phương thức factory thứ hai.

Trong ví dụ thứ hai, B tự động đã biết về A, bởi vì nó kế thừa từ nó. Điều này có thể được mong muốn hơn. Nhưng hãy nghĩ về nó, điều này thậm chí có thể đã được thực hiện trong A, vì vậy mà phương thức này sẽ tự động có sẵn trong tất cả các lớp con của A rồi.