Reputation: 4719
I have a Class named A
that extends a Trait X
. X
has an abstract variable x
that has been implemented in the class A
. Class A
uses one of the functions in Trait X
named foo
. I am trying to make a companion object of Class A
and put in some 'static' method inside it named Ofoo
. My problem is that Ofoo
uses foo
. So, I tried doing something like this:
trait X{
val x:String
def foo = {
//Full implementation here
}
}
case class A extends X{
val x = "barbaz"
// Class uses foo
}
object A extends X{
def Ofoo = {
//This also needs to use foo
}
}
I get an error saying the object A
cannot be instantiated as the variable x
is not defined in trait X
.
How should I structure A
such that it can use the function foo
defined in the trait X
?
Upvotes: 0
Views: 753
Reputation: 38247
How about implementing x
in A
? It's just an object; it has to obey the same rules, which include implementing the abstract members of any classes/traits that are being extended.
object A extends X {
val x = "hello"
...
}
just because it's the companion object of a class A
that already inherits from X
and implements x
, does not mean that object X
somehow magically reuses it.
In fact, technically a class and it's companion object are not connected; their only relation exists by convention.
On the other hand, if you want to make sure the value of x
is the same in both class A
as well as object A
, you can just define val x
in object A
and pull in that value in class A
:
class A extends X {
val x = X.x
...
}
object A extends X {
val x = "shared-value-of-x"
...
}
Upvotes: 1
Reputation: 661
At any rate, x must be defined by object A or in one of its superclasses/supertraits.
Based of the previous proposals and the OP's responses, I'll assume that foo should not be accessible from elsewhere, thus:
package pack {
trait X{
val x:String
}
// Reachable only in the same source file
sealed trait Y extends X{
// if foo doesn't use x below, no need to extend X, though
private[pack] def foo = {
//Full implementation here
println("x = "+x)
}
}
case class A() extends X with Y{
val x = "barbaz"
// Class uses foo
foo
}
object A extends X with Y{
val x = "barbatruc"
def ofoo = {
//This also needs to use foo
foo
}
}
}
Actually I have a hard time to understand what the OP wants. I agree with toto2.
Upvotes: 0
Reputation: 31754
The compiler behaves as it should. There can be 2 things: Does foo
use x
?
If that is the case then it is required to have an Instance with x
declared as the compiler says. You could say:
object A{
def ofoo = new X{val x = "default"}.foo
}
If foo
does not use x
then I am not sure if it should even belong to the trait X
. You could then create an object X
and then have foo
inside it something like:
trait X{
val x:String
}
object X{
def foo = {}
}
Upvotes: 3