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ę.
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ę.
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.
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
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
Jak 'Klasa C używać T {}' być inna niż to, co my już (oprócz nieco innej składni)? – Jon
Skrócona składnia, gdy chcę rozszerzyć niektóre klasy z klasy bazowej, ale z wykorzystaniem cech (-y). – Meglio
@Meglio: Po prostu zrób to: 'Klasa C rozszerza Bazę {użyj T}'. – hakre