Surcharge d'une fonction abstraite [Résolu]

Signaler
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
-
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
-
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

Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
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;
}
?>
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1
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 :)
Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
17
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...
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1
ok :)
merci à vous alors, je vais m'atteler là-dessus ! :)
Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
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;
}
?>
Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
17
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...
Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
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).
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1
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
Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
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;
}
?>
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1
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 :)