Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala generic method overriding

Tags:

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.

like image 380
Jannik Luyten Avatar asked Jan 07 '11 15:01

Jannik Luyten


People also ask

How to override object in Scala?

In scala, you must use either override keyword or override annotation to override methods from parent class.

Does Scala support generics?

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, [ ].

How to parameterize in Scala?

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.

What is generic type in Scala?

Generic classes are classes which take a type as a parameter. They are particularly useful for collection classes.


2 Answers

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.

like image 83
Ken Bloom Avatar answered Oct 07 '22 19:10

Ken Bloom


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 } 
like image 30
Landei Avatar answered Oct 07 '22 20:10

Landei