Surcharge d'une fonction abstraite

Résolu
codefalse Messages postés 1123 Date d'inscription mardi 8 janvier 2002 Statut Modérateur Dernière intervention 21 avril 2009 - 17 déc. 2007 à 15:11
codefalse Messages postés 1123 Date d'inscription mardi 8 janvier 2002 Statut Modérateur Dernière intervention 21 avril 2009 - 18 déc. 2007 à 21:37
Bonjour à tous :)
J'ai un petit soucis syntaxique, j'aimerai votre avis avant de continuer.

J'ai une classe
abstract class genericReader {} qui contient des fonction abstraites (par exemple read)
Le truc, c'est que j'aurai une classe fille "file" et une classe fille "socket".
class file extends genericReader
classe socket extends genericReader

Dans chaque classes filles, il se peux que j'ai, plus tard des classes filles.

L'idée, c'est que je veux que la fonction read soit implémentée dans chaques classses instanciables (file, socket, etc).
Mais je ne peux pas déclarer une classe read (); dans genericReader, et mettre dans class file extends genericReader une fonction read ($sPathToFile) et dans socket extends genericReader, une fonction read ($host, $port, $file);

Comment faire cela ?
Est-ce que je doit déclarer une fonction abstraite qui prendre le maximum de parametres (dans ce cas 3) et ignorer les deux autres dans la classe "file" ?

Ou y-a-t-il une solution plus "logique" et surtout plus "performante"

10 réponses

malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
17 déc. 2007 à 18:09
Hello,

tu peux très bien utiliser func_get_args() et cie :

<?php
abstract class A {
    abstract public function myFunc();
}

class B extends A {
    public function myFunc() {
        $aArgs = func_get_args();
        if(count($aArgs) !== 1 || (isset($aArgs[0]) && !is_int($aArgs[0]))) {
            throw new Exception(__FUNCTION__.' required 1 parameter which must  be an integer');
        }
        echo 'B succeeded';
    }
}

class C extends A {
    public function myFunc() {
        $aArgs = func_get_args();
        if(count($aArgs) !== 2 || (isset($aArgs[0]) && !is_int($aArgs[0])) || (isset($aArgs[1]) && !is_string($aArgs[1]))) {
            throw new Exception(__FUNCTION__.' required 2 parameter, the 1st one must be an integer and the second one must be a string');
        }
        echo 'C succeeded';
    }
}
try {
    $b = new B;
    $b->myFunc();
} catch(Exception $e) {
    try {
        $b->myFunc(5);
        $c = new C;
        $c->myFunc(5);
    } catch(Exception $exc) {
        $c->myFunc(5, 'toto');
        echo $exc;
    }
    echo $e;
}
?>
3
codefalse Messages postés 1123 Date d'inscription mardi 8 janvier 2002 Statut Modérateur Dernière intervention 21 avril 2009 1
17 déc. 2007 à 19:33
J'y ai pensé, et faire aussi un list ($var1, $var2, etc), mais je me suis dit que ca allait alourdir le traitement et qu'il devait y avoir une méthode plus légére.
C'est vraiment la meilleure méthode ?
Et est-ce la bonne voie que j'emploi la ?

Merci en tout cas pour ta réponse Malalam :)
0
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
18 déc. 2007 à 13:55
Salut,

Je sais pas si c'est la meilleure méthode, mais les fonction func_get_args() et func_num_args() existent, c'est pour une raison : servir dans le cas d'arguments variables. C'est ton cas ici, autant les utiliser...
Et puis si c'est pas la meilleure méthode, pour ma part, je n'en vois pas d'autre...
0
codefalse Messages postés 1123 Date d'inscription mardi 8 janvier 2002 Statut Modérateur Dernière intervention 21 avril 2009 1
18 déc. 2007 à 14:18
ok :)
merci à vous alors, je vais m'atteler là-dessus ! :)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
18 déc. 2007 à 19:12
Boah, d'autres façons, il y en a, mais je ne suis pas sûr qu'elles soient moins lourdes.
Par exemple...:-) :

<?php
abstract class A {
    abstract public function myGenericFunc(FuncObj $o);
}

abstract class FuncObj {
    protected $aParams;
   
    abstract public function mySpecificFunc();
}

class FuncObj1 extends FuncObj {
    public function __construct($aParams) {
        if(count($aParams) !== 1 || !isset($aParams[0]) || !is_int($aParams[0])) {
            throw new Exception('Params array must have only 1 entry wich must be an integer');
        }
        $this->aParams = $aParams;
    }
   
    public function mySpecificFunc() {
        echo 'Param : '.$this->aParams[0];
    }
}

