Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protocol for class method

Tags:

swift

I want to declare in a protocol a class func, I intend to conform to this protocol from a class A, B and C.

B and C inherit from A.

Essentially I want to override this func in B and C while still providing an implementation in A.

So, I had to declare my protocol as follows:

protocol MyManagedObjectCoolStuff {

    static func entityName() -> String
}

And then I have this in 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"
    }
}

The problem here, is clear and Xcode confirms: "Class method overrides a 'final' class method".

enter image description here

How can I work around this? I cannot use class func in the protocol... I'm not sure how to abstract this.

Thanks!

like image 465
Daniel Avatar asked Jun 29 '15 10:06

Daniel


People also ask

CAN protocol class method?

A protocol can have properties as well as methods that a class, enum or struct conforming to this protocol can implement. A protocol declaration only specifies the required property name and type. It doesn't say anything about whether the property should be a stored one or a computed one.

What is a class protocol?

A classroom protocol allows a faculty member to complete a single IRB application for an entire class research project in which all students are completing similar research. A classroom protocol may be used if the research involving human subjects is meant for classroom instruction and not for publication.

What is protocol class in Python?

Protocol class was added to Python 3.8 as part of PEP 544 as a mechanism for “structural subtyping.” Basically, it is used to define an interface class that acts as a blueprint for designing other classes. Like classes, interface classes define methods however Unlike classes, these methods are abstract methods.

What is protocol method?

A protocol is most commonly a predefined procedural method in the design and implementation of an experiment. Research methods may be published separately (in method focused journals, books, or dissertations) or included as a supplement to a published article.


1 Answers

In a class definition, static is an alias for class final, so it marks a type method (or property) which cannot be overridden in subclasses.

Since you want to override the method in subclasses, all you have to do is to define the method as class instead of 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"
    }
}

Alternatively one could use the fact that for a Core Data entity, the class name is usually defined as <ModuleName>.<EntityName> so that the entity name is the last component of the class name.

So you could define entityName() as an extension method of NSManagedObject (the superclass of all Core Data object classes) as in 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
    }
}

and override it only where necessary:

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
like image 105
Martin R Avatar answered Sep 21 '22 17:09

Martin R