2011-10-26 4 views
13

Tại sao tôi không thể sử dụng mã như thế này?Tại sao PHP không có hàm tạo mặc định?

<?php 

class NoConstructor { 
} 

class ChildWithConstructor extends NoConstructor { 
    public function __construct() { 
     parent::__construct(); 
     // do something 
    } 
} 

$foo = new ChildWithConstructor(); 
// **Fatal error: Cannot call constructor in file.php on line 8** 

Ví dụ: Các lớp Java có mặc định, không có hàm tạo args. Nó có thể được gọi ngay cả khi nó không được xác định rõ ràng.

Hành vi của PHP có thể gây ra sự cố khi chúng tôi xóa không có hàm tạo args nào từ lớp cha, ví dụ: khi chúng tôi nghĩ rằng nó không cần thiết nữa.

Có ai biết tại sao người sáng tạo PHP làm theo cách này không?

+1

Bên cạnh câu hỏi của bạn, bạn nên biết rằng bạn có thể giải quyết vấn đề này: kiểm tra sự tồn tại của hàm trước cuộc gọi. –

+6

Những người tạo PHP đã thực hiện một * nhiều * quyết định ngớ ngẩn ... –

+1

http://www.php.net/manual/en/function.is-callable.php: if (is_callable ('parent :: __ construct')) { parent :: __ construct(); } –

Trả lời

20

lớp Java có mặc định, không có constructor args.

Có ai biết tại sao người sáng tạo PHP làm theo cách này không?

Java là ngôn ngữ được lập kế hoạch. Nó được xem xét một cách nghiêm ngặt và chính thức được chỉ định từ lúc bắt đầu. Nó được thiết kế để kéo dài càng lâu càng tốt với những thay đổi tối thiểu vì lợi ích của sự tương thích ngược và chuyển tiếp, để đơn giản cho các nhà phát triển và những người thực hiện như nhau. Chắc chắn không thành công với mức độ mà họ hy vọng, nhưng bạn vẫn có thể lấy mã Java 1.0, biên dịch nó và chạy nó trên các máy ảo hiện đại.

Các nhà thiết kế của PHP chưa bao giờ lên kế hoạch cho ngôn ngữ gần đến mức cực đoan như vậy. Họ làm cho nó lên khi họ đi cùng. Đối với tốt hơn hoặc tệ hơn, họ đang sẵn sàng để ném ngôn ngữ ngoài và xây dựng lại nó trong phiên bản tiếp theo. Nó đã thay đổi không thể nhận ra kể từ PHP 1 và 2. Thậm chí gần đây, trong PHP 5, bạn đã có sự thay đổi đáng kể từ các giá trị theo giá trị đến các tham chiếu theo tham chiếu cho các đối tượng.Đó là cùng một phương pháp tuyệt vời đã mang đến cho chúng tôi các trích dẫn kỳ diệu, thiếu Unicode, không nhất quán được đặt tên (và thường xuyên đổi tên) và một trình phân tích cú pháp mà không hề có lỗi (thậm chí với error_reporting(-1);), sẽ vui vẻ diễn giải số 09 bằng chữ số như 0 .

Hành vi của PHP có thể gây ra rắc rối khi chúng tôi xóa không có hàm tạo args từ lớp cha, ví dụ: khi chúng tôi nghĩ rằng nó không cần thiết nữa.

Bạn có thể yêu cầu điều này được thay đổi trên bugs.php.net, nhưng rất có thể họ sẽ bỏ qua hoặc bỏ qua bạn với "Xin lỗi, nhưng vấn đề của bạn không có nghĩa là vấn đề trong chính PHP ... ".

+2

+1, đây là câu trả lời duy nhất giải quyết các câu hỏi. – Brad

1

Trước PHP 5, hàm tạo có cùng tên với lớp, như JAVA. Trong PHP 5, một lớp có thể có một phương thức khởi tạo có cùng tên với lớp (nếu không phải trong một không gian tên) hoặc được đặt tên là __construct. Có thể nó có liên quan đến điều đó.

4

Như chúng ta đã thấy với 5.3.7 disaster, việc phát triển PHP có thể cần một số tính ổn định hơn. Bên cạnh đó PHP là khác nhau trong nhiều cách khác nhau.

  • Enterprise sao lưu không có trong cùng một giải đấu (không Oracle, không có IBM, vv)
  • PHP là cũ, và đôi khi không phù hợp
  • PHP Interpreter (Zend Engine) có để có thể làm hết sức rất nhiều, bằng cách hỗ trợ rất nhiều cấu trúc kế thừa và mô hình lập trình.
  • Nguồn gốc của PHP là ngôn ngữ kịch bản đơn giản dành cho người có sở thích.

Tôi thực sự thích PHP và làm việc với nó hàng ngày, nhưng đôi khi nó chỉ là một chút gian lận. Mặt khác, nếu bạn loại bỏ __construct() có hai điều bạn nên cân nhắc.

  1. Không bao giờ làm điều đó, chỉ có sản phẩm nào các nhà xây dựng
  2. Nếu bạn đang xây dựng một khuôn khổ thực hiện chức năng init một khái niệm cốt lõi vì đây là thậm chí thực hành tốt.

tôi muốn nói điều này:

class BaseClass { 
    public function __construct() { 
     if(method_exists($this, 'init') { 
      $this->init(); 
     } 
    } 
} 
1

Dòng

parent::__construct(); 

là một cuộc gọi rõ ràng để các nhà xây dựng của lớp cha mẹ. "PHP" đang cung cấp cho bạn một lỗi vì nó không tồn tại.

Bạn có thể thực sự gọi một hàm khởi tạo không tồn tại của cha mẹ trong Java và không nhận được lỗi không?

Hãy nhớ rằng hàm tạo của lớp mở rộng lớp cha sẽ ghi đè hàm tạo của lớp cha khi lớp mở rộng được tạo. Gọi một hàm tạo cha mẹ ngụ ý rằng bạn đang mong đợi nó làm điều gì đó. Nếu hàm tạo không tồn tại thì cuộc gọi của bạn đến nó không thuộc về mã cho dù trình thông dịch có cho bạn lỗi hay không.

+0

Trong Java không có thứ gì như một lớp không có một hàm tạo - trình biên dịch sẽ thêm một nếu nó không được viết trong mã nguồn. Xem https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.8.9 – bdsl