class FuncObj2 extends FuncObj {
    public function __construct($aParams) {
        if(count($aParams) !== 2 || !isset($aParams[0]) || !isset($aParams[1]) || !is_int($aParams[0]) || !is_string($aParams[1])) {
            throw new Exception('Params array must have only 2 e,tries, the 1st one being an integer and the 2d one being a string');
        }
        $this->aParams = $aParams;
    }
   
    public function mySpecificFunc() {
        echo 'Param 1 : '.$this->aParams[0]. ' and param 2 :'.$this->aParams[1];
    }
}

class B extends A {
    public function myGenericFunc(FuncObj $o) {
        if(!$o instanceof FuncObj1) {
            throw new Exception('Object must be an instance of FuncObj1');
        }
        $o->mySpecificFunc();
    }
}

class C extends A {
    public function myGenericFunc(FuncObj $o) {
        if(!$o instanceof FuncObj2) {
            throw new Exception('Object must be an instance of FuncObj2');
        }
        $o->mySpecificFunc();
    }
}

try {
    $b = new B;
    $c = new C;
    $b->myGenericFunc(new FuncObj1(array(5)));
    $c->myGenericFunc(new FuncObj2(array(5, 'toto')));   
    $c->myGenericFunc(new FuncObj1(array(2)));   
} catch(Exception $e) {
    echo $e;
}
?>
0
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
18 déc. 2007 à 19:16
Bah oui, j'avais bien pensé à ça, mais en fait, dans le principe, c'est pas bien différent : Dans ton premier exemple, on récupère les arguments dans un tableau avec func_get_args(), là, le tableau est tout prêt. Sinon, c'est pareil...
0
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
18 déc. 2007 à 19:26
Tout à fait, sauf que là, en réalité, le principe ne serait pas d'avoir X objets étendant A, mais un seul...et son comportement varieraiot en fonction de l'objet de type FuncObj qu'on lui passerait. Qui lui, serait déterminé en fonction du contexte (bref, de la stratégie à adopter).
0
codefalse Messages postés 1123 Date d'inscription mardi 8 janvier 2002 Statut Modérateur Dernière intervention 21 avril 2009 1
18 déc. 2007 à 20:45
perso je trouve la deuxieme méthode plus lourde :) et plus complexe à mettre en oeuvre, si on imagine que j'ai 5 niveau d'extends, avec à chaque fois des parametres différents, ca va faire beaucoup de classes en plus :p
0
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
18 déc. 2007 à 21:26
bah oui, j'ai proposé l'autre d'abord hein lol.
Mais celle-ci peut-être très utile dans ce cas-ci :

<?php
abstract class A {
    abstract public function myGenericFunc(FuncObj $o);
}

abstract class FuncObj {
    protected $aParams;
   
    abstract public function mySpecificFunc();
}

class FuncObj1 extends FuncObj {
    public function __construct($aParams) {
        if(count($aParams) !== 1 || !isset($aParams[0]) || !is_int($aParams[0])) {
            throw new Exception('Params array must have only 1 entry wich must be an integer');
        }
        $this->aParams = $aParams;
    }
   
    public function mySpecificFunc() {
        echo 'Param : '.$this->aParams[0];
    }
}

class FuncObj2 extends FuncObj {
    public function __construct($aParams) {
        if(count($aParams) !== 2 || !isset($aParams[0]) || !isset($aParams[1]) || !is_int($aParams[0]) || !is_string($aParams[1])) {
            throw new Exception('Params array must have only 2 e,tries, the 1st one being an integer and the 2d one being a string');
        }
        $this->aParams = $aParams;
    }
   
    public function mySpecificFunc() {
        echo 'Param 1 : '.$this->aParams[0]. ' and param 2 :'.$this->aParams[1];
    }
}

class B extends A {
    public function myGenericFunc(FuncObj $o) {
        $o->mySpecificFunc();
    }
}

try {
    $b = new B;
    $b->myGenericFunc(new FuncObj1(array(5)));
    $b->myGenericFunc(new FuncObj2(array(5, 'toto')));   
} catch(Exception $e) {
    echo $e;
}
?>
0
codefalse Messages postés 1123 Date d'inscription mardi 8 janvier 2002 Statut Modérateur Dernière intervention 21 avril 2009 1
18 déc. 2007 à 21:37
en fait là tu es en train de nous faire une sorte de surcharge à la java ... mais en php ? :p

Ok je vois le truc :)
Mais en effet, niveau code et simplicité, je partirai sur la premiere :)
En tout cas merci de vos aides :)
0
Rejoignez-nous