Jack
Jack

Reputation: 181

Swift can't return subclass as superclass

I have this base class:

class FieldModel<T>{
   var pageModel : PageModel
   var fieldId : String
   var fieldTitle : String
   var required : Bool

   var type : String
   var rule : ShowHideRule?
   var fieldValue : T?


   init(json:JSON, pageModel : PageModel){
       //not important
   }
}

and this subclass:

class HeaderFieldModel : FieldModel<String> {    
   override init(json: JSON, pageModel: PageModel) {
       super.init(json: json, pageModel: pageModel)
   }
}

Why does

class FieldFactory {
    class func createField< T : FieldModel<AnyObject> >
        (json: JSON, pagemodel: PageModel) -> T {

            let type = json["type"].stringValue

            switch type {
            case "header":
                return HeaderFieldModel(json: json, pageModel: pagemodel)
            case "mood":
                return MoodFieldModel(json: json, pageModel: pagemodel)
            // ...
            }
        }
    }
}

... give me:

Cannot convert return expression of type HeaderFieldModel to return type T

The class I'm returning fulfills the condition, it's subclassing FieldModel. Even if I change the generic type from AnyObject to String, to make it exactly the same as in HeaderFieldModel, nothing changes.

Upvotes: 0

Views: 633

Answers (1)

Sulthan
Sulthan

Reputation: 130102

Your generic constrain says:

T : FieldModel<AnyObject>

T is defined as a subclass of FieldModel. One specific subclass is supposed to be returned from this method.

However, your switch is returning two or more different subclasses, not one single subclass.

What you actually want is:

class func createField(json: JSON, pagemodel: PageModel) -> FieldModel<String> 

You want the method to be able to return any subclass of FieldModel, not one specific subclass.

Of course, also note that HeaderFieldModel is not a subclass of FieldModel<AnyObject>.

Upvotes: 1

Related Questions