2015-06-29 13 views
9

tôi muốn tuyên bố trong một giao thức một class func, tôi có ý định để phù hợp với giao thức này từ một lớp A, B và C.Nghị định thư cho phương pháp lớp

B và C kế thừa từ A.

Về cơ bản tôi muốn ghi đè func này trong B và C trong khi vẫn cung cấp một thực hiện trong A.

vì vậy, tôi đã phải tuyên bố giao thức của tôi như sau:

protocol MyManagedObjectCoolStuff { 

    static func entityName() -> String 
} 

và sau đó tôi có t của anh ấy trong A:

class A: NSManagedObject { } 

class B: A { } 

class C: A { } 

extension A: MyManagedObjectCoolStuff { 

    static func entityName() -> String { 
     return "Animal" 
    } 
} 

extension B: MyManagedObjectCoolStuff { 

    override static func entityName() -> String { 
     return "Bat" 
    } 
} 

extension C: MyManagedObjectCoolStuff { 

    override static func entityName() -> String { 
     return "Cat" 
    } 
} 

Vấn đề ở đây, rõ ràng và Xcode xác nhận: "Phương thức lớp ghi đè" phương thức lớp cuối cùng ".

enter image description here

Làm cách nào tôi có thể giải quyết vấn đề này? Tôi không thể sử dụng class func trong giao thức ... Tôi không chắc chắn làm thế nào để trừu tượng điều này.

Cảm ơn!

+0

remove 'static' ghi đè tại B và C, không thể có hai triển khai của một hàm tĩnh – Daniel

+0

Ngoài ra, không làm cho B và C kế thừa từ A. – Daniel

Trả lời

18

Trong một lớp định nghĩa, static là một bí danh cho class final, để nó đánh dấu một phương pháp loại (hoặc tài sản) mà không thể được ghi đè trong lớp con.

Vì bạn muốn để ghi đè phương pháp này trong các lớp con, tất cả các bạn phải làm là xác định phương pháp như class thay vì static:

extension A: MyManagedObjectCoolStuff { 

    class func entityName() -> String { 
     return "Animal" 
    } 
} 

extension B: MyManagedObjectCoolStuff { 

    override class func entityName() -> String { 
     return "Bat" 
    } 
} 

extension C: MyManagedObjectCoolStuff { 

    override class func entityName() -> String { 
     return "Cat" 
    } 
} 

Ngoài ra người ta có thể sử dụng thực tế là cho một thực thể Core Data, tên lớp là thường định nghĩa là <ModuleName>.<EntityName> để tên đơn vị là thành phần cuối cùng của tên lớp .

Vì vậy, bạn có thể định nghĩa entityName() như một phương pháp mở rộng của NSManagedObject (lớp cha của tất cả lớp đối tượng Core Data) như trong How can I create instances of managed object subclasses in a NSManagedObject Swift extension?:

extension NSManagedObject { 

    class func entityName() -> String { 
     let classString = NSStringFromClass(self) 
     // The entity is the last component of dot-separated class name: 
     let components = split(classString) { $0 == "." } 
     return components.last ?? classString 
    } 
} 

và ghi đè lên nó chỉ khi cần thiết:

class A: NSManagedObject { } 

class B: A { } 

class C: A { } 

extension C { 

    override class func entityName() -> String { 
     return "Cat" 
    } 
} 

println(A.entityName()) // A 
println(B.entityName()) // B 
println(C.entityName()) // Cat 
+0

@MatteoPiombo: Cảm ơn đề xuất chỉnh sửa, nhưng ý định của tôi là cho thấy rằng vấn đề có thể được giải quyết bằng cách sử dụng các phương pháp mở rộng từ câu hỏi. Định nghĩa 'class func entityName()' trực tiếp trong 'class A' (như trong câu trả lời đã xóa của bạn) * có thể * là thích hợp, nhưng dường như không liên quan đến vấn đề với tôi. Một vấn đề khác với cách tiếp cận đó là các lớp con NSManagedObject có thể được tạo tự động từ Xcode. –

+0

... và suy nghĩ về đề xuất của bạn một lần nữa dẫn đến "phụ lục" :) –

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