2011-07-27 5 views
21

Tôi đang cố gắng tạo một đặc điểm, khi được trộn vào, sẽ thay thế định nghĩa mặc định của phương thức bằng phương pháp gốc, sau đó thao tác kết quả.Gọi phương thức trên siêu lớp trong đặc điểm tự đánh máy trong scala

Dưới đây là những gì tôi đang cố gắng để làm:

class Foo { 
    def bar() : String = "Foos bar" 
} 

trait OtherStuff { 
    self : Foo => 
    def bar() : String = self.bar() + " with OtherStuff" 
} 

class Quux extends Foo with OtherStuff 

Nếu đây làm việc theo cách tôi muốn nó, sau đó (new Quux).bar mà ngày nay trở Foos bar with OtherStuff. Thật không may, nó không hoạt động theo cách đó - những gì tôi nhận được là:

<console>:6: error: error overriding method bar in class Foo of type()String; 
method bar in trait OtherStuff of type()String needs `override' modifier 
     class Quux extends Foo with OtherStuff 

Nhưng nếu tôi sử dụng override khi xác định OtherStuff, tôi nhận được:

<console>:7: error: method bar overrides nothing 
     override def bar() : String = self.bar() + " with OtherStuff" 

Có thể ghi đè lên một phương pháp trong một tự loại bằng cách sử dụng đặc điểm? Nếu không, sẽ thay đổi OtherStuff là một đặc điểm mà extends Foo thay vì một trong đó có một tự loại Foo làm bất cứ điều gì xấu để tất cả các mã mà tồn tại nói những điều như

class WhatEver extends Foo with Xyz with Pqr with OtherStuff with Abc 

Tôi đang làm việc trong scala 2,7. 7 vì đây là quy tắc xây dựng sbt và chúng tôi chưa nâng cấp dự án sbt của mình lên phiên bản 0.10.x. (Plugin chúng tôi chưa sẵn sàng)

Trả lời

29

Bạn cần abstract override và không tự loại cho điều đó.

trait OtherStuff extends Foo {         
    abstract override def bar() = super.bar() + " with OtherStuff" 
} 

Sau đó, class Quux extends Foo with OtherStuff thực hiện những gì bạn muốn.

This article có thể được quan tâm.

+3

Nếu OtherStuff không phải là một Foo trong logic của tôi thì sao? Không có giải pháp nào khác mà không có Foo mở rộng? Hoặc tôi đang lạm dụng tự đánh máy ở đây? – Radian

+0

@Dupont: Tại sao lớp Quux mở rộng Foo với OtherStuff thay vì chỉ mở rộng OtherStuff và lấy Foo từ thừa kế? – polo

0

hoặc bạn có thể làm một quá tải như sau

class Foo { 
    def bar() : String = "Foos bar"} 
trait OtherStuff { 
    self : Foo => 
    def bar(s : String) : String = self.bar() + s} 

class Quux extends Foo with OtherStuff 
(new Quux).bar(" with other stuff") 

điều này là, với tự loại chú thích, các "công cụ khác" quy định tại OtherStuff là một phần của Foo khi các Trait được trộn với Foo, chứ không phải là mối quan hệ phụ.

+2

Bạn vừa xác định một hàm đệ quy vô hạn. –

+2

@TonyK .: Không, vì chữ ký của hai phương thức 'bar' khác nhau –