出于C++/Java/C#背景,我希望在Swift中看到虚拟方法,但是在阅读swift文档时,我没有看到虚拟方法。
我遗漏了什么?
由于有大量的评论,我决定悬赏给一个最新的和非常清楚/详细的答案。
发布于 2014-08-22 09:23:46
与C++不同,在Swift中没有必要指定一个方法是虚拟的。编译器将确定使用以下哪一项:
(性能指标当然取决于硬件)
当然,Objective-C总是使用后者。4.9 is的开销通常不是问题,因为这只占整个方法执行时间的一小部分。然而,在必要的地方,开发人员可以无缝地退回到C或C++。然而,在Swift中,编译器将分析哪些最快的可以使用,并试图代表您做出决定,支持内联、静态和虚拟,但保留用于Objective-C互操作性的消息传递。可以用dynamic标记一个方法来鼓励消息传递。
这样做的一个副作用是,动态分派提供的一些强大功能可能不可用,因为以前可以假设任何Objective-C方法都是这种情况。动态分派用于方法截获,方法截获由以下对象使用:
上面的这些特性是由late binding语言提供的。请注意,虽然Java使用vtable分派进行方法调用,但它仍然被认为是一种后期绑定语言,因此由于具有虚拟机和类加载器系统(这是提供运行时插装的另一种方法),因此能够提供上述功能。“纯”Swift (没有Objective-C互操作)类似于C++,因为它是一种具有静态分派的直接到可执行的编译语言,那么这些动态功能在运行时是不可能的。在ARC的传统中,我们可能会看到更多这类功能转移到编译时间,这在“性能功耗比”方面提供了优势-移动计算中的一个重要考虑因素。
发布于 2014-06-03 19:52:54
所有方法都是虚拟的;但是,您需要使用override关键字声明您正在覆盖基类中的方法:
覆盖
子类可以提供它自己的实例方法、类方法、实例属性或下标的自定义实现,否则它将从超类继承。这就是所谓的覆盖。
要覆盖原本会被继承的特征,您可以在覆盖定义前面加上override关键字。这样做表明您打算提供覆盖,并且没有错误地提供匹配的定义。意外地重写可能会导致意外的行为,任何没有override关键字的重写都会在编译代码时被诊断为错误。
override关键字还提示Swift编译器检查覆盖类的超类(或其父类之一)是否具有与您为覆盖提供的声明相匹配的声明。此检查确保您的覆盖定义是正确的。
发布于 2014-06-05 05:16:30
class A {
func visit(target: Target) {
target.method(self);
}
}
class B: A {}
class C: A {
override func visit(target: Target) {
target.method(self);
}
}
class Target {
func method(argument: A) {
println("A");
}
func method(argument: B) {
println("B");
}
func method(argument: C) {
println("C");
}
}
let t = Target();
let a: A = A();
let ab: A = B();
let b: B = B();
let ac: A = C();
let c: C = C();
a.visit(t);
ab.visit(t);
b.visit(t);
ac.visit(t);
c.visit(t);请注意A和C的visit()中的self引用。就像在Java语言中一样,它不会被复制过来,相反,self会保持相同的类型,直到再次在覆盖中使用它。
结果是A,C,C,所以没有可用的动态调度。不幸的是。
https://stackoverflow.com/questions/24014045
复制相似问题