2016-07-07 17 views
11

Tôi đang cố gắng sử dụng loại đối tượng trường hợp làm loại trừu tượng. Tôi rất ngạc nhiên khi nhìn thấy (tương tự) mã bên dưới biên dịch:Làm thế nào để cụ thể thiết lập loại trừu tượng với loại bị ràng buộc?

sealed abstract class Bar 

case object BarOne extends Bar 

case object BarTwo extends Bar 

sealed abstract class Foo { 
    type A <: Bar 

    def f: A 
} 

object Foo { 
    object FooOne extends Foo { 
    type A = BarOne.type 
    val f = BarTwo 
    } 

    object FooTwo extends Foo { 
    type A = BarTwo.type 
    val f = BarOne 
    } 
} 

Trong ví dụ thật của tôi Foo được parametrized và sử dụng như một lớp hợp cụ thể. Vì vậy, tôi không thể chỉ thực hiện một tham số loại A.

Làm thế nào để f = BarTwo biên dịch, khi A được đặt thành BarOne.type?

Nếu A trong f: A được hiểu là A <: Bar, tại sao vậy?

Có cách nào cụ thể được đặt A cho mỗi trường hợp đối tượng của Foo không?


Tôi đang sử dụng Scala 2.11.8.


Cập nhật: khi tôi thay val attributeType = ... với def attributeType = ... trong FooOne & FooTwo biên soạn thất bại (như mong đợi).

+1

Là mất tích 'kéo dài Foo' trên' FooOne' và 'FooTwo' một lỗi đánh máy? Bởi vì nó không biên dịch nếu bạn thêm nó. –

+0

@EndeNeu Đó là một sự giám sát. Và bạn nói đúng, nó không biên dịch (như mong đợi). Tôi đã cập nhật câu hỏi để làm cho nó trông gần nhất có thể với mã thực. Tất nhiên nó không sử dụng vì mã trên không biên dịch và mã của tôi biên dịch. – muhuk

+1

@muhuk nếu mã ở trên không biên dịch thì nó không đại diện cho mã biên dịch của bạn. Câu hỏi này không phải là câu trả lời trừ khi bạn nhận được một ví dụ tối thiểu chính xác. – Daenyth

Trả lời

1

Có ai đề nghị bạn nâng cấp lên phiên bản Scala hiện đại không? (Joke.)

Lỗi về ghi đè cung cấp đường dẫn đẹp cho loại đó.

$ scala 
Welcome to Scala 2.12.0-M5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_92). 
Type in expressions for evaluation. Or try :help. 

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

sealed abstract class Bar 

case object BarOne extends Bar 

case object BarTwo extends Bar 

sealed abstract class Foo { 
    type A <: Bar 

    def f: A 
} 

object Foo { 
    object FooOne extends Foo { 
    type A = BarOne.type 
    val f = BarTwo 
    } 

    object FooTwo extends Foo { 
    type A = BarTwo.type 
    val f = BarOne 
    } 
} 

// Exiting paste mode, now interpreting. 

<console>:26: error: overriding method f in class Foo of type => Foo.FooOne.A; 
value f has incompatible type 
      val f = BarTwo 
      ^
<console>:31: error: overriding method f in class Foo of type => Foo.FooTwo.A; 
value f has incompatible type 
      val f = BarOne 
      ^

Lỗi là this one và câu hỏi trùng lặp là from last November.

Bản chất của lỗi cũng rất thông minh: nó được giới thiệu bởi -Yoverride-objects, đây không phải là một lựa chọn rất hữu ích mà là số liệu trong một vài S.O. câu trả lời, và bây giờ trong một câu hỏi.

Edit:

$ scala 
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_92). 
Type in expressions for evaluation. Or try :help. 

scala> object X ; object Y 
defined object X 
defined object Y 

scala> class C { def f: X.type = X } 
defined class C 

scala> class D extends C { override def f: Y.type = Y } 
defined class D 

scala> :quit 
$ scalam 
Welcome to Scala 2.12.0-M5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_92). 
Type in expressions for evaluation. Or try :help. 

scala> scala> object X ; object Y 

// Detected repl transcript. Paste more, or ctrl-D to finish. 

defined object X 
defined object Y 

scala> class C { def f: X.type = X } 
defined class C 

scala> class D extends C { override def f: Y.type = Y } 
defined class D 
// Replaying 3 commands from transcript. 

scala> object X ; object Y 
defined object X 
defined object Y 

scala> class C { def f: X.type = X } 
defined class C 

scala> class D extends C { override def f: Y.type = Y } 
<console>:13: error: overriding method f in class C of type => X.type; 
method f has incompatible type 
     class D extends C { override def f: Y.type = Y } 
             ^
1

Tôi không biết điều gì đang xảy ra ở đây, nhưng tôi đã làm cho vấn đề bị cô lập hơn một chút. Ngoài ra, nó hoạt động với các lớp con Foo cũng như các đối tượng. Tôi đã xác nhận điều này biên dịch trên scalac 2.11.8:

object BarOne 
object BarTwo 

abstract class Foo[A] { 
    def attributeType: A 
} 

object FooContainer { 
    class FooOne extends Foo[BarOne.type] { 
    val attributeType = BarTwo 
    } 

    object FooTwo extends Foo[BarOne.type] { 
    val attributeType = BarOne 
    } 
} 
+0

Cảm ơn. Nhưng đây không phải là câu trả lời. – muhuk

+0

Vâng, tôi không biết làm thế nào để có được một đoạn mã lớn trên Stack Overflow nếu không. – robot1208

0
  1. A trong f: A được hiểu như là một <: Bar
  2. Bởi vì đó là những gì Một đại diện khi F được định nghĩa trong lớp trừu tượng
  3. Làm thế nào về trọng định nghĩa trừu tượng (dưới đây sẽ không biên dịch):

    object Foo { 
    
        object FooOne extends Foo { 
        type A = BarOne.type 
        override val f: A = BarTwo 
        } 
    
        object FooTwo extends Foo { 
        type A = BarTwo.type 
        override val f: A = BarOne 
        } 
    
    } 
    
Các vấn đề liên quan