Swift:覆盖子类内的typealias

Dev*_*ist 11 generics protocols swift swift2

所以我在考虑项目中的自定义模式,但我无法让它工作.主要的想法是改变typealias每个子类以访问子类特定的接口.

protocol InstanceInterface: class {

    typealias Interface

    var interface: Interface { get }
}

// Baseclass
protocol FirstClassInterface: class { /* nothing here for the example */ }

class FirstClass: InstanceInterface, FirstClassInterface {

    typealias Interface = FirstClassInterface

    var interface: Interface { return self }
}

// Subclass
protocol SecondClassInterface: FirstClassInterface { 

    func foo()
}

class SecondClass: FirstClass, SecondClassInterface {

    typealias Interface = SecondClassInterface // <--- This does nothing :(

    func foo() { print("hello world") } // Swift 2.0 here
}

// Lets say I want to call foo trough the interface
let test = SecondClass()

test.interface.foo() // 'Interface' does not have a member named 'foo'
Run Code Online (Sandbox Code Playgroud)

有什么我做错了或者我误解了一些Swift概念吗?!我确实需要在这里进行子类化,不要一遍又一遍地从超类的协议中实现所有东西.我的小模式甚至可能吗?我很感激任何帮助.:)

dal*_*ook 11

这样的东西会用于你的目的吗?

class MyClass<T> {

}

class MySubclass1: MyClass<String> {

}

class MySubclass2: MyClass<Int> {

}
Run Code Online (Sandbox Code Playgroud)


Qby*_*yte 6

不幸的是,这个问题没有好的解决方法.

超越的主要思想 typealias在这种情况下可行的,但请考虑以下内容:

protocol TakeAndGet {
    typealias T
    func take(value: T)
    func get() -> T
}

class FirstClass: TakeAndGet {
    typealias T = FirstClass

    var property = 0

    func take(value: T) {
        value.property = 4
    }

    func get() -> T {
        return FirstClass()
    }
}

class SecondClass: FirstClass {

    typealias T = SecondClass

    var property2 = "hello"
}
Run Code Online (Sandbox Code Playgroud)

如果typealias所述的SecondClass替代的另一个的take方法将起作用,因为它需要其可以被视为超类的子类.但该get方法无法隐式转换FirstClassSecondClass.因此无法覆盖a typealias.

现在,如果我们想要覆盖它的get功能get() -> SecondClass将无法工作,因为它与超类中的签名不同.另外,我们继承了get导致模糊使用的方法:

SecondClass().get() // which type gets returned? SecondClass or FirstClass
Run Code Online (Sandbox Code Playgroud)

所以你必须尝试不同的方法.

  • 我现在明白了。但是,如果您覆盖子类中的类型别名,仍然应该有某种错误或警告!?我的意思是它什么都不做,即使对于你的例子,它仍然会坚持在 SecondClass 中使用 FirstClass,还是我又错了?覆盖类型别名有什么意义? (3认同)
  • @DevAndArtist 关键是“typealias”不能被覆盖,如果你像在“SecondClass”中声明一个同名的新名称,它会遮蔽另一个。这意味着 `T` 在 `SecondClass` 的范围内是一种不同的类型,但不会改变 `FirstClass` 的 `T`。 (2认同)