« Redéfinition » variables d'instance dans le sous-type: risques possibles?
-
30-09-2019 - |
Question
Say I avait une classe et deux sous-classes SuperClass SubClassA et SubClassB héritant de superclasse.
abstract class SuperClass{
...
List someList;
...
}
class SubClassA extends SuperClass{
...
List<String> someList;
...
}
class SubClassB extends SuperClass{
...
List<Integer> someList;
...
}
De cette façon, il est pratique parce que je peux obtenir someList.size()
dans Superclass
et ont dans les sous-Sûreté du typage.
Le problème est que ce ne est pas « sensation », peut vous faire penser à des dangers potentiels ce apporach a que je ne suis pas au courant?
La solution
D'une part, toute méthode de SuperClass
voit la liste des superclasse, pas celle de la sous-classe. Cela conduit presque à coup sûr à des bugs subtils. Par exemple. quand vous dites
Je peux obtenir
someList.size()
dansSuperclass
ce que vous obtenez est en fait la taille de la liste Superclass
, pas celle de la sous-classe. La liste des superclasse peut être vide alors que la liste de sous-classe contient des éléments (ou vice versa).
La raison derrière cela est que SubClassA.someList
ne remplace en aucun cas ou override Superclass.someList
- il ombres juste, de sorte que les méthodes de sous-classe au lieu de voir SubClassA.someList
Superclass.someList
. Cependant, cela n'a absolument aucun effet dans Superclass
. Les méthodes peuvent être virtuelles (et en Java, ils sont par défaut), mais les membres de données ne peut pas.
Autres conseils
Ceci est une très mauvaise idée. Avez-vous vraiment voulez une instance de la sous-classe soit d'avoir deux listes ? Parce que ce qui se passe. Vous déclarer une seconde variable - si le code dans la superclasse utilisera une variable, et le code dans la sous-classe utilisera une autre. C'est juste d'avoir des ennuis, l'OMI.
Je pense que vous devriez plutôt définir une méthode au lieu de la variable de membre de classe. Alors que vous serez en mesure de mettre en œuvre des méthodes dans vos sous-classes et ne pas à se soucier de la sécurité de type.
Remplacer la variable avec la méthode que je propose.
merci.
Il semble briser IS-A et le Liskov principe de substitution pour moi. Si vous avez une collection d'instances superclasse, dont chacun peut être SubClassA ou SubClassB, vous aurez un comportement surprenant au mieux.
Ne pas le faire.
Peut-être quelque chose en utilisant les médicaments génériques serait mieux:
public class X<T>
{
private List<T> list;
}