从实例访问类属性?

时间:2014-06-19 14:46:22

标签: swift

我不确定这是正确的行为还是无意的。我已设置StealthFighter,以便它返回一个名为ammunition的类类型计算属性变量。

func globalTests() {
    println("globalTests")
    println("AMMUNITION: \(StealthFighter.ammunition)")
    var myStealthFighter = StealthFighter()
    println("MISSILES: \(myStealthFighter.missiles)")
    println("AMMUNITION: \(myStealthFighter.ammunition)") // ERROR
}

class StealthFighter {
    class var ammunition:Int {
    return 500;
    }
    var missiles: Int = 5
}

直接访问班级StealthFighter时,此工作正常并按预期返回500。但是,如果我创建并实例myStealthFighter然后尝试访问实例上的类属性,我会收到错误:'StealthFighter' does not have a member named 'ammunition'我无法提及这一点,我从这里假设类属性只能通过类访问?而不是从它创建的任何实例?我只是想确保我正确理解这一点......

编辑:

所以我可能已经说错了类型变量名称,因为它应该是maxAmmunition来表示StealthFighters只能进行500轮。我可以看到这一点,如果你想要课程的maxAmmunition,那么你就问全班。

正如@Kreiri和@ 0x7fffffff所指出的,你似乎可以通过使用dynamicType向实例询问类弹药(或maxAmmunition)是什么。

println("CLASS - AMMUNITION: \(StealthFighter.ammunition)")
var myStealthFighter = StealthFighter()
println("INSTA - AMMUNITION: \(myStealthFighter.dynamicType.ammunition)")

// OUTPUT
// CLASS - AMMUNITION: 500
// INSTA - AMMUNITION: 500

5 个答案:

答案 0 :(得分:10)

你的假设是正确的。类型变量只能直接从类中访问。如果您想从实例中获取它们,可以通过访问实例上的dynamicType属性来实现,如上所示。

let theFighter = StealthFighter()
let missiles = theFighter.dynamicType.missiles
println(missiles)

但是,我不认为这是你在这里采取的正确方法。假设您想要一个类“StealthFighter”,并且可能有多个该类的实例,每个类都能够拥有自己的导弹数量而不依赖于其他类型,您应该通过简单地抛弃class关键字使其成为实例变量

答案 1 :(得分:3)

这些属性在swift中称为Type properties。它应该在其type ie类名称上调用,而不是在实例上调用。类型属性在类的所有实例中保持相同的值,就像C中的静态常量一样。

  

查询和设置类型属性

     

查询类型属性并使用点语法进行设置,就像实例属性一样。但是,类型属性将在类型上进行查询和设置,而不是在该类型的实例上进行设置

摘自:swift programming language

答案 2 :(得分:3)

dynamicType允许访问实例的运行时类型作为值,因此从实例访问类属性将如下所示:

var myStealthFighter = StealthFighter()
myStealthFighter.dynamicType.ammunition

至少在游乐场工作。

答案 3 :(得分:2)

是。这是正确的行为。这些Type Properties只能通过Type访问,并且在实例本身上不可用。

在Apple的Swift Book中,它在"类型属性"部分中描述。 (第205页)。

Swift Type Properties

  

“与存储的实例属性不同,您必须始终为存储的类型属性提供默认值。这是因为类型本身没有初始化程序,可以在初始化时将值分配给存储的类型属性"

答案 4 :(得分:1)

斯威夫特4:

var myStealthFighter = StealthFighter()
type(of: myStealthFighter).ammunition