Scala: how to inherit a “static slot”?

前端 未结 4 645
鱼传尺愫
鱼传尺愫 2021-01-05 09:33

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

相关标签:
4条回答
  • 2021-01-05 10:18

    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.

    0 讨论(0)
  • 2021-01-05 10:28

    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.

    0 讨论(0)
  • 2021-01-05 10:35

    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
    
    0 讨论(0)
  • 2021-01-05 10:35

    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) }
    
    0 讨论(0)
提交回复
热议问题