从泛型类继承初始值设定项

时间:2015-12-13 10:46:31

标签: ios swift generics inheritance swift2

我已经看过一些关于这个问题的讨论,但还没有看到令人满意的解释。任何人都可以告诉我为什么这不起作用?

class Parent<T> {

  var data:T

  init(data:T) {
    self.data = data
  }
}

class Child : Parent<Int> {}

let c = Child(data: 4)

最后一行给出错误:

'Child' cannot be constructed because it has no accessible initializers

我是否真的需要实现初始化程序才能调用super

修改

为了给出一些上下文,真正的代码看起来更接近下面。我有一个使用泛型的Action类,因为我有另外一些可以将动作链接在一起的代码,我想使用Swift的类型安全来确保可以链接动作。然后我有一堆子类(例如CustomAction)。我正在寻找一种方法来避免覆盖每个子类中的init方法。或者,我想了解为什么这是不可能的。

class Action<Input, Output> {

  var cachedOutput:Output?

  init(cachedOutput:Output?) {
    self.cachedOutput = cachedOutput
  }
}

protocol CustomInput {}
protocol CustomOutput {}

class CustomAction : Action<CustomInput, CustomOutput> {
}

2 个答案:

答案 0 :(得分:2)

是的,你真的需要覆盖init方法..

# app/controllers/api/v1/profiles_controller.rb
module Api
  module V1
    class ProfilesController < ApplicationController
      # To allow only json request
      protect_from_forgery with: :null_session, if: Proc.new {|c| c.request.format.json? }

      # POST yoursites.com/api/v1/profiles
      def create
      end
    end
  end
end

有什么错误...

class Parent<T> {

    var data:T

    init(data:T) {
        self.data = data
    }
}

class Child<T> : Parent<T> {
    override init(data: T) {
        super.init(data: data)
    }
}

let c = Child(data: 4)       // Child<Int>
let c2 = Child(data: "alfa") // Child<String>
那太可怕了,不是吗?所以看看我的最后一个例子!

// what is the type T ? it is undeclared!
class Child2: Parent2<T> {}
// how to specialize non-generic type Parent ? how to create it?
// i need an initializer in class Child3 ... Hm ...
class Child3: Parent<Int> {}

// cannot specialize non-generic type 'Parent'
class Child3: Parent<Int> {
    override init(data: Int) {
        super.init(data: data)
    }
}
// So, Child3 must be of the same specialized type as Parent!!

在你的情况下它就像

一样
class Parent<T> {

    var data:T

    init(data:T) {
        self.data = data
    }
}

class Child<Double> : Parent<String> {
    init(data: Double) {
        super.init(data: "\(data)")
    }
}

let c = Child(data: 4)       // Child<Int> !!!!!
let d = Child(data: true)    // Child<Bool> !!!

答案 1 :(得分:0)

现在可以在Swift 3中使用。我的原始示例现在可以编译。 <{3}}中没有提到这一点,所以我只能假设这是一个错误。