I am using several classes like this:
class MyClassOne {
doSomething(a : A) : B
...
}
class MyClassTwo {
doSomething(a : A) : B
...
}
The source for the classes is not under my control. Although the classes have methods with the same signature they don't implement an interface. I would like to define methods that work on all the classes.
So I've made a Trait like this:
trait MyTrait {
doSomething(a : A) : B
}
And have made implicit conversions for all the classes:
implicit class MyClassOneMyTrait(myClassOne : MyClassOne) {
def doSomething(a : A) = myClassOne.doSomething(a)
}
Is there a way to take advantage of the naming conventions used in the classes and avoid explicitly delegating to the objects passed into the constructor? More generally, is using a Trait with implicit classes the best approach to this problem?
Actually, there is scala feature exactly for your situation. It's called structural types.
For structural types type requirements are expressed by interface structure instead of a concrete type. Internal implementation uses reflection, so be performance-aware!
type A = String
type B = String
class MyClassOne {
def doSomething(a: A): B = {
println("1")
"1"
}
}
class MyClassTwo {
def doSomething(a: A): B = {
println("2")
"2"
}
}
type MyClassType = {
def doSomething(a: A): B
}
List[MyClassType](new MyClassOne, new MyClassTwo).foreach(_.doSomething("test"))
List(new MyClassOne, new MyClassTwo).foreach {
case a: MyClassType => a.doSomething("test")
case _ =>
}