2009-08-11 8 views

Antwort

4

Normalerweise sind diese Methoden nützlich, wenn Sie mit einer API eines Drittanbieters kommunizieren oder wenn die Struktur der Methoden/Mitglieder unklar ist.

Nehmen wir an, Sie schreiben einen generischen XML-RPC-Wrapper. Da Sie die verfügbaren Methoden vor dem Herunterladen der WDL-Datei nicht kennen, ist es sinnvoll, Overloading zu verwenden.

Dann wird anstelle des Schreibens der folgende:

$xmlrpc->call_method('DoSomething', array($arg1, $arg2)); 

Sie verwenden können:

$xmlrpc->DoSomething($arg1, $arg2); 

, die eine natürlichere Syntax ist.


Sie können das Überladen von Elementen auch auf die gleiche Weise wie das Überladen von Methoden für variable Objekte verwenden.

Nur eine Sache, auf die Sie achten sollten: Beschränken Sie die Verwendung nur auf Objekte mit variabler Struktur oder verwenden Sie sie nur für syntaktische Verknüpfungen zu Getter und Setter. Es macht Sinn, Getter und Setter in Ihrer Klasse zu halten Business-Logik in mehreren Methoden zu trennen, aber es ist nichts falsch daran als eine Verknüpfung mit:

class ShortcutDemo { 
    function &__get($name) { 
    // Usually you want to make sure the method 
    // exists using method_exists, but for sake 
    // of simplicity of this demo, I will omit 
    // that logic. 
    return call_user_method('get'.$name, $this); 
    } 

    function __set($name, &$value) { 
    return call_user_method('set'.$name, $this, $value); 
    } 

    private $_Name; 

    function &getName() { return $this->_Name; } 
    function setName(&$value) { $this->_Name = $value; } 
} 

Auf diese Weise können Sie weiterhin Ihre Getter und Setter mit zu validieren und stellen Sie Ihre Daten, und verwenden immer noch die syntaktischen Verknüpfungen als solche:

$shortcut->Name = 'Hello'; 
0

andere Methode, die Andrew nicht erwähnt (oder überhaupt nicht zum Zeitpunkt des Schreibens erwähnt) ist für von Getter und Setter loszuwerden. Statt mit jedem Setter und Getter wie folgt zu erklären:

$obj->setName("Chacha"); 
$obj->setRep(10000000000000000000000); 

können Sie stattdessen nur tun

$obj->Name = "chacha"; 
$obj->Rep = 100000000000000000; 

Die zweite Methode ist natürlicher.

Magic Methods im Grunde weiter den Gedanken der objektorientierten Programmierung, und die Idee, wie Sie einen Job implementieren, sollte nach außen keine Rolle spielen. Mit den Magic-Methoden können Sie Ihre Variablen beliebig speichern und anderen Klassen auf natürliche Weise zuweisen.

Beispiel: Ich könnte alle Kontoeinstellungen meines Benutzers in einem einzigen Array speichern, wodurch es sehr einfach wäre, durchzublättern, um alles auf die Sitzung zu übertragen.

Wenn ich keine Magic-Methode dafür verwenden würde, müsste ich entweder eine Reihe von Sets oder Gets machen, was bedeutet, mehr Code schreiben oder direkten Zugriff auf das Array erlauben, was die Implementierung enthüllt, also ich kann nicht gehen und es später ändern.

Stattdessen, ich benutze Magic Methoden, habe ich nur sie setzen die Variable regelmäßig, und ich beschäftige mich intern.

+0

Obwohl ich noch nicht Getters und Setter loswerden würde. Mehrere Methoden, die Geschäftsregeln für die verschiedenen individuellen Eigenschaften enthalten, sind in der Regel leichter zu warten und zu debuggen als eine große Methode, die alle Geschäftsregeln für alle Eigenschaften enthält. Ich würde einfach '__get()' und '__set()' für eine Abkürzung verwenden, um 'getX',' setX' aufzurufen. Die Objektüberladung muss nur für variable Strukturobjekte beibehalten werden. –

+0

Lesen Sie meine aktualisierte Version. –

+0

Dies funktioniert jedoch nicht wirklich wie C# Get/Set-Eigenschaft. Zumindest nicht so flexibel, wenn Sie überprüfen oder validieren möchten, was eingestellt ist. – Extrakun

0

Sie können es für Fälle verwenden, in denen eine Klasse komplexe Regeln für isset und unset aufweist. Zum Beispiel könnte eine Klasse, die eine Variable $ a enthält, ein Array von Objekten oder anderen Ressourcen sein, und wenn sie nicht gesetzt sind, müssen sie einige andere Funktionalitäten ausführen.

Obwohl ich nicht sicher bin, warum sie das Hinzufügen einer neuen Eigenschaft und das Abrufen einer nicht privaten Eigenschaft erlauben, können Sie jedoch den internen Status eines Objekts ändern, indem Sie abhängig vom Namen des Objekts einen anderen Code aufrufen Eigenschaft/Mitgliedsvariable wird gesetzt.

