I have an abstract class :
abstract class Foo(...){ def bar1(f : Foo) : Boolean def bar2(f : Foo) : Foo }
multiple classes extend Foo and override the methods
class FooImpl(...) extends Foo{ override def bar1(f : Foo) : Boolean { ... } override def bar2(f : Foo) : Foo { ... } }
Is it possible, using generics (or something) to make the overriding methods have the parametertype of the subclass implementing it? Like this :
class FooImpl(...) extends Foo{ override def bar1(f : FooImpl) : Boolean { ... } override def bar2(f : FooImpl) : FooImpl { ... } }
I was thinking something along the line of the following, but that didn't seem to work...
abstract class Foo(...){ def bar1[T <: Foo](f : T) : Boolean def bar2[T <: Foo](f : T) : T } class FooImpl(...) extends Foo{ override def bar1[FooImpl](f : FooImpl) : Boolean { ... } override def bar2[FooImpl](f : FooImpl) : FooImpl{ ... } }
Any help is much appreciated!
Thank you.
In scala, you must use either override keyword or override annotation to override methods from parent class.
The classes that takes a type just like a parameter are known to be Generic Classes in Scala. This classes takes a type like a parameter inside the square brackets i.e, [ ].
Methods in Scala can be parameterized by type as well as by value. The syntax is similar to that of generic classes. Type parameters are enclosed in square brackets, while value parameters are enclosed in parentheses.
Generic classes are classes which take a type as a parameter. They are particularly useful for collection classes.
abstract class Foo{ type T <: Foo def bar1(f:T):Boolean def bar2(f:T):T } class FooImpl extends Foo{ type T = FooImpl override def bar1(f:FooImpl) = true override def bar2(f:FooImpl) = f }
In this version, different subclasses of Foo
all share Foo
as a superclass, but to hold the return value of bar2
(or the parameters to bar1
or bar2
) in a setting where all you know about your object (let's say it's named obj
) is that it's a Foo
, you need to use the type obj.T
as the type of the variable.
To make Ken Blum's second version a little bit nicer you can use self types:
abstract class Foo[T] { self:T => def bar1(f:T):Boolean def bar2(f:T):T } class FooImpl extends Foo[FooImpl]{ override def bar1(f:FooImpl) = true override def bar2(f:FooImpl) = f }
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