views:

53

answers:

4

Say I had a class SuperClass and two subclasses SubClassA and SubClassB that inherit from SuperClass.

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

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

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

That way it is convenient because I can get someList.size() in Superclass and have Typesafety in the Subclasses. The problem is that it does not "feel" right, can you think of potential hazards this apporach has that I am not aware of?

+8  A: 

For one thing, any method of SuperClass sees the superclass list, not that of the subclass. This almost surely leads to subtle bugs. E.g. when you say

I can get someList.size() in Superclass

what you actually get is the size of the list in Superclass, not that of the subclass. The superclass list may be empty while the subclass list contains elements (or vice versa).

The reason behind this is that SubClassA.someList does not in any way replace or override Superclass.someList - it just shadows it, so the subclass methods see SubClassA.someList instead of Superclass.someList. However, this has absolutely no effect in Superclass. Methods can be made virtual (and in Java, they are by default), but data members can't.

Péter Török
They could be different references pointing to the same object. (Although `private` and `final` would help as ever.)
Tom Hawtin - tackline
@Tom, good point, haven't thought of that... possibly because, although semantically correct, this would still be an ugly, unnecessarily complex, hard to understand solution (to me).
Péter Török
I found out the hard way, that it is actually shadowing. The only thing I did here was essentially trick the compiler (and me).
sebastiangeiger
+1  A: 

This is a really bad idea. Do you really want an instance of either subclass to have two lists? Because that's what is happening. You're declaring a second variable - so code in the superclass will use one variable, and code in the subclass will use another. That's just asking for trouble, IMO.

Jon Skeet
+1  A: 

Seems to break IS-A and the Liskov Substitution Principle to me. If you have a collection of SuperClass instances, each of which can be SubClassA or SubClassB, you'll get some surprising behavior at best.

Don't do it.

Maybe something using generics would be better:

public class X<T>
{
    private List<T> list;
}
duffymo
+1  A: 

I think you should rather define a method instead of the class member variable. So that you will be able to implement methods in your sub classes and don't need to worry about the type safety.

Replace variable with Method i suggest.

thanks.

Paarth