Reputation: 172
I would like to have an abstract method that has a parameter of the exact class of the instance. For example:
abstract class Foo {
abstract void aFunc(???? newInst);
}
class Bar extends Foo {
@Override
void aFunc(Bar newInst);
}
class Baz extends Foo {
@Override
void aFunc(Baz newInst);
}
Effectively I would like to be able to access all subclass fields and methods without having to check and cast the newInst parameter. (As the function would be called from a central handler location that does the checks and casts).
I know I can do this by parameterising Foo with Foo<T extends Foo>
, but I would ideally like to avoid declaring subclasses as class Name extends Foo<Name>
if possible.
I doubt this is possible, and I have been unable to find anything on the topic, but I would just like to confirm that there is nothing i have missed.
Upvotes: 0
Views: 73
Reputation: 8932
Meta-Comment:
the thing that you would like to have does break polymorphism: now you cannot use Bar
or Baz
everywhere you can use Foo
because they have an aFunc signator that is not compatible anymore.
However, what you can do is have a return type that is more specific:
class Foo {
Foo aFunc();
}
class Bar extends Foo {
@Override
Bar aFunc();
}
is valid. You can use an instance of Bar instead of Foo and call its aFunc
method; then you can use the result of that method also as an instance of Foo. Therefore JLS allows for covariant return types since Java 1.5.
Upvotes: 2
Reputation: 172
Thanks to all who commented to help.
The correct way to do this is by declaring the class as class Bar extends Foo<Bar>
and for the sake of simplicity, I will just pass Foo as the parameter and make all subclasses cast the argument themselves (if they need to).
Upvotes: 0