【问题标题】:Returning a subclass from its base class in swift快速从其基类返回子类
【发布时间】:2016-09-19 00:58:31
【问题描述】:

我正在尝试允许超类中的方法返回子类的实例,以便我可以使用方法链接以及跨父类和子类的方法。

但是,当我尝试链接方法时,我收到错误消息“BaseClass 没有名为 someOtherChainableMethod 的成员”。这是我的代码:

class BaseClass {
    func someChainableMethod() -> BaseClass {
        return self
    }
}

class ChildClass: BaseClass {
    func someOtherChainableMethod() -> ChildClass {
        return self
    }
}

let childClass = ChildClass

childClass.someChainableMethod().someOtherChainableMethoid()

问题似乎是父链式方法中的“返回自我”返回一个类型为 BaseClass 而不是 ChildClass 的实例。

我也尝试过使用泛型,但失败了,这就是我尝试过的:

class BaseClass<T> {
    func someChainableMethod() -> T {
        return self
    }
}

class ChildClass: BaseClass<ChildClass> {
    func someOtherChainableMethod() -> ChildClass {
        return self
    }
}

let childClass = ChildClass

childClass.someChainableMethod().someOtherChainableMethoid()

在这种情况下,来自 BaseClass someChainableMethod 方法的错误是“BaseClass is not convertible to T”。

【问题讨论】:

    标签: inheritance swift


    【解决方案1】:

    如果您将方法的返回类型更改为Self,您的代码就可以工作:

    class BaseClass {
        func someChainableMethod() -> Self {
            return self
        }
    }
    
    class ChildClass: BaseClass {
        func someOtherChainableMethod() -> Self {
            return self
        }
    }
    
    let childClass = ChildClass()
    let foo = childClass.someChainableMethod().someOtherChainableMethod()
    

    【讨论】:

      【解决方案2】:

      在您的基类中添加 someOtherChaingableMethod 并留下一个空实现。

      【讨论】:

      • 问题是someOtherChaingableMethod方法实际上是ChildClass特有的。有多个具有特定方法的子类,我不想用它们污染我的基类。
      • 或者你可以将你的链方法提取到一个协议中,让所有类实现协议并在你的链方法中响应协议。
      • 不能通过继承实现,因此基类不知道子类的方法。污染所有链方法到你的基类,你也可以有多态性。
      【解决方案3】:

      既然你已经知道 childClass 是 ChildClass 的一个实例,你可以这样做

      (childClass.someChainableMethod() as ChildClass).someOtherChainableMethoid()
      

      【讨论】:

        【解决方案4】:

        只需重写基类 someChainableMethod

        class BaseClass {
            func someChainableMethod() -> Self{
                return self
            }
        }
        
        class ChildClass: BaseClass {
            override func someChainableMethod() -> Self {
                return self
            }
            func A(){
        
            }
        }
        
        var objChild = ChildClass()
        objChild.someChainableMethod()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-12-01
          • 2023-03-20
          • 1970-01-01
          • 2014-04-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多