2012-07-01 27 views
8

Tại sao tôi có thể nói rằng một trường kiểu có kiểu của một lớp với một lớp khác được trộn vào nó (khi chỉ các đặc điểm có thể được trộn lẫn trong một lớp)?Tại sao có thể kết hợp các lớp trong một trường loại?

Ví dụ:

scala> class A 
defined class A 

scala> class B extends A 
defined class B 

Trộn trong B-A không được phép:

scala> new A with B 
<console>:10: error: class B needs to be a trait to be mixed in 
      new A with B 
         ^

Nhưng điều này có thể:

scala> class E {type T = A with B} 
defined class E 

scala> new E 
res1: E = [email protected] 
+0

Trông giống như một lỗi đối với tôi. –

Trả lời

3

này được gọi là compound type và không có gì để làm với những đặc điểm. Nó cho phép bạn thể hiện rằng một loại là một loại phụ của một số loại khác.

Để biết thêm thông tin, nơi chúng có thể xảy ra, hãy xem Scala tag info trong phần "xử lý loại".

+0

Điều đó không trả lời được câu hỏi: tại sao điều này lại có thể xảy ra? –

+1

@RobinGreen: Tại sao nó không thể thực hiện được? 'new A with B' có nghĩa là * mixin *' B' thành 'A',' type T = A với B' có nghĩa là 'T' là kiểu' A' * và * 'B'. – sschaef

+2

@Antoras - câu hỏi là hợp lệ. Vì bạn không thể _instantiate_ kết hợp hai lớp, một tình huống hữu ích là nơi bạn có thể có loại kết hợp của hai lớp? Trong khi toàn bộ hệ thống vẫn còn âm thanh, người ta có thể lập luận rằng khi trong 'A với B' hai loại đó được biết đến trình biên dịch để tham chiếu đến các lớp, nó có thể phát ra một cảnh báo ít nhất. –

6

Có sự khác biệt giữa bản mixin và định nghĩa loại hợp chất. Đầu tiên của tất cả các loại A with B tồn tại và chính xác là loại B, than ôi nó là hoàn toàn hợp pháp trong scala viết

val x: A with B = new B 

như là

val y: Any with AnyRef with A with B = new B 

vì nó mô tả chính xác cùng loại. Bạn chỉ giới thiệu các hạn chế về loại giá trị mà bạn có thể gán cho một biến loại đó. Những hạn chế này tất nhiên luôn giữ trong trường hợp đó.

Ngoài ra, bạn phải nhớ rằng Scala không nhất thiết phải có loại người ở - tức là loại dưới cùng Nothing có thể không được khởi tạo. Nhưng khi Nothing là một subtype của tất cả các loại có thể được thể hiện bằng Scala nó thậm chí còn hợp lệ để viết một biểu thức như

def foo: AnyRef with AnyVal = sys.error("IMPOSSIBRU!") 

Nothing là một subtype của AnyRef with AnyVal theo định nghĩa như vậy mà typechecks khai.

Các vấn đề liên quan