In einigen Fällen ähnelt dieser Operator für C++

0

Nachricht Überlastung bei der Weiterleitung, wenn Sie komponiert haben oder Objekte zusammengefasst, wo Polymorphismus keine Option ist (sagen wir, Sie verwenden eine Bibliothek Klasse, die Sie nicht kontrollieren können,).

<?php 

// Class A is final, so we can't make subclasses. 
final class A 
{ 
    public function hello($callback) 
    { 
    echo call_user_func($callback, 'hello world'); 
    } 
} 

// so instead, we make a wrapper class that will take an instance 
// of A as an aggregate 
class B 
{ 
    private $a; 

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

    // this mimics inheritance on the aggregate object 
    // method calls are automatically forwarded to instance of A 
    // if they are valid 
    public function __call($method, $args) 
    { 
    if (method_exists($this->a, $method)) 
    { 
     return call_user_func_array(array($this->a, $method), $args); 
    } 
    throw new Exception("Method [$method] not found."); 
    } 
} 

class C extends B 
{ 
    // This mimics overriding an "inherited" method 
    public function hello($callback) 
    { 
    echo call_user_func($callback, 'bonjour le monde'); 
    } 
} 

$a = new A; 

$b = new B($a); 
$c = new C($a); 

$b->hello('strtoupper'); 
$c->hello('strtoupper'); 
0

Diese Funktion ist eigentlich what object oriented programming is all about, im Geist seines Erfinders Alan Kay: Objekte gegenseitig Nachrichten senden und möglicherweise auf jede Art von Nachricht zu reagieren. Methoden, die zur Kompilierzeit festgelegt werden, sind eine begrenzte (aber auch effizientere) Implementierung dieses Konzepts. Hier ist Kay's berühmtes Zitat: "Ich habe den Begriff objektorientiert erfunden, und ich kann Ihnen sagen, dass C++ nicht das war, was ich im Sinn hatte." kommt von.

Grundsätzlich ermöglicht es Objekte, auf Methodenaufrufe zu reagieren, ohne dass eine entsprechende Methode zur Kompilierzeit festgelegt wurde, diese ursprüngliche, breitere Definition der Objektorientierung. Die meisten modernen "dynamischen" Sprachen unterstützen es in der einen oder anderen Form.

Für was es gut ist: Werfen Sie einen Blick auf Groovy's Builders für ein gutes Beispiel. Im Grunde genommen ermöglicht es eine sehr kompakte Syntax mit niedriger Redundanz, indem Methodennamen selbst in Daten umgewandelt werden.

0

Ein Weg, der ein bisschen zarter ist, dass ich es verwendet habe, ist ein Linq wie Object Relational Management (ORM) System zu erstellen. Dort können Sie dann eine Datenbanktabellenstruktur laden und die Daten (aus der Datenbanktabelle) manipulieren, als wäre es nur ein Objekt.

d.h.

include('blibrary/bLinq.class.inc'); 

$linq = new bLinq(new bLinqSql('mysql://dsn')); 
$r = $linq->from('Users') 
      ->password 
      ->select(); 

, die auf die folgende SQL übersetzt:

SELECT `password` from Users; 

Die password in der SELECT-Anweisung von der überladenen Methode kommen.

Das Ergebnis kann wie verwendet werden:

(array)$r->password; // which outputs an array multiple results of password; 
(string)$r->password; // which outputs a string of the first password hash; 
$r->password[2];  // which outputs a string of the third password hash; 

Der Punkt ist, dass das Wort „password“ für andere Bereiche in der Datenbank im laufenden Betrieb ersetzt werden kann, wenn die Programmierung.

0

Ich verwende __get und __set, um Objekte miteinander zu verknüpfen, z.

Dies (normalerweise) ruft einige SQL-Verknüpfung users.id = profile.user_id.

0

Eigenschaften (wie in Python oder C#).Zum Beispiel, wenn Sie so etwas wie dieses in Nette verwenden, erstellen Sie eine Klasse, die eine bestimmte Eigenschaft als öffentliche zeigt:

<?php 
class Foo extends Object 
{ 
    public $bar; 
} 

können Sie diese Eigenschaft Zugriff auf natürliche Weise - $instance->bar. Aber wenn Sie einige Validierung usw. tun wollen, fügen Sie einfach Getter und Setter:

<?php 
class Foo extends Object 
{ 
    private $bar; 

    public function getBar() 
    { 
     return $this->bar; 
    } 

    public function setBar($bar) 
    { 
     if ($bar === NULL) throw new Exception('…'); 
     $this->bar = $bar; 
    } 
} 

Und Sie verwenden noch $instance->bar. Aber wenn Sie $instance->bar = NULL; tun, ist es wie $instance->setBar(NULL); aufrufen.

Verwandte Themen