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
Afaics, Daniel Spiewak's and Walter Chang's answers appear to provide two separate copies of the all
list. I didn't test the following, but I hope this provides the correct outline even it if has errors.
class Person
class Student extends Person
object Person {
val all: List[Person]
}
then within Student
, access via Person.all
If you want to provide access via Student.all
then
object Student {
def all() = Person.all
}
Another way to do it, would allow you to declare the statics (i.e singleton object) in a trait to be inherited.
trait StaticAll {
object Static { val all: List[Person] }
}
class Person extends StaticAll
class Student extends Person
Then access with StaticAll#Static.all
. I think that is correct and not StaticAll.Static.all
. Again this is all off the top of my head, I didn't test any this. Please correct my errors.
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.
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
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) }