2015-10-14 5 views
5

Volevo creare un'interfaccia in PHP, ma non volevo che fosse troppo restrittivo su quale tipo di argomento avrebbe accettato in uno dei metodi pubblici. Non volevo fareL'interfaccia PHP accetta l'argomento dell'interfaccia?

interface myInterface { 
    public function a(myClass $a); 
} 

Perché io non può decidere di passare un'istanza di myClass. Ma, voglio assicurarmi che l'oggetto passato sia conforme a determinati parametri, che potrei realizzare definendo un'interfaccia. Così ho pensato di specificare le classi che usano le interfacce, in questo modo:

<?php 

interface iA {} 
interface iB {} 

interface iC { 
    public function takes_a(iA $a); 
    public function takes_b(iB $b); 
} 

class apple implements iA {} 
class bananna implements iB {} 

class obj implements iC { 
    public function takes_a(apple $a) {} 
    public function takes_b(bananna $b) {} 
} 

Ma, ottengo l'errore PHP Fatal error: Declaration of obj::takes_a() must be compatible with iC::takes_a(iA $a) on line 15

Esiste un modo garantire che un argomento accetta solo una classe di una certa interfaccia? O forse sto pensando troppo a questo?

+0

quando si implementa l'interfaccia, la firma dei metodi deve essere lo stesso nell'interfaccia. ('funzione pubblica take_a (iA $ a);' nella tua classe obj) ma puoi passare apple su questa istanza. '$ o = nuovo obj(); $ o-> takes_a (nuova mela()); ' –

+0

@ RaphaelMüller Non capisco cosa stai dicendo-- So come passare un oggetto mela. L'aggiunta della tua linea alla fine dello script non la rende compilabile; si lamenta ancora della firma della funzione che non corrisponde. – user151841

+4

vedere https://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29. Restringendo in basso 'takes_a()' per consentire solo "apple" non si disabilitano altri "iA", ma l'interfaccia iC richiede di accettare _any_ iA come parametro. – VolkerK

risposta

3

Il tuo concetto è completamente corretto. C'è solo una piccola parte sbagliata. I metodi delle tue classi devono avere la stessa firma di quella specificata nell'interfaccia.

come VolkerK detto:

vedere wikipedia. Con il restringimento di take_a() per consentire solo "apple" non si accettano altri "iA", ma l'interfaccia iC richiede di accettare qualsiasi iA come parametro. - VolkerK

con questo in mente vedere il codice corretto:

<?php 

interface iA { 
    function printtest(); 
} 
interface iB { 
    function play(); 
} 

//since an interface only have public methods you shouldn't use the verb public 
interface iC { 
    function takes_a(iA $a); 
    function takes_b(iB $b); 
} 

class apple implements iA { 
    public function printtest() 
    { 
     echo "print apple"; 
    } 
} 
class bananna implements iB { 
    public function play() 
    { 
     echo "play banana"; 
    } 
} 

//the signatures of the functions which implement your interface must be the same as specified in your interface 
class obj implements iC { 
    public function takes_a(iA $a) { 
     $a->printtest(); 
    } 
    public function takes_b(iB $b) { 
     $b->play(); 
    } 
} 

$o = new obj(); 

$o->takes_a(new apple()); 
$o->takes_b(new bananna());