Disclaimer: I know English & Portuguese only.
And although I can understand Spanish more or less, still I can’t properly reply using it, sorry.
Anyways, we can always count on Google Translate, right?
Indeed, if your method Animal::hijo() is something like this:
class Animal {
Animal hijo(final String name) {
return new Animal(name);
}
}
And you’ve got a class
that extends
it:
class Perro extends Animal {
Perro(final String name) {
super(name);
}
}
Java won’t “automagically” upgrade the datatype Animal in return new Animal(name);
to the datatype of that subclass like return new Perro(name);
in any way!
As a workaround, we could use Java reflection techniques in order to always instantiate the current subclass’ Constructor:
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/reflect/Constructor.html
However, reflection is complicated! And thus it should be used only if there’s no other alternative:
And a simpler alternative is to implement the Cloneable interface
and its clone() method:
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Cloneable.html
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Object.html#clone()
Here’s an example of a class
named Pair which implements
Cloneable:
And inspired by my previous sketch above, here’s “Cloneable Inheritance”:
/**
* Cloneable Inheritance (v1.0.1)
* GoToLoop (2019/May/13)
* Discourse.Processing.org/t/problema-con-class-extend-y-herencia/11204/2
*/
import java.util.List;
final List<Animal> animales = new ArrayList<Animal>();
void setup() {
animales.add(new Animal("Madre"));
println(animales);
animales.add(animales.get(animales.size() - 1).hijo("Hijo"));
println(animales);
animales.add(new Perro("Rex"));
println(animales);
animales.add(animales.get(animales.size() - 1).hijo("Perla"));
println(animales);
exit();
}
class Animal implements Cloneable {
String name;
Animal() {
}
Animal(final String name) {
set(name);
}
Animal set(final String nick) {
name = nick;
return this;
}
Animal hijo(final String name) {
//return new Animal(name);
return clone().set(name);
}
@Override Animal clone() {
try {
return (Animal) super.clone();
}
catch (final CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
@Override String toString() {
return name + " el " + getClass().getSimpleName();
}
}
class Perro extends Animal {
Perro() {
}
Perro(final String name) {
super(name);
}
}