2010-08-02 4 views
0

cela fonctionne pour moi, mais il semble correct en termes de meilleures pratiques as3. Est-il correct de retourner null si elle échoue?AS3 override addChild(), test pour le type

 override public function addChild(child:DisplayObject):DisplayObject { 
     if(child is Screen) { 
      super.addChild(child); 
      return child; 
     } 

     return null; 
    } 

Répondre

0

Je vois un couple d'options et aucun ne se sent complètement "juste".

La meilleure solution, comme je le vois, n'est pas possible dans Actionscript (je pense que cela est autorisé dans d'autres langues). Cela est, déclare que vous accepterez que les instances de l'écran:

override public function addChild(child:Screen):Screen { 
    return super.addChild(child); 
} 

Depuis ce n'est pas possible, les autres options que je peux penser serait:

1) Lancer une erreur.

Je ne suis généralement pas très friands d'erreurs de lancement, mais un pro ici est qu'il correspond au comportement de la classe étendue. Si vous passez un objet d'affichage non valide à addChild, il sera lancé. D'un autre côté, ceci est valide étant donné que la signature de la méthode vous indique que vous devez passer un DisplayObject. Dans ce cas, votre méthode est "menteuse", d'une certaine manière, car elle dit qu'elle accepte DisplayObjects mais qu'elle n'accepte en réalité que des instances de Screen. Vous vous fiez donc à la documentation (espérons-le) plutôt que sur le système de type pour indiquer au code utilisateur comment il est supposé utiliser votre fonction.

2) Ajout d'une méthode addScreen qui appelle addChild.

public function addScreen(child:Screen):Screen { 
    return super.addChild(child) as Screen; 
} 

C'est un peu plus typé, mais vous perdez quelques-uns des advatanges de polymorphisme (et peut-être il est impossible/réalisable dans votre code). Peut-être que si nous avions une méthode surchargée ... mais nous ne le faisons pas, encore une fois, je suppose que c'est un compromis.

3) Vérification du type d'exécution et retour de la valeur null en cas d'échec.

Voici ce que fait votre code. Cela pourrait être très bien. Ce que je n'aime pas c'est ce que j'ai mentionné plus haut: que votre méthode est une sorte de "mensonge". Je ne m'attends pas à une méthode qui provoque l'échec d'un objet DisplayObject car j'ai transmis un objet DisplayObject. Mais bon, parfois, ce n'est pas un gros problème. Je crains de ne pouvoir donner une réponse définitive à ce sujet. Si possible, je pense que j'irais probablement avec l'option 2), mais toutes ces options semblent également valables. À un moment donné, il faut se contenter de celui qui a le plus de sens pour vous et votre projet, je suppose.

1

Je ne vois pas pourquoi pas. En pratique, je n'ai jamais utilisé la valeur de retour de addChild. Vous auriez besoin d'une certaine façon de savoir si l'enfant avait été ajouté afin que vous pouvez ensuite utiliser:

if (!addChild(child)) 
{ 
    //couldn't be added 
} 

au lieu de

if (child is Screen) 
{ 
    addChild(child); 
} 
else 
{ 
    // couldn't be added 
} 

Ou vous pourriez plutôt jeter une erreur dans votre override et attraper que si ce n'est pas une instance de Screen.

Je ne pense pas que ce soit un problème de bonne pratique du tout si cela fonctionne pour vous.

+0

Voici pourquoi: var enfant: Shape = new Shape(); var conteneur: DisplayObjectContainer = instanceOfScreen; container.addChild (enfant) .x = 100;/* lancera une exception de pointeur NULL */ container.removeChild (enfant);/* lancera une erreur, car le DisplayObject fourni doit être un enfant du conteneur, lequel ce n'est pas le cas, bien qu'il ait été ajouté juste une ligne au-dessus de */je le ferais -1, mais c'est une erreur si commune, je ne blâmerais personne. Tout est la faute de C++. :RÉ – back2dos

0

Il n'y a pas de bonne façon de faire, ce que vous voulez. Si vous voulez le comportement souhaité, vous devez utiliser la composition au lieu de l'héritage. Ce que vous essayez de faire est de violer le Liskov substitution principle.