【问题标题】:Swift: overriding typealias inside subclassSwift:在子类中覆盖类型别名
【发布时间】:2015-08-21 10:43:29
【问题描述】:

所以我正在考虑在我的项目中使用自定义模式,但我无法让它发挥作用。主要思想是更改每个子类上的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'

是我做错了什么还是我误解了一些 Swift 概念?!我确实需要在这里进行子类化,以免一遍又一遍地实现超类协议中的所有内容。我的小模式甚至可能吗?我会很感激任何帮助。 :)

【问题讨论】:

    标签: swift generics protocols swift2


    【解决方案1】:

    这样的东西对你有用吗?

    class MyClass<T> {
    
    }
    
    class MySubclass1: MyClass<String> {
    
    }
    
    class MySubclass2: MyClass<Int> {
    
    }
    

    【讨论】:

      【解决方案2】:

      很遗憾,这个问题没有好的解决方法。

      覆盖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"
      }
      

      如果SecondClasstypealias 覆盖另一个take 方法将起作用,因为它采用可被视为超类的子类。但是get 方法不能将FirstClass 隐式转换为SecondClass。因此无法覆盖typealias

      现在,如果我们想用get() -&gt; SecondClass 覆盖get 函数,它不会起作用,因为它与超类中的签名不同。另外我们继承了get 方法,导致使用不明确:

      SecondClass().get() // which type gets returned? SecondClass or FirstClass
      

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

      【讨论】:

      • 我现在明白了。但是,如果您覆盖子类中的类型别名,仍然应该有某种错误或警告!?我的意思是它什么都不做,即使对于你的例子,它仍然会坚持在 SecondClass 中的 FirstClass,还是我又错了?重写 typealias 有什么意义?
      • @DevAndArtist 关键是typealias 不能被覆盖,如果你声明一个与SecondClass 相同名称的新的,它会影响另一个。这意味着TSecondClass 的范围内是一个不同的类型,但不会改变FirstClassT
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 2022-11-05
      • 2014-12-04
      • 1970-01-01
      • 2017-03-20
      • 2020-01-09
      相关资源
      最近更新 更多