Domanda

dire che ho avuto una classe SuperClass e due sottoclassi SubClassA e SubClassB che ereditano da superclasse.

 abstract class SuperClass{
   ...
   List someList;
   ...
 }

 class SubClassA extends SuperClass{
   ...
   List<String> someList;
   ...
 }

 class SubClassB extends SuperClass{
   ...
   List<Integer> someList;
   ...
 }

In questo modo è conveniente perché posso ottenere someList.size() in Superclass ed avere sicurezza rispetto ai tipi nelle sottoclassi. Il problema è che non "sentire" a destra, si può pensare a potenziali pericoli questa suddetto approccio ha che io non sono a conoscenza?

È stato utile?

Soluzione

Per prima cosa, qualsiasi metodo di SuperClass vede la lista superclasse, non quello della sottoclasse. Questo porta quasi sicuramente a bug sottili. Per esempio. quando si dice

  

posso ottenere someList.size() in Superclass

quello che in realtà è la dimensione della lista in Superclass, non quello della sottoclasse. L'elenco superclasse può essere vuota mentre la lista sottoclasse contiene elementi (o viceversa).

La ragione di questo è che SubClassA.someList non sostituisce in alcun modo o sostituzione Superclass.someList - solo ombre, così i metodi delle sottoclassi vedono SubClassA.someList invece di Superclass.someList. Tuttavia, questo non ha assolutamente alcun effetto in Superclass. I metodi possono essere fatte virtuale (e in Java, che sono di default), ma i membri dati non possono.

Altri suggerimenti

Questa è una pessima idea. Ti davvero desidera un'istanza di una sottoclasse di avere due liste? Perché questo è ciò che sta accadendo. Si sta dichiarando una seconda variabile - così il codice nella superclasse utilizzerà una variabile, e il codice nella sottoclasse utilizzerà un'altra. Questo è solo in cerca di guai, IMO.

Credo che si dovrebbe piuttosto definire un metodo al posto della variabile membro della classe. In modo che si sarà in grado di implementare i metodi nelle classi secondarie e non c'è bisogno di preoccuparsi per la sicurezza tipo.

Sostituire variabile con metodo che suggerisco.

Grazie.

sembra rompere IS-A e il principio di sostituzione Liskov a me. Se si dispone di una collezione di istanze superclasse, ognuno dei quali può essere SubClassA o SubClassB, avrai un comportamento sorprendente al meglio.

Non farlo.

Forse qualcosa usando farmaci generici sarebbe meglio:

public class X<T>
{
    private List<T> list;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top