Свойство класса доступа из экземпляра?

Я не уверен, что это правильное поведение или непреднамеренное. У меня setup 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' Я не могу найти упоминания об этом, я предполагаю, что свойства класса доступны только через класс? а не на каких-либо экземплярах, созданных из него? Я просто хочу убедиться, что правильно понимаю...

EDIT:

Поэтому я, вероятно, неправильно назвал имя переменной типа, поскольку, вероятно, должно быть maxAmmunition, чтобы обозначить, что StealthFighters может принимать только 500 раундов. Я могу понять, что если вы хотите maxAmmunition для класса, то задаете класс.

Как указывает @Kreiri и @0x7fffffff, кажется, что вы можете спросить экземпляр, что класс боеприпасов (или maxAmmunition), используя dynamicType.

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

.

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

Ответ 1

Ваше предположение верно. Переменные типа предназначены только для доступа непосредственно из класса. Если вы хотите получить от них экземпляр, вы можете сделать это, обратившись к свойству dynamicType на вашем экземпляре, например.

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

Однако я не думаю, что это правильный подход для вас, чтобы вы здесь. Предполагая, что вы хотите иметь один класс "StealthFighter" и, возможно, несколько экземпляров этого класса, каждый из которых имеет возможность иметь собственное количество ракет независимо от других, вы должны, вероятно, сделать это переменной экземпляра, просто отбросив ключевое слово класса.

Ответ 2

Эти свойства известны как Type properties в swift. Он должен быть вызван на его type т.е. имя класса, а не на экземпляр. Свойства типа имеют одинаковое значение во всех экземплярах класса, как и статическая константа в C.

Свойства запроса и настройки типа

Свойства типа запрашиваются и задаются с помощью точечного синтаксиса, как и свойства экземпляра. Однако свойства типа запрашиваются и устанавливаются на тип, а не на экземпляр этого типа

Отрывок из: быстрый язык программирования

Ответ 3

dynamicType позволяет использовать экземпляр экземпляра экземпляра экземпляра как значение, поэтому доступ к экземпляру класса из экземпляра будет выглядеть следующим образом:

var myStealthFighter = StealthFighter()
myStealthFighter.dynamicType.ammunition

Работает на детской площадке, по крайней мере.

Ответ 4

Да. Это правильное поведение. Эти Type Properties могут быть доступны только по типу и не доступны в самом экземпляре.

В Swift Book от Apple описано в разделе "Свойства типа" (Страница 205).

Свойства Swift Type

"В отличие от хранимых свойств экземпляра вы всегда должны указывать хранимые свойства типа по умолчанию. Это связано с тем, что сам тип не имеет инициализатора, который может присваивать значение сохраненному типу свойства во время инициализации"

Ответ 5

Swift 4:

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