Most probably, inside the abstract class there something like this:
public abstract class SomeClass<T extends SomeClass<T>> implements Cloneable {
public abstract T someMethod(); //<-- variable return type should be the implementing class itself
public abstract int someOtherMethod(T someInstance); //<-- variable parameter type should be the implementing class itself
}
With such declaration, when you extend the class SomeClass with something concrete, let's say SomeConcreteClass, then you'll have:
public class SomeConcreteClass extends SomeClass<SomeConcreteClass> {
@Override
public SomeConcreteClass someMethod() {
//implementation that returns SomeConcreteClass
}
@Override
public int someOtherMethod(SomeConcreteClass instance) {
//implementation that takes in parameter this type of class
}
}
When you declare an abstract class like that, you basically ask to self-reference the child class in the parameter type.
Of course you may also use another child (it would still be inside bounds as long as it extends SomeClass), but it's a rare use case (I'll never seen it personally)