2015-11-30 2 views
3

факторизовать мой код, я хочу, чтобы установить stringKey из класса ребенка, который я буду получать в классе FUNC в родительском классе:Override статический вар у ребенка класса Swift

Chair.request(); 
Table.request(); 

class Furniture: NSObject { 

    static let requestKey : String! 

    class func request(){ 

     print("class key => \(self.requestKey)") 
     ... 
    } 
} 

class Chair: Furniture { 
    static let requestKey : String = "jsonchairs" 
} 

class Table: Furniture { 
    static let requestKey : String = "tables" 
} 

Конечно, у меня есть сообщение об ошибке прекомпилированного

недвижимость не переопределяет любое имущества от суперкласса

есть ли решение, чтобы сделать это, или мне нужно, чтобы передать ключ как пункт метр? например:

Chair.request(key : "jsonchairs"); 
Table.request(key : "tables"); 
+1

Зачем вам нужна статика здесь? У вас может быть переменная-член, такая как furnitureType, и может переопределить ее в инициализаторе соответствующих подклассов. – Shripada

+0

Любой класс instanciated, я использую только метод класса ... –

ответ

0

Вы можете использовать протоколы для этого. Просто заставьте их обоих соответствовать примеру RequestKeyProtocol fir и реализовать его в каждом случае.

protocol RequestKeyProtocol { 
var requestKey: String 
} 




class myClass: RequestKeyProtocol { 
    var requestKey = "myKey" 
    } 

Если вам требуется значение по умолчанию, посмотрите на расширения протоколов. Take a look at this year WWDC video about protocols as well.

+0

Я думаю, что это (+1) - это правильный способ решить эту проблему в Swift. Используйте протокол для объявления переменной. Я бы, вероятно, также использовал расширение протокола для реализации метода 'request'. – Rob

1

Я считаю, что vale верна, что в этом случае обычно рассматриваются протоколы. В дополнение к определению протокола для requestKey, я бы также реализовать request как реализация по умолчанию протокола:

// define Furniture protocol 

protocol Furniture { 
    static var requestKey: String { get } 
    static func request() 
} 

// implement default implementation in extension 

extension Furniture { 
    static func request() { 
     print("class key => \(self.requestKey)") 
    } 
} 

// both Chair and Table conform to this protocol 

class Chair: Furniture { 
    static let requestKey = "jsonchairs" 
} 

class Table: Furniture { 
    static let requestKey = "tables" 
} 

Заметьте, я предполагаю, что Furniture базовый класс не был действительно нужен, так что я co-opted для моего протокола. Вам просто нужно решить, действительно ли вам нужен базовый класс Furniture. Мое правило, поскольку я перешел от объектно-ориентированного к протоколовому программированию, состоит в том, могут ли быть конкретные экземпляры этого типа Furniture, или же он больше абстрактного/виртуального типа, который используется просто для определения некоторого общего поведения другие типы, которые в конечном итоге будут созданы (т.е. Chair и Table).

Если Furniture действительно конкретный тип, тогда вам нужно будет найти способ достижения желаемого, не используя типы или методы static, потому что вы не можете переопределить статику. Если вы покажете нам, как вы используете этот тип Furniture в дополнение к типам Chair и Table, мы можем помочь вам реорганизовать его таким образом, чтобы вам не нужны методы и типы static.

Но если Furniture не является конкретным типом, тогда я предлагаю подтолкнуть себя и посмотреть, сможете ли вы выполнить все, что нужно, с помощью протокола. Когда вы делаете переход от объектно-ориентированного программирования к протоколо-ориентированному программированию, для его поиска требуется немного времени. Просто не будьте слишком Crusty. Для получения дополнительной информации см. WWDC 2015 video Protocol-Oriented Programming in Swift или эквивалент WWDC 2016 video Protocol and Value Oriented Programming in UIKit Apps.

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

3

Просто у той же проблемы. Используйте рассчитанные свойства - они могут быть переопределены.

Базовый класс:

class BaseLanguage { 
    class var language: String { 
     return "Base" 
    } 

    static func getLocalized(key: String) -> String { 
     print("language: \(language)"); 
    } 
} 

Детский класс:

class German: BaseLanguage { 
    override class var language: String { 
     return "de" 
    } 
} 

Если вы не можете использовать вычисляемые свойства какой-то причине, вы всегда можете обернуть переменные свойства в частном одноплодной. Класс предоставляет внешний интерфейс как статический, но внутри он имеет статическую частную ссылку на свой экземпляр. Вы можете изменить значение любого свойства (до тех пор, пока оно является переменной) в методе init.

Смежные вопросы