1

The below code compiles fine (it is a simple companion object tutorial)

scala> :paste
// Entering paste mode (ctrl-D to finish)

trait Colours { def printColour: Unit }
object Colours {
private class Red extends Colours { override def printColour = { println ("colour is Red")} }
def apply : Colours = new Red
}

// Exiting paste mode, now interpreting.

defined trait Colours
defined object Colours

when i try

val r = Colours

it works fine, but when i use

r.printColour 

I get an error

<console>:17: error: value printColour is not a member of object Colours
   r.printColour
Srinivas
  • 2,010
  • 7
  • 26
  • 51

2 Answers2

2

When you do val r = Colours, its not calling your apply on companion object because your apply method does not take params because it does not have ().

see example,

class MyClass {
  def doSomething : String= "vnjdfkghk"
}

object MyClass {
  def apply: MyClass = new MyClass()
}

MyClass.apply.doSomething shouldBe "vnjdfkghk" //explicit apply call

So, you have to call apply on your companion object

val r = Colours.apply

Or else, you must have parenthesis with apply (empty-paren), so that you don't need to call .apply explicitly.

eg.

class MyClass {
  def doSomething : String= "vnjdfkghk"
}

object MyClass {
  def apply(): MyClass = new MyClass()
}

MyClass().doSomething shouldBe "vnjdfkghk"

very useful resources

Difference between function with parentheses and without [duplicate]

Why does Scala need parameterless in addition to zero-parameter methods?

Why to use empty parentheses in Scala if we can just use no parentheses to define a function which does not need any arguments?

prayagupa
  • 30,204
  • 14
  • 155
  • 192
1

Add parenthesis to your apply method definition ...

def apply(): ...

... and the Colours object invocation.

val r = Colours()

Then it will work as desired.

r.printColour  // "colour is Red"
jwvh
  • 50,871
  • 7
  • 38
  • 64