覆盖最初在Obj-c超类中定义的swift类中的属性

时间:2016-07-24 16:26:41

标签: swift

虽然我完全理解强类型实现的不良做法,但我有一些需要在子类中更改的通用代码。 obj-c代码中的getter和setter处理 id 类型的值,因此它需要更多的通用值。

// objc
@interface A
@property NSNumber* foo;
@end

// swift subclass
class B : A {
   var foo: String?
}

有没有定义一个属性是Swift,以便它完全取代超类属性?

具有(id)类型的Obj-c的松散类型性质允许一些灵活性,即快速关闭。

1 个答案:

答案 0 :(得分:2)

这是不可能的。您可以覆盖该属性以提供不同的行为,但更改类型会违反OO设计,因此无法编译。

覆盖属性:

override var foo: NSNumber! {
  get { return NSNumber(int: 5) }
  set { }
}

编辑:为什么这会打破OO?

原因是,通过继承A,你保证会像A一样行事。想象一下如果你有这样的函数会发生什么:

func doStuff(obj: A) {
   print("Foo / 2: \(Float(obj.foo.integerValue) / 2.0)")
}

如果您尝试在此处提交B的实例,会发生什么?在强类型的编译语言中,这不能被协调。在动态语言中,这会导致运行时错误。

我还会提到Liskov Substitution Principle

  

可替代性是面向对象编程中的一个原则,它指出,在计算机程序中,如果S是T的子类型,则类型T的对象可以用类型S的对象替换(即,类型的对象) T可以用其类型S)的子类型对象替换而不改变该程序的任何期望属性(正确性,执行的任务等)

这更像是一个指导原则,说明你不应该破坏在你的超类上运行的方法和程序的现有行为,因为你已经进行了子类化。但结构也是如此,只是编译器强制执行此而不是作为指导。