Swift 泛型继承

标签 swift generics inheritance

我有一个基本 View Controller 和一些 subview Controller 。我很难将 subview Controller (CommentViewController)中创建的 View 模型传递给其父 View Controller (FeedBaseViewController)进行访问。

class BaseViewController: UIViewController {
    ...
}

class FeedBaseViewController: BaseViewController {
    var viewModel1 = FeedBaseViewModel<BaseObject>()
    ...
}

class CommentViewController: FeedBaseViewController {
    var viewModel2: CommentViewModel<CommentObject>

    init() {
        viewModel2 = CommentViewModel()

        /* This is where I have issue, and I tried a few approaches. And here are the 2 of them.*/
        // Method 1:
        // viewModel1 = viewModel2
        // Error: Cannot assign value of type 'CommentViewModel<CommentObject>' to type 'FeedBaseViewModel<BaseObject>'

        // Method 2:
        // viewModel1 = viewModel2 as FeedBaseViewModel<BaseObject>
        // Error: Cannot convert value of type 'CommentViewModel<CommentObject>' to type 'FeedBaseViewModel<BaseObject>' in coercion

        ...

    }
    ...
}

我的 View Controller View 模型

class FeedBaseViewModel<Item: BaseObject> {
}

class CommentViewModel<T: CommentObject>: FeedBaseViewModel<CommentObject> {
}

这里是对象类,BaseObject类是这里唯一的Objective-C类,还有一个继承自BaseObject的CommentObject swift类。

@interface BaseObject : NSObject <NSCoding>
@end

class CommentObject: BaseObject {
}

我不确定是否可以这样做,或者这只是语法问题。 请指教,谢谢!

已编辑(2017-09-11):

我想我可以提供更多关于我想要实现的目标的信息,希望它有所帮助。

FeedBaseViewModel 存储和操作 BaseObject 类型的项目数组。 FeedBaseViewController 具有 UI 处理操作,例如“过滤”、“排序”,并要求 FeedBaseViewModel 来完成这项工作。

对于注释部分,我将有一个带有基本操作和一些特定操作的 CommentObject 数组。这就是为什么 CommentViewModel 出现的原因,CommentViewModel 继承 FeedBaseViewModel 这样基本的操作就可以由父级来处理,并且它会自己做具体的操作。

与 View Controller 部分类似,CommentViewController会继承FeedBaseViewController,因此FeedBaseViewController可以做基本的处理,而CommentViewController code>本身可以提供额外的功能。

最佳答案

我认为这是不可能的。

您的问题归结为:

let m = FeedBaseViewModel<CommentObject>()
let k : FeedBaseViewModel<BaseObject> = m

这是不允许的。至于原因:假设 FeedBaseViewModel 包含其泛型类型的成员,并为该成员提供 set 函数。 如果您现在被允许编写第二行,则使用会违反 通用约束的 BasObject 实例调用 set m 因为它们仍然是具有不同通用约束的相同对象实例,所以 BaseObject 实例不一定是 CommentObject 的实例。

您的情况的解决方案应该是将泛型向上移动一点:

class FeedBaseViewController<T : BaseObject>: BaseViewController {

    var viewModel1: FeedBaseViewModel<T>

    required init?(coder aDecoder: NSCoder) {
        viewModel1 = FeedBaseViewModel<T>()
        super.init(coder: aDecoder)
    }
}

class CommentViewController: FeedBaseViewController<CommentObject> {
    var viewModel2: CommentViewModel<CommentObject>

    required init?(coder aDecoder: NSCoder) {
        viewModel2 = CommentViewModel<CommentObject>()
        super.init(coder: aDecoder)
        viewModel1 = viewModel2 
        // now this assignment is allowed because viewModel1 and viewModel2 have the super type FeedBaseViewModel<CommentObject>
    }
}

但不确定该解决方案是否适合您的情况。

关于Swift 泛型继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46112299/

相关文章:

swift - 在 RxSwift 中将一种类型的列表映射到另一种类型,但保留现有列表

java - 具有相关类型的通用键/值的通用映射

c# - 如何测试类的实例是否为特定泛型类型?

Java继承设计思想 - 求指教

swift - 添加左侧按钮和标题后右侧按钮不显示

swift - 反转 Swift 字典中值的键,收集重复值

ios - 即使设置了高度,UIScrollView 也无法正常工作

c# - 为什么我们不能在派生类中使用带参数的构造函数

java - 当 Java 编译器看到关键字 extends 时会做什么?

Ruby:如何从类方法设置实例变量?