Когда говорят о создании «частного метода» в Swift или ObjC (или ruby, java или…), эти методы на самом деле не являются частными. Там нет фактического контроля доступа вокруг них. Любой язык, который предлагает даже небольшой самоанализ, позволяет разработчикам получать эти значения извне класса, если они действительно этого хотят.
То, о чем мы на самом деле говорим, это способ определения общедоступного интерфейса, который просто представляет функциональность, к которой мы стремимся, и «скрывает» все остальное, что мы считаем «приватным».
Механизм Swift для объявления интерфейсов есть protocol
, и его можно использовать для этой цели.
protocol MyClass {
var publicProperty:Int {get set}
func publicMethod(foo:String)->String
}
class MyClassImplementation : MyClass {
var publicProperty:Int = 5
var privateProperty:Int = 8
func publicMethod(foo:String)->String{
return privateMethod(foo)
}
func privateMethod(foo:String)->String{
return "Hello \(foo)"
}
}
Помните, что протоколы являются первоклассными типами и могут использоваться везде, где могут типы. И при использовании таким образом они предоставляют только свои собственные интерфейсы, а не интерфейсы реализующего типа.
Таким образом, до тех пор, пока вы используете MyClass
вместо MyClassImplementation
типов параметров и т. Д., Все должно работать:
func breakingAndEntering(foo:MyClass)->String{
return foo.privateMethod()
//ERROR: 'MyClass' does not have a member named 'privateMethod'
}
Есть несколько случаев прямого присваивания, когда вы должны явно указывать тип, а не полагаться на Swift, чтобы вывести его, но это вряд ли нарушает условия:
var myClass:MyClass = MyClassImplementation()
Использование протоколов таким образом семантически, достаточно кратко и, на мой взгляд, очень похоже на расширения классов, которые мы использовали для этой цели в ObjC.