Reputation: 4595
I have a superclass like this:
public class GenericUpdate{
//...other stuff...
public String getName(){return null;};
}
And a subclasses like this:
public class FromFriend extends GenericUpdate {
@Override
public String getName() {return getFriend().getName();}
}
or this:
public class FromArtist extends GenericUpdate {
@Override
public String getName() {return getArtist().getName();}
}
Now,
some other class delivers me a list of GenericUpdate
if I iterate on the list and call GenericUpdate.getName()
I get null back from getName()
is there a nice solution to avoid this?
Thanks
EDIT EDIT EDIT EDIT EDIT
the actual instances of the GenericUpdate
class are retrieved from Android Intents, they are retrieved like this:
genericUpdate=intent.getParcelableExtra(GENERIC_UPDATE);
and they are put in the intent like this:
GenericUpdate genericUpdate=((FlowAdapter)parent.getAdapter()).getItem(position);
//...
intent.putExtra(PostDetailActivity.GENERIC_UPDATE,genericUpdate);
//...
Upvotes: 1
Views: 92
Reputation: 420991
All methods in Java are virtual, so you can't "accidentally" call the base class method on an object of a subclass.
To see the runtime type of the objects in your list, you can for instance print genericUpdate.getClass().toString()
.
If this gives class com.mypackage.javaclasses.FromFriend
then getFriend.getName()
most likely return null
. If this gives class com.mypackage.javaclasses.GenericUpdate
your objects are not of the right subtypes and there should be no surprise that the subclass implementations of getName
are not called.
(Turns out it was the latter in this case.)
So if you have control over the code of the GenericUpdate
class you can make sure this situation is avoided by making GenericUpdate
abstract. (Note that an abstract class can still have fields.)
Upvotes: 2
Reputation: 1567
From your statement above, the class GenericUpdate
has a method getName()
which returns null. If you observe correctly, this class can also be instantiated. Therefore, if you have a list of GenericUpdate
classes, they will always return null, since the getName()
method always returns null
.
If you don't want your Generic
class to be instantiated, you can do something like this:
public abstract class GenericUpdate{
public abstract String getName();
}
Then, you can now extend your classes the same way you've done.
Now, to use the GenericUpdate
's getName()
method, you have to do something like:
GenericUpdate fromFriend = new FromFriend();
fromFriend.getName();
This will never return null for GenericUpdate as long as the getFriend().getName();
method in your implementation has a value, and is not null.
Another alternative is to use Krzysztof Cichocki answer above.
Upvotes: 2
Reputation: 6414
Maybe you need interface?
public interface GenericUpdate{
//...other stuff...
public String getName();
}
public class FromFriend implements GenericUpdate {
@Override
public String getName() {return getFriend().getName();}
}
or this:
public class FromArtist implements GenericUpdate {
@Override
public String getName() {return getArtist().getName();}
}
Then no one could add a non valid object to your list, and there should be always a valid implementation of this method if you have an instance of object implementing this interface.
The interfaces role is exactly that, to tell others what they should implement, so you can have some abstact algorithm that uses this kind of objects that implement it.
You can't instantiate pure intercface, you need to implement it, and this guarantess you, that every object will have implementation, that should be valid.
Upvotes: 2