In Scala, how can an Inner case class consistently override a method?

Related searches

I recently discovered that Scala compiler has an interesting feature for case class: Since it generates both a class & an object signature, if defined as an inner class, it can be used to override an abstract type definition and a function definition of its super class with minimal boilerplate code, here is an example:

object InnerCaseClassOverridingBoth {

  trait AALike

  trait SS {
    type AA <: AALike
    def AA(): AnyRef
  }

  trait SS_Clear extends SS {
    def AA(): AnyRef
  }

  class SSA extends SS_Clear {
    case class AA() extends AALike
  }
  object SSA extends SSA {}
}

This will compile without any error. However the shortcut stops here, if the function definition def AA is parameterized, then neither the inner case class nor inner object is capable of overriding it: the apply function of the inner object doesn't automatically expand to a method of its outer class:

  trait SS_Parameterised extends SS {
    def AA(ii: Int): AnyRef
  }

  class SSB extends SS_Parameterised {
    case class AA(ii: Int) extends AALike
  }
  object SSB extends SSB {}

This gives an error:

class SSB needs to be abstract, since method AA in trait
SS_Parameterised of type (ii: Int)AnyRef is not defined
    class SSB extends SS_Parameterised {

My question is, is there a shortcut in this case? Why is the Scala compiler is designed to link case 1 but not case 2?

It's not particularly designed at all; or, it is, but not in the way you seem to think. You aren't overriding def AA() with a method that constructs AA, you are overriding it with the object AA itself. Notice

trait T {
   type I <: AnyRef
   def I(): AnyRef
}
object O extends T {
   case class I(val i: Int)
}

This works fine.

> (O: T).I()
I
> (O: T).I().getClass
class O$I$
> O.I(5)
I(5)
> O.I(5).getClass
class O$I

The salient design choices are "objects can override no-param defs" (and so can vals, vars and, of course, no-param defs) and "case classes automatically generate objects". "Inner case classes override methods of the same name in their outer class with their constructors," is not one of Scala's rules. object O contains a case class I and an object I, and the abstract def I(): AnyRef is overridden to return said object I. The contents of object I don't matter, because def I() only has to return an AnyRef, which means no restrictions are imposed. It makes perfect sense that

trait U {
   type I <: AnyRef
   def I(i: Int): AnyRef
}
object P extends U {
   case class I(i: Int)
}

fails, then. object P contains a case class I and an associated object I, but it also needs a def I(i: Int): AnyRef, which it lacks.

Chapter 6. Advanced Object-Oriented Programming In Scala, I recently discovered that Scala compiler has an interesting feature for case class: Since it generates both a class & an object signature, if defined as an inner� I don't know how to override the apply method in the companion object (if that is even possible) but you could also use a special type for upper case strings:. class UpperCaseString(s: String) extends Proxy { val self: String = s.toUpperCase } implicit def stringToUpperCaseString(s: String) = new UpperCaseString(s) implicit def upperCaseStringToString(s: UpperCaseString) = s.self case class A

I am guessing it is simply related to the role apply plays in case classes. See Case Class default apply method SSA satisfies SS_Clear.AA via companion object of SSA (SSA.apply).

When you add a parameter to the method you no longer have the 0-parameter apply method to fulfill that role.

Classes & Objects, Classes and traits can declare abstract members: fields, methods, and types. When overriding a concrete member, Scala requires the override keyword. In this case, since Clickable doesn't define toString , Widget. with new AbstractT2 … , we are actually using an anonymous inner class that implicitly extends the trait. So here's the situation. I want to define a case class like so: case class A(val s: String) and I want to define an object to ensure that when I create instances of the class, the value for 's' is

OK I found 2 ways of doing this

Method 1: overriden by case class:

  trait SS_Parameterised {
    type AA <: AALike
    def AA: Int => AnyRef
  }

Method 2: overriden by implicit class:

  trait SS_Parameterised {
    type AA <: AALike
    implicit def AA(ii: Int): AnyRef
  }

  class SSB extends SS_Parameterised {
    implicit class AA(ii: Int) extends AALike
  }

End of story :) One case class overriding 2 declarations? No problem.

(Method 2 works as scala internally generates an implicit function for every implicit class)

Equality and case objects, In the following, we will always assume that this implicit extension has been no type T is given, S is just C. Inside the template, the type of this is assumed to be S. Every case class implicitly overrides some method definitions of class scala. Case classes are good for modeling immutable data. In the next step of the tour, we’ll see how they are useful in pattern matching. Defining a case class. A minimal case class requires the keywords case class, an identifier, and a parameter list (which may be empty):

9. Objects, Case Classes, and Traits - Learning Scala [Book], So when the equals method is defined in terms of something which is defined in terms objects in general) will always override equality to mean objects that matching on an inner case class or a case object would not test the Inner class is only visible within the compilation unit, say because Inner (or Outer) is private (but not private[x]), and the compilation unit doesn't use @outer; the inner class is anonymous (so it can't be used in a pattern match - right?) the inner class is annotated with @noouter (Jason Zaugg's proposal).

An object can extend another class, making its fields and methods available in And you can add commands to access the classes and objects right inside the . scala file, A parent class, if specified, must always come before any parent traits. toString } defined trait C scala> class D extends A with B with C { override def� Scala Abstract Class Example. In this example, we have created a Bike abstract class. It contains an abstract method. A class Hero extends it and provides implementation of its run method. A class that extends an abstract class must provide implementation of its all abstract methods. You can't create object of an abstract class.

Now that we have a better understanding of Scala classes and objects, let’s take a look at some of the differences: Definition: A class is defined with the class keyword while an object is defined using the object keyword. Also, whereas a class can take parameters, an object can’t take any parameter

Comments
  • agreed but in this case def I(i: Int) can't be defined anymore. This is a good answer but let's see if a scala compiler designer can clarify this in a few days.
  • @tribbloid What does "def I(i: Int) can't be defined anymore" mean? In what "case"? I can add a def I(i: Int): AnyRef = java.lang.Integer.valueOf(i) or whatever to both object O and object P and have them both compile.
  • yes you are right, just did a quick experiment and turns out that the new function definition is possible. Accepted as canonical answer