Анонимный класс в быстром
Есть ли эквивалентный синтаксис или метод для анонимного класса в Swift? Просто для разъяснения Анонимный класс в примере Java здесь - http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
Благодарю!
Ответы
Ответ 1
Насколько я знаю, нет эквивалентного синтаксиса.
Что касается эквивалентных методов, теоретически вы можете использовать закрытие и определять структуры и классы внутри них. К сожалению, я не могу заставить это работать на детской площадке или в проекте, не сделав это крушением. Скорее всего, это не готово к использованию в текущей бета-версии.
Что-то вроде...
protocol SomeProtocol {
func hello()
}
let closure : () -> () = {
class NotSoAnonymousClass : SomeProtocol {
func hello() {
println("Hello")
}
}
let object = NotSoAnonymousClass()
object.hello()
}
... в настоящее время выводит эту ошибку:
invalid linkage type for global declaration
%swift.full_heapmetadata* @_TMdCFIv4Test7closureFT_T_iU_FT_T_L_19NotSoAnonymousClass
LLVM ERROR: Broken module found, compilation aborted!
Command /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 1
Ответ 2
Например, шаблон Java-слушателя/адаптера будет переведен в Swift следующим образом:
protocol EventListener {
func handleEvent(event: Int) -> ()
}
class Adapter : EventListener {
func handleEvent(event: Int) -> () {
}
}
var instance: EventListener = {
class NotSoAnonymous : Adapter {
override func handleEvent(event: Int) {
println("Event: \(event)")
}
}
return NotSoAnonymous()
}()
instance.handleEvent(10)
(Сбой компилятора на бета-версии 2)
Проблема в том, что вы всегда должны указывать имя. Я не думаю, что Apple когда-нибудь представит анонимные классы (и структуры и т.д.), Потому что было бы довольно сложно получить синтаксис, который не сталкивается с трейлинг-закрытиями.
Также в программировании анонимных вещей плохо. Именование вещей помогает читателям понять код.
Ответ 3
Вы также можете создать базовый пустой класс, который действует как открытый протокол, и передать закрытие функции init
которая отменяет все, что вы хотите, например:
class EmptyClass {
var someFunc: () -> () = { }
init(overrides: EmptyClass -> EmptyClass) {
overrides(self)
}
}
// Now you initialize 'EmptyClass' with a closure that sets
// whatever variable properties you want to override:
let workingClass = EmptyClass { ec in
ec.someFunc = { println("It worked!") }
return ec
}
workingClass.someFunc() // Outputs: "It worked!"
Это не технически "анонимно", но работает одинаково. Вам предоставляется пустая оболочка класса, а затем вы заполняете ее или переопределяете все параметры, которые вы хотите, когда вы инициализируете ее закрытием.
Это в основном то же самое, за исключением того, что вместо выполнения ожиданий протокола он переопределяет свойства класса.
Ответ 4
Нет синтаксиса анонимного класса в Swift. Но вы можете создать класс внутри методов класса и класса:
class ViewController: UIViewController {
class anonymousSwiftClass {
func add(number1:Int, number2:Int) -> Int {
return number1+number2;
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
class innerSwiftClass {
func sub(number1:Int, number2:Int) -> Int {
return number1-number2;
}
}
var inner = innerSwiftClass();
println(inner.sub(2, number2: 3));
var anonymous = anonymousSwiftClass();
println(anonymous.add(2, number2: 3));
}
}
Ответ 5
Это то, что я закончил делать (шаблон наблюдателя). Вы можете использовать блокировки аналогичным образом, чтобы использовать анонимные классы в Java. Конечно, с очевидными ограничениями.
class Subject {
// array of closures
var observers: [() -> Void] = []
// @escaping says the closure will be called after the method returns
func register(observer: @escaping () -> Void) {
observers.append(observer)
}
func triggerEvent() {
observers.forEach { observer in
observer()
}
}
}
var subj = Subject()
// you can use a trailing closure
subj.register() {
print("observerd")
}
// or you can assign a closure to a variable so you can maybe use the reference to removeObserver() if you choose to implement that method
var namedObserver: () -> Void = {
print("named observer")
}
subj.register(observer: namedObserver)
subj.triggerEvent()
// output:
// observerd
// named observer