2012-04-07 6 views
20

Dlaczego nie możemy rozszerzać funkcji z klasami w PHP?Rozszerzać cechy z klasami w PHP?

Na przykład:

Trait T { } 

Class C use T {} 
/* or */ 
Class C extends T {} 

Czy istnieje potencjalny konflikt na taką składnię? Nie sądzę.

+0

Jak 'Klasa C używać T {}' być inna niż to, co my już (oprócz nieco innej składni)? – Jon

+0

Skrócona składnia, gdy chcę rozszerzyć niektóre klasy z klasy bazowej, ale z wykorzystaniem cech (-y). – Meglio

+1

@Meglio: Po prostu zrób to: 'Klasa C rozszerza Bazę {użyj T}'. – hakre

Odpowiedz

5

Tylko klasy można przedłużyć. Cechy to klasy , a nie. Mogą być używane/uwzględniane przez klasy, ale same nie są klasami. Jeśli uważasz, że cecha musi zostać rozszerzona, prawdopodobnie powinna to być klasa, prawdopodobnie abstrakcyjna, a nie cecha.

+0

Pomysł jest tutaj na krótszą składnię, a nie na sposób, aby rzeczywiście rozszerzyć cechy. – Meglio

+3

@Meglio: składnia nie ma długości, więc nie ma krótszej składni. – hakre

+0

Krótsza notacja. – Meglio

31

PZP ręczne stwierdza więc:

Cechy to mechanizm ponownego wykorzystania kodu w pojedynczych języków dziedziczenia takich jak PHP. Cecha ma na celu ograniczenie pewnych ograniczeń pojedynczego dziedziczenia poprzez umożliwienie twórcy ponownego użycia zestawów metod w kilku niezależnych klasach żyjących w różnych hierarchiach klas. Semantyka kombinacji Cech i klas jest definiowana w sposób, który zmniejsza złożoność i unika typowych problemów związanych z dziedziczeniem wielokrotnym i Mieszankami.

Jeśli chcesz rozszerzyć cechę, powinna to być klasa. Jeśli masz zestaw metod w jednej klasie, z których chcesz korzystać w innych, ale nie wydaje ci się, aby rozszerzyć klasę (np. class Animal extends Vehicle), to w PHP 5.4 może to dobrze działać jako cecha.

Aby odpowiedzieć na to pytanie bardziej bezpośrednio, nie "rozszerzasz" cechy, ale możesz tworzyć cechy, które same wykorzystują inne cechy. Zgodnie z podręcznika PHP:

trait Hello { 
    public function sayHello() { 
     echo 'Hello '; 
    } 
} 

trait World { 
    public function sayWorld() { 
     echo 'World!'; 
    } 
} 

trait HelloWorld { 
    use Hello, World; 
} 

class MyHelloWorld { 
    use HelloWorld; 
} 

Można rozważyć, że jest to sposób, aby utrzymać swoje cechy w logiczne grupy i wprowadzić pewne modułowość.

Edycja: po obejrzeniu niektórych komentarzy, myślę, że warto zauważyć, że używanie cechy w klasie bazowej oznacza również, że cecha jest w dowolnej klasie, która ją rozszerza, a funkcje cechy mają pierwszeństwo przed klasą podstawową " . Umieszczenie go w klasie potomnej sprawiłoby, że funkcje cechy były niedostępne dla klasy nadrzędnej/podstawowej.

Parent > Trait > Child 

http://php.net/manual/en/language.oop5.traits.php

11

można rozszerzyć cechy nieco. Rozszerzając odpowiedź mrlee, po use cechę można zmienić nazwy jej metod.

powiedzmy na przykład masz „nadrzędny” cechę, która została zdefiniowana przez ramowa:

trait FrameworkTrait { 
    public function keepMe() { 
     // Framework's logic that you want to keep 
    } 

    public function replaceMe() { 
     // Framework's logic that you need to overwrite 
    } 
} 

prostu wyciągnąć z cechą dominującą, zmienić swoją metodę replaceMe do czegoś innego, i określić swoją własną metodę replaceMe.

trait MyTrait { 
    use FrameworkTrait { 
     FrameworkTrait::replaceMe as frameworkReplaceMe; 
    } 

    public function replaceMe() { 
     // You can even call the "parent" method if you'd like: 
     $this->frameworkReplaceMe(); 

     // Your logic here 
    } 
} 

A potem w swojej klasie:

class MyClass { 
    use MyTrait; 
} 

Teraz obiektów tej klasy może to zrobić:

$obj = new MyClass(); 

$obj->keepMe();    // calls "parent" trait 
$obj->replaceMe();   // calls "child" trait 
$obj->frameworkReplaceMe(); // calls "parent" trait