So I have an Interface MyInterface<T> which has a method String save(T obj)
The implementing class has this definition Animal<T> implements MyInterface<T>. My Main function looks like this:
MyInterface<Cow> animal = new Animal<Cow>();
Cow cow = new Cow();
cow.setName("Rose");
animal.save(cow);
So far so good, animal.save() can only save Cows which is type-safe.
Now the problem. In my Animal class I have the save method, but before I save I want to know that my Cow has a name. The Cow class has a getName() method.
Save method:
@Override
public void save(T obj)
What would be an apropriate way to go from T obj to a Cow-object so I can use the member method getName()?
My idea is:
@Override
public void save(T obj)
{
Object unknown = obj.getClass().newInstance();
if (unknown instanceof Cow)
{
String name = ((Cow) unknown).getName();
}
}
Is this "ok" java? I guess I could use reflection and search for all methods related to the unknown object as well..
Update
As long as I define MyInterface<Cow> animal = new Animal<Cow>(); Like this I'm safe, but the problem apperas when it looks like this:
MyInterface<Object> animal = new Animal<Object>();
Then there is no getName() method....
If you assume that all animals have a name then create an interface.
static interface HasName {
String getName();
}
All objects having a name should then implements the interface
class Cow implements HasName{
String name;
Cow(String name){
this.name = name;
}
@Override
public String getName() {
return name;
}
}
Then modifying Annimal to allow all objects implementing the interface you will be able to get their names:
class Annimal<T extends HasName> {
void save(T obj) {
...
String name = obj.getName();
}
}
Even if the use of instanceof works, like in your post, it's a practice to avoid, because if one day you want to implement a new type of animal, let's say Horse, you will have to modify the implementation of your save method to add the if (unknown instanceof Horse) condition.
instanceof should be avoided wherever possible, and so should reflection.
I would add a separate interface which indicates whether something is in a saveable state. Your Animal class would then need to change it's generic type parameter to only allow saveable items.
interface Saveable
{
boolean canSave();
}
public class Cow implements Saveable
{
//...
@Override
boolean canSave()
{
return getName() != null && !getName().isEmpty();
}
}
public class Animal<T extends Saveable> implements MyInterface<T>
{
@Override
public void save(T obj)
{
if (obj.canSave())
{
//whatever
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With