2010-02-08 37 views
36

Trong Scala, tôi đã nhìn thấy các cấu trúcSự khác nhau giữa kế thừa đặc điểm và tự chú thích kiểu

trait T extends S 

trait T { this: S => 

sử dụng để đạt được những điều tương tự (cụ thể là các phương pháp trừu tượng trong S phải được định nghĩa trước khi một cá thể có thể được tạo). Sự khác nhau giữa chúng là gì? Tại sao bạn sử dụng cái này qua cái kia?

+9

Bản sao chính xác của http://stackoverflow.com/questions/1990948/what-is-the-difference-between-scala-self-types-and-trait-subclasses, là câu hỏi đầu tiên được hiển thị trên danh sách có liên quan . –

Trả lời

12

Tôi muốn sử dụng các loại tự quản lý phụ thuộc: Đặc điểm này yêu cầu một đặc điểm khác được trộn lẫn. Và tôi muốn sử dụng thừa kế để tinh chỉnh một đặc điểm hoặc giao diện khác.

Cũng như một ví dụ:

trait FooService 

trait FooRemoting { this : FooService => } 
trait FooPersistence { this : FooService => } 

object Services extends FooService with FooRemoting with FooPersistence 

Bây giờ, nếu FooRemoting và FooPersistence cả sẽ có được thừa kế từ FooService, và FooService có thành viên và phương pháp, làm thế nào sẽ dịch vụ như thế nào?

Trong khi đó đối với thừa kế, chúng tôi muốn có một cái gì đó như:

trait Iterator[T] { 
    def hasNext : boolean 
    def next : T 
} 

trait InfiniteIterator[T] extends Iterator[T] { 
    def hasNext = true 
} 
+16

Xin lỗi Victor, tôi không hiểu "Dịch vụ trông như thế nào?" phần. Tôi đã thử cả hai cách và tôi có thể thấy đối tượng Dịch vụ hoạt động giống nhau. Tình hình làm cho sự khác biệt rõ ràng là gì? – ithkuil

25

Tự kiểu chú thích cho phép bạn thể hiện sự phụ thuộc theo chu kỳ. Ví dụ:

trait A extends B 
trait B { self: A => } 

Điều này không thể thừa kế đơn giản.

+0

bạn có trường hợp sử dụng không? – crak

+0

Bạn có thể sử dụng kỹ thuật này để bắt chước một phần các lớp như trong C#. Xem https://msdn.microsoft.com/en-us/library/wa80x488.aspx chẳng hạn. –

6

Kể từ khi đặt ra câu hỏi Tôi đã xem qua những bài viết:

Spiros Tzavellas cuộc đàm phán về việc sử dụng một đặc điểm như giao diện công cộng và tự loại như một helper mà phải được trộn lẫn trong bởi lớp thực hiện.

Tóm lại, nếu chúng ta muốn di chuyển triển khai phương pháp bên trong đặc điểm thì chúng ta có nguy cơ gây ô nhiễm giao diện những đặc điểm với các phương pháp trừu tượng có hỗ trợ việc thực hiện các phương pháp cụ thể và không liên quan với chính trách nhiệm của đặc tính . Giải pháp cho vấn đề này là để di chuyển các phương pháp trừu tượng đó trong các đặc điểm khác và soạn các đặc điểm cùng với chú thích tự nhập và nhiều kế thừa.

Ví dụ:

trait PublicInterface { this: HelperTrait => 
    // Uses helperMethod 
} 

trait HelperTrait { 
    def helperMethod = // ... 
} 

class ImplementationClass extends PublicInterface with HelperTrait 

A Tour of Scala thảo luận về sử dụng chú thích tự loại với các thành viên loại trừu tượng - có lẽ nó không thể extend một thành viên loại trừu tượng

+0

ngược lại, phải không? Nên là "class ImplementationClass mở rộng HelperTrait với PublicInterface"; có nghĩa là, một đặc điểm phải được trộn lẫn trước tiên để tham khảo nó như là một kiểu tự – virtualeyes

+0

Điều này dường như với tôi là một thiết kế tồi. Các phương thức trợ giúp là một mối quan tâm thực hiện của các lớp con của 'PublicInterface'. Tại sao không chỉ sử dụng các phương thức 'protected'? –

1

Mặc dù nó không trả lời (?) câu hỏi của bạn, tôi đã cố gắng hiểu chú thích tự gõ và về cơ bản đã bị mất trong câu trả lời, và bằng cách nào đó kết thúc đạp xe thông qua các biến thể của câu hỏi của bạn, trong đó tập trung vào việc sử dụng các chú thích tự gõ để nêu phụ thuộc.

Vì vậy, ở đây tôi viết mô tả về một trường hợp sử dụng nơi tự loại chú thích được minh họa tốt, cụ thể là một cái gì đó giống như một kiểu an trường hợp 'này' như một subtype:

http://programming-scala.labs.oreilly.com/ch13.html#SelfTypeAnnotationsAndAbstractTypeMembers

hy vọng rằng nó sẽ hữu ích cho những người kết thúc câu hỏi này một cách tình cờ (và, như tôi, không có thời gian để đọc một cuốn sách scala trước khi bắt đầu khám phá :-))

+0

Họ đã thay đổi các liên kết. Bây giờ là: http://ofps.oreilly.com/titles/9780596155957/ApplicationDesign.html (tại "Chú thích Tự gõ và Thành viên Loại Tóm tắt"; không có liên kết trực tiếp) – akauppi

2

Câu trả lời là "tròn". Nhưng không chỉ.

Chú thích tự gõ giải quyết cho tôi vấn đề cơ bản của thừa kế: những gì bạn kế thừa từ không thể sử dụng bạn là gì. Với kiểu tự, mọi thứ trở nên dễ dàng.

mẫu của tôi là những điều sau đây và có thể được coi như một chiếc bánh đã bị suy thoái:

trait A { self: X => def a = reuseme} 
trait B { self: X => def b = a } 
class X extends A with B { def reuseme=null } 

Bạn có thể phát nổ lớp học của bạn trong nhiều hành vi mà có thể được gọi từ bất cứ nơi nào trong lắp ráp, trong khi ở sạch sẽ gõ. Không cần phải có sự hướng dẫn đau đớn quá thường xuyên (và sai) được xác định bằng mẫu bánh.

Một nửa (nếu không phải là toàn bộ) của các khung Java DI phức tạp trong mười năm qua đã được dành để làm điều này, tất nhiên mà không cần gõ. Mọi người vẫn đang sử dụng JAVA trong miền này rõ ràng sẽ mất thời gian của họ: "SCALA ouakbar".

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