2012-04-09 18 views
6

Tôi đang cố gắng mở rộng một lớp PHP mà không cần viết lại toàn bộ điều. Dưới đây là một ví dụ:Làm thế nào một lớp PHP có thể mở rộng thêm một hàm riêng khác?

<? 
$a = new foo(); 
print $a->xxx(); 
$b = new bar(); 
print $b->xxx(); 

class foo { 
    const something = 10; 

    public function xxx() { 
    $this->setSomething(); 
    return $this->something; 
    } 

    private function setSomething() { 
    $this->something = self::something; 
    } 
} 

class bar extends foo { 

    public function xxx() { 
    $this->setSomething(); 
    $this->something++; 
    return $this->something; 
    } 

} 
?> 

Tuy nhiên khi tôi chạy kịch bản tôi nhận được lỗi sau:

Fatal error: Call to private method foo::setSomething() from context 'bar' in test.php on line 23 

Có vẻ như thanh mà không kế thừa các chức năng setSomething tin(). Làm thế nào tôi sửa lỗi này mà không sửa đổi lớp foo?

+0

Bạn không thể thay đổi 'setSomething()' thành 'được bảo vệ'? – alex

+0

Như tôi đã nói ở trên, lớp foo không được sửa đổi. Làm cách nào khác tôi có thể làm điều này? –

+0

Bạn sử dụng đúng công cụ cho công việc, nghĩa là, bảo vệ nó 'bảo vệ'. – alex

Trả lời

4

barkế thừa chức năng ổn, nhưng nó không thể gọi nó. Đó là toàn bộ các điểm của phương thức private, chỉ lớp khai báo mới có thể gọi chúng.

+0

Vì vậy, tôi sẽ phải xác định lại setSomething() một cách rõ ràng trong lớp bar của tôi? –

+1

Vâng, đó là phương pháp * sane * để thực hiện việc này. – deceze

+5

Phương pháp tốt hơn là sử dụng bảo vệ trong lớp cha mẹ;) theo cách đó nó vẫn ở chế độ riêng tư từ bên ngoài, nhưng lớp "con" có thể truy cập nó. –

6

Thành viên riêng tư không được kế thừa, bạn không thể sử dụng chúng trong lớp con. Họ không thể truy cập bên ngoài lớp học.

Bạn phải thực hiện chức năng đó là được bảo vệ hoặc công khai. Các thành viên được bảo vệ có thể truy cập vào lớp đó và cho lớp được kế thừa. Vì vậy, đặt cược tốt nhất của bạn là làm cho chức năng đó được bảo vệ.

+0

Như tôi đã nói ở trên, lớp foo không được sửa đổi. Làm cách nào khác tôi có thể làm điều này? –

+0

@KennethVogt: Bạn không có lựa chọn nào ở đây. –

13

Không, bạn không thể sửa lỗi này mà không sửa đổi lớp foo. Bởi vì một lớp được kế thừa không thể truy cập các thành viên riêng của lớp cha. Đó là quy tắc rất cơ bản.

Khai báo setSomething()protected. Nó sẽ được giải quyết.

Xem manual

+0

Như tôi đã nói ở trên, lớp foo không được sửa đổi. Làm cách nào khác tôi có thể làm điều này? –

+0

Bạn không thể làm điều đó miễn là duy trì oop. –

0

Không sửa đổi lớp gốc, không có cách nào để lớp được kế thừa gọi trực tiếp private phương thức của lớp cha.

0

Bạn thử này?

class bar extends foo { 

    public function xxx() { 
     $this->something = parent::xxx(); 
     $this->something++; 
     return $this->something; 
    } 
} 

Lưu ý parent :: xxx(); là công khai, vì vậy nó sẽ hoạt động ... mặc dù nó trông giống như một cuộc gọi tĩnh.

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