看完视频here后,我对使用final关键字感到困惑。

以下是视频中的示例图片

ios - 快速优化性能说明-LMLPHP

这里有两个类Pet作为父类,而Dog作为子类,并且我们有makeNoise(p)的函数实现,该函数以Pet实例为参数。但是在后台,编译器在此方法中再插入几行用于检查类。

由于makeNoise(p)将参数作为Pet实例,因此编译器应直接从Pet类中调用属性“名称”,因为方法参数适用于此类。

为什么编译器会担心子类中的重写属性,因为该参数是Pet实例并且编译器知道它。是不是

我的问题可能看起来很愚蠢,但是如果有人可以更清楚地解释它,我将不胜感激。

最佳答案

makeNoise(p: Pet)的参数必须是Pet,但它不是Pet本身的直接实例。由于DogPet的子类,因此它也是Pet。因此,在Swift中,有人将Dog实例传递给makeNoise是完全有效的,在这种情况下,将调用noise的重写版本。同样,此狗可能已为name选择了不同的值。

动态类型

这称为p的“动态类型”。 p的编译时类型为Pet,但是编译器必须考虑以下事实:p的运行时类型可能是覆盖某些内容的Pet子类。这称为p的“动态类型”。在WWDC 2015时使用的Swift 1和Swift 2中,在对象上使用.dynamicType语法确定其运行时类型。 Swift 3使用type(of: object)全局函数。这不是您经常需要的,但是它演示了编译器如何允许子类充当其父类并仍然覆盖它们。
finalfinal告诉编译器该类将不会被子类化,或者该属性或方法将不会被覆盖。这样,它就不需要检查替代。

Swift 3的变化

如果我没记错的话,今年的WWDC 2016 Swift性能 session 没有一次提到final关键字。尽管它在Swift 3中仍然可用并且具有相同的目的,但是有新的方法可以防止子类化和覆盖。这是通过访问控制。 Swift 3引入了open关键字,与public不同。

  • public –模块
  • 内部或外部的任何人都可以访问对象,属性,方法等。
  • open –类或方法不仅可以被任何人访问,还可以被子类化(对于类而言)或被重写(对于方法而言)。

  • 我不确定是否像final一样向Swift编译器传达它不需要进行额外的类型检查。

    关于ios - 快速优化性能说明,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39550709/

    10-11 00:46