Pływający kotek, czyli o korzystaniu z metod klasy A w obiekcie B.

pływający kotekDzisiaj Bartek odkrył interesującą rzecz o której ani On ani ja wcześniej nie wiedzieliśmy. Być może i ktoś z Was również o tym nie wie, więc chętnie opowiemy :) Generalnie chodzi o to że… koty nie pływają pod wodą…



przyjrzyjmy się przykładowemu kodowi:


class Fish {

public function BreathUnderwater(){
echo 'ok we can swim';
}

public function Breath(){
//$this is a cat, NOT A FISH
$this->BreathUnderwater();
}

}
class Cat {

public function Swim(){
Fish::Breath();
}

public function Breath(){
echo 'ok we can swim above water';
}

function BreathUnderwater(){
die('sink and die');
}

}

$Cat = new Cat();
$Cat->Swim();

?>

WYNIK:
sink and die

Gdyby kot chciał pływać pod wiodą i oddychać niczym ryba to niestety zginie…

function Swim(){

Cat::Breath();

}

WYNIK:
ok we can swim above water

Natomiast gdyby nasz kot oddychał jak każdy inny to na powierzchni wody na pewno uda mu popływać (o ile ma ochotę :) ).

Mówiąc językiem technicznym: w obiekcie można wywoływać metody z innych klas w sposób statyczny. Natomiast są one wywoływane z poziomu tego obiektu, czyli tak jak gdyby chwilowo były zaimplementowane w tym obiekcie ($this wskazuje na ten obiekt).

A może ktoś zna albo ma pomysł na jakieś praktyczne wykorzystanie tego rozwiązania?

Ten wpis umieszczono w kategorii PHP. Możesz dodać go do zakładek permalink. Dodaj komentarz lub dodaj odpowiedź (trackback): Trackback URL.

2 Komentarze

  1. Opublikowano 21 April, 2008 at 02:54 | Permalink

    Pytacie o praktyczne wykorzystanie… Ależ ono jest BANALNE! I na przykład w podobny sposób działa język Ruby. Tylko, że w nim nazywa się to Modułami ( keyword: module).

    A samo wykorzystanie pozwala na “prymitywne” bo prymitywne ale jednak rozszerzanie możliwości już istniejących klas w PHP o nowe funkcje właśnie dzięki takim zakresom zmiennych (tak coś takiego jeśli się nie mylę nazywa się w C++).

    Ale dość gadania, czas na przykład:

    class Animal {
    public function Walk(){
    echo “animal {$this->name} is walking”;
    }
    public function Eat() {
    echo “animal {$this->name} is eating”;
    }
    }

    class Mammal {
    public function CleanUpFur(){
    echo “Mammal {$this->name} is cleaning itself”;
    }
    }

    class Cat {

    public function __construct($name){
    $this->name = $name;
    }

    public function Hunt(){
    Animal::Walk();
    $this->Bite();
    Animal::Eat();
    Mammal::CleanUpFur();
    }

    private function Bite(){
    echo “Rrrroarrr! “;
    }
    }

    $kotek = new Cat(‘Mruczek’);

    >> animal Mruczek is walking
    >> Rrrroarrr!
    >> animal Mruczek is eating
    >> Mammal Mruczek is cleaning itself

    Taka technika pozwala na rozszerzanie mozliwości obiektów bez “zaśmiecania” ich przestrzeni nazw zbędnymi funkcjami.

    (przykład jest tylko obrazowy i pisany z głowy.)

    Ale jednak wygodniejsze ( bo pozbawione odwoływania się do składowych przez ::) jest zwykłe rozszerzanie możliwości klas (keyword: extends).

    Co Wy na to?

  2. Opublikowano 21 April, 2008 at 03:04 | Permalink

    Ale jednak wygodniejsze ( bo pozbawione odwoływania się do składowych przez ::) jest zwykłe rozszerzanie możliwości klas (keyword: extends).

    no właśnie… stosowanie extends jest zdecydowanie ładniejszym i bardziej przejrzystym rozwiązaniem. Aczkolwiek idąc Twoim tokiem rozumowania, w ten sposób można uzyskać “multi-dziedziczenie”? (w przenośni, bo o faktycznym dziedziczeniu nie ma tu mowy) To może być interesujące. Ciekawe jak wtedy zachowuje się ten przykład… trzeba to przećwiczyć ;)

    Taka technika pozwala na rozszerzanie możliwości obiektów bez “zaśmiecania” ich przestrzeni nazw zbędnymi funkcjami.

    Ciekawe jaki to ma wpływ (owe zaśmiecanie) na wydajność aplikacji

Skomentuj

Twój adres email nie zostanie opublikowany i nie będzie rozpowszechniany. Wymagane pola są oznaczone *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>