Access class property from instance?

12

I am not sure is this is correct behaviour or if its unintended. I have setup StealthFighter so that it returns a class type computed property variable called 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
}

When directly accessing the class StealthFighter this works fine and returns 500 as expected. But if I create and instance myStealthFighter and then try and access the class property on the instance I get the error: 'StealthFighter' does not have a member named 'ammunition' I can't find any mention of this, I am assuming from this that class properties are accessible only via the class? and not on any instances created from it? I just want to make sure I am understanding this correctly ...

EDIT:

So I have probably worded the type variable name wrong as it should probably be maxAmmunition to signify that StealthFighters can only take 500 rounds. I can see the point, if you want the maxAmmunition for the class then you ask the class.

As @Kreiri and @0x7fffffff points out it does seem that you can ask the instance what the class ammunition (or maxAmmunition) is by using dynamicType.

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

.

// OUTPUT
// CLASS - AMMUNITION: 500
// INSTA - AMMUNITION: 500
swift
asked on Stack Overflow Jun 19, 2014 by fuzzygoat • edited Jun 19, 2014 by fuzzygoat

5 Answers

10

Your assumption is correct. Type variables are only meant to be accessed directly from the class. If you want to get at them from an instance, you can do so by accessing the dynamicType property on your instance, like so.

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

However, I don't think that this is the correct approach for you to be taking here. Assuming that you want to have one class "StealthFighter", and possibly multiple instances of that class, each with the ability to have its own number of missiles independent of the others, you should probably make this an instance variable by simply ditching the class keyword.

answered on Stack Overflow Jun 19, 2014 by Mick MacCallum • edited Jun 19, 2014 by Mick MacCallum
3

These properties are known as Type properties in swift. It should be called on its type ie class name, not on instance. Type properties holds same value across all the instances of the class just like static constant in C.

Querying and Setting Type Properties

Type properties are queried and set with dot syntax, just like instance properties. However, type properties are queried and set on the type, not on an instance of that type

Excerpt from : swift programming language

answered on Stack Overflow Jun 19, 2014 by Anil Varghese • edited Jun 19, 2014 by Anil Varghese
3

dynamicType allows access instance’s runtime type as a value, so accessing class property from instance would look like this:

var myStealthFighter = StealthFighter()
myStealthFighter.dynamicType.ammunition

Works in playground, at least.

answered on Stack Overflow Jun 19, 2014 by Kreiri
2

Yes. This is a correct behaviour. These Type Properties can only be accessed over the Type and are not available on the instance itself.

In the Swift Book from Apple it is described in the section "Type Properties" (Page 205).

Swift Type Properties

“Unlike stored instance properties, you must always give stored type properties a default value. This is because the type itself does not have an initializer that can assign a value to a stored type property at initialization time"

answered on Stack Overflow Jun 19, 2014 by Prine
1

Swift 4:

var myStealthFighter = StealthFighter()
type(of: myStealthFighter).ammunition
answered on Stack Overflow Nov 30, 2017 by Vlad

User contributions licensed under CC BY-SA 3.0