Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: how to inherit a "static slot"?

Well, I'm learning Scala so this question may be too basic for most people.

In Java I can have a static slot (function or variable) in a class, and then I will have that slot in inherited classes too.

In Scala I don't have static slots, but I have companion objects. But I'm finding out that those objects are not part of the inherited class, so if I have two classes Person and Student, and Person has a companion object with a variable all:List that returns a list of all persons so I can do Person.all, I was expecting that I could do Student.all too, but that's not the case.

Is there any way to get the same behaviour that I would get in java?

Thanks!

like image 691
Damian Avatar asked Oct 19 '09 02:10

Damian


3 Answers

Theoretically speaking, Java's behavior in this respect is very broken. The fact that subclasses inherit static members really doesn't make any sense from an object-oriented point of view. Statics are really nothing more than fancy, scoped globals. Inheritance is something you see at the class level, but statics really aren't at the class level (since they're global) so inheritance shouldn't apply. The fact that it does in Java is...disturbing.

Scala has really taken the high road in this department; something for which we should all be grateful. As mentioned in another answer, the correct way to define "inherited" statics is to extract the inherited members out into a trait:

trait Inherited {
  def foo() { ... }
  def bar(i: Int) = ...
}

class Person {
  ...
}

object Person extends Inherited

class Student extends Person {
  ...
}

object Student extends Inherited

It may seem needlessly more verbose than Java, but trust me when I say that the semantics are a lot less surprising as a result.

like image 84
Daniel Spiewak Avatar answered Nov 09 '22 00:11

Daniel Spiewak


I don't know if this is what you meant, but a companion object can extend from some traits/classes:

class Person
class Student extends Person

trait Aggregation[T] {
  val all: List[T]
}

object Person extends Aggregation[Person] {
  val all: List[Person] = List(new Person, new Person)
}

object Student extends Aggregation[Student] {
  val all: List[Student] = List(new Student, new Student)
}

println(Person.all) // prints all persons
println(Student.all) // prints all students
like image 21
Walter Chang Avatar answered Nov 08 '22 23:11

Walter Chang


Objects in Scala are not class-level entities like statics are in Java. They are simply a class definition and singleton instantiation rolled into one.

A companion object is a special case that allows the sharing of private data between it and its companion class.

Objects can extend classes, but not other objects. After all an 'object' is just a singleton instance - the class definition of an 'object' is hidden.

Is it reasonable to expect the special relationship between companion objects and companion classes to project an additional class hierarchy on companion objects?

I suspect the best way to achieve a dependency between Person and Student is to delegate.

object Person { val all = List(1,2,3) }
object Student { val all = Person.all.filter(_ % 2 == 0) }
like image 35
Synesso Avatar answered Nov 09 '22 01:11

Synesso