2011-10-26 13 views
13

Dlaczego nie mogę użyć takiego kodu?Dlaczego PHP nie ma domyślnego konstruktora?

<?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** 

Np. Klasy Java mają domyślny, bez konstruktora args. Można go wywołać, nawet jeśli nie jest zdefiniowany jawnie.

Zachowanie PHP może powodować problemy, gdy nie usuniemy żadnego konstruktora args z klasy nadrzędnej, np. kiedy myślimy, że nie jest już potrzebna.

Czy ktoś wie, dlaczego twórcy PHP zrobili to w ten sposób?

+1

Oprócz pytania, które należy zadać, należy wspomnieć, że można obejść to: sprawdzić funkcjonowanie przed wywołaniem. –

+6

Twórcy PHP zrobili * wiele * niemądrych decyzji ... –

+1

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

Odpowiedz

20

klas Javy, nie ma domyślnego konstruktora args.

Czy ktoś wie, dlaczego twórcy PHP zrobili to w ten sposób?

Java była językiem planowym. Został dokładnie przemyślany i formalnie określony od samego początku. Miał on trwać tak długo, jak to możliwe, przy minimalnych zmianach ze względu na kompatybilność wsteczną i do przodu, dla uproszczenia zarówno dla programistów, jak i realizatorów. Zdecydowanie nie udało się osiągnąć takiego poziomu, na jaki liczyły, ale nadal można wziąć kod Java 1.0, skompilować go i uruchomić na nowoczesnych maszynach wirtualnych.

Programiści PHP nigdy nie planowali języka do takiej skrajności. Robią to, kiedy idą dalej. Na lepsze lub na gorsze, są umiarkowanie chętni do wyrzucenia tego języka i odbudowania go w następnej wersji. Zmieniło się to nierozpoznawalnie od PHP 1 i 2. Jeszcze niedawno, w PHP 5, nastąpiła dramatyczna zmiana z wartości by-zależnej na semantykę odniesienia dla obiektów.To ta sama genialna metodologia, która przyniosła nam magiczne cytaty, brak Unicode, niekonsekwentnie nazwane (i często przemianowane) funkcje oraz parser, który bez nawet śladu błędu (nawet z error_reporting(-1);), z radością zinterpretuje numeryczny literał 09 jako 0 .

Zachowanie PHP może powodować problemy, gdy nie usuniemy konstruktora args z klasy nadrzędnej, np. kiedy myślimy, że nie jest już potrzebna.

Można zażądać to być zmienione na bugs.php.net, ale są szanse, oni go zignorować lub fob cię z „Przykro mi, ale twój problem nie oznacza problemu w samym PHP ... ".

+2

+1, jest to jedyna odpowiedź, która odpowiada na pytanie. – Brad

1

Przed PHP 5 konstruktor miał taką samą nazwę jak klasa, podobnie jak JAVA. W PHP 5 klasa może mieć metodę konstruktora o tej samej nazwie co klasa (jeśli nie w przestrzeni nazw) lub o nazwie __construct. Może to ma coś z tym wspólnego.

4

Jak widzieliśmy z 5.3.7 disaster, rozwój PHP może wymagać nieco większej stabilności. Poza tym PHP różni się na wiele innych sposobów.

  • Przedsiębiorstwo zapasowa nie jest w tej samej lidze (brak danych Oracle, nie IBM, etc.)
  • PHP jest stary, a czasem niespójne
  • PHP Interpreter (Zend Engine) musi być w stanie zrobić strasznie wiele, wspierając tak wiele starszych konstrukcji i paradygmatów programowania.
  • Pochodzenie PHP jest prostym językiem skryptowym dla hobbystów.

Bardzo lubię PHP i pracuję z nim codziennie, ale czasami jest to po prostu odrobina dziwactwa. Z drugiej strony, jeśli usuniesz __construct(), powinieneś rozważyć dwie rzeczy.

  1. Nigdy nie zrobić to, po prostu opróżnić konstruktora
  2. Jeśli budujesz ramy sprawiają startowych funkcjonuje pojęcie rdzenia, gdyż są to nawet dobra praktyka.

Znaczy to:

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

Linia

parent::__construct(); 

jest jawne wywołanie konstruktora klasy nadrzędnej. "PHP" daje błąd, ponieważ nie istnieje.

Czy rzeczywiście możesz wywołać nieistniejący konstruktor nadrzędny w Javie i nie uzyskać błędu?

Należy pamiętać, że konstruktor klasy rozszerzającej klasę nadrzędną nadpisze konstruktor klasy nadrzędnej podczas konstruowania klasy rozszerzającej. Wywołanie rodzica konstruktora oznacza, że ​​oczekujesz, że coś zrobi. Jeśli konstruktor nie istnieje, twoje wywołanie nie jest w kodzie, czy tłumacz daje błąd, czy nie.

+0

W Javie nie ma czegoś takiego jak klasa bez konstruktora - kompilator dodaje jeden, jeśli nie jest napisany w kodzie źródłowym. Zobacz https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.8.9 – bdsl

Powiązane problemy