2010-12-22 2 views
1

Bit d'une question de base Je suppose, mais si je veux qu'un objet possède un autre objet de type A ou B, comment l'application utilisant l'objet peut-elle accéder aux attributs spécifiques? Par exemple.Accéder aux attributs concrets sur un objet abstrait?

public abstract class Animal 
{ 
    private int Age; 
    // Get Set 
} 

public class Tiger: Animal 
{ 
    private int NoStripes; 
    // Get Set 
} 

public class Lion : Animal 
{ 
    private bool HasMane; 
    // Get Set 
} 

public class Zoo 
{ 
    private Animal animal; 
    // Get Set 
} 

public static void Main() 
{ 
    Zoo zoo = new Zoo(); 
    zoo.animal = new Tiger(); 

    // want to set Tiger.NoStripes 
} 

Répondre

0

C'est l'essentiel de l'héritage et du polymorphisme.

Si vous êtes en mesure de déterminer si une instance d'animaux est en fait une instance de Tiger, vous pouvez lancer ce:

((Tiger)zoo.Animal).NoStripes = 1; 

Cependant, si vous essayez de faire faire sur une instance d'animal qui ISN 't un Tigre, vous obtiendrez une exception d'exécution.

par exemple:

Zoo zoo = new Zoo(); 
zoo.animal = new Tiger(); 
((Tiger)zoo.Animal).NoStripes = 1; //Works Fine 

((Lion)zoo.Animal).NoStripes = 1; //!Boom - The compiler allows this, but at runtime it will fail. 

Il y a une syntaxe de coulée alternative utilisant le « comme » mot-clé, qui renvoie null, au lieu d'une exception si la distribution échoue. Cela semble très bien, mais en pratique, vous risquez d'obtenir des bugs subtils plus tard lorsque l'objet nul est consommé.

Tiger temp = zoo.Animal as Tiger; //This will not throw an exception 
temp.NoStripes = 1; //This however, could throw a null reference exception - harder to debug 
zoo.Animal = temp; 

Pour éviter l'exception de référence null, null, vous pouvez vérifier bien sûr

Tiger temp = zoo.Animal as Tiger; //This will not throw an exception 
if (temp != null) 
{ 
    temp.NoStripes = 1; //This however, could throw a null reference exception - harder to debug 
    zoo.Animal = temp; 
} 
2

Vous devrez jeter zoo.Animal-Tiger

Ou vous pouvez essayer quelque chose comme

public abstract class Animal 
{ 
    public int Age; 
    // Get Set 
} 

public class Tiger : Animal 
{ 
    public int NoStripes; 
    // Get Set 
} 

public class Lion : Animal 
{ 
    public bool HasMane; 
    // Get Set 
} 

public class Zoo<T> where T : Animal 
{ 
    public T animal; 
    // Get Set 
} 

Zoo<Tiger> zoo = new Zoo<Tiger>(); 
zoo.animal = new Tiger(); 
zoo.animal.NoStripes = 1; 
0

La réponse directe est de faire

public static void Main() { 
    Zoo zoo = new Zoo(); 
    zoo.animal = new Tiger(); 

    ((Tiger)zoo.Animal).NoStripes = 10; 
} 

Bien sûr, pour que cela travailler, vous devez savoir que zoo.Animal est en fait un Tiger. Vous pouvez utiliser zoo.Animal is Tiger pour tester cela (bien que l'opérateur as soit préférable à is).

En général, cependant, concevoir votre programme ne sent pas très bon. Il est probable que le code que vous devrez écrire sera encombrant.

+0

D'accord, alors comment la contourner? Si vous avez un objet qui contiendra l'un ou l'autre, par ex. un garage a soit une voiture A ou une voiture B, alors quelle est la meilleure pratique de conception pour cela? Créer à la fois A et B dans l'objet contenant semble faux aussi ... – DAE

Questions connexes