Mam tendencję do umieszczania tylko niezbędnych elementów (przechowywanych właściwości, inicjatorów) w definicjach moich klas i przenoszę wszystko inne do ich własnych extension, podobnie jak w przypadku extensionbloku logicznego, z // MARK:którym również bym się grupował.
Na przykład w przypadku podklasy UIView chciałbym otrzymać rozszerzenie do rzeczy związanych z układem, jedno do subskrybowania i obsługi zdarzeń i tak dalej. W tych rozszerzeniach nieuchronnie muszę przesłonić niektóre metody UIKit, np layoutSubviews. Nigdy nie zauważyłem żadnych problemów z tym podejściem - do dzisiaj.
Weźmy na przykład tę hierarchię klas:
public class C: NSObject {
public func method() { print("C") }
}
public class B: C {
}
extension B {
override public func method() { print("B") }
}
public class A: B {
}
extension A {
override public func method() { print("A") }
}
(A() as A).method()
(A() as B).method()
(A() as C).method()
Wynik jest A B C. To nie ma dla mnie sensu. Czytałem o statycznym wysyłaniu rozszerzeń protokołów, ale to nie jest protokół. Jest to zwykła klasa i oczekuję, że wywołania metod będą dynamicznie wysyłane w czasie wykonywania. Oczywiście wezwanie Cpowinno być przynajmniej dynamicznie wysyłane i produkować C?
Jeśli usunę dziedziczenie z NSObjecti Cutworzę klasę root, kompilator narzeka, mówiąc declarations in extensions cannot override yet, o czym już czytałem. Ale w jaki sposób posiadanie NSObjectklasy głównej zmienia rzeczy?
Przenoszenie zarówno przesłonięcia do ich deklaracji klasy produkuje A A Azgodnie z oczekiwaniami, poruszając tylko B„s produkuje A B B, poruszając tylko A” s produkuje C B C, z których ostatni ma absolutnie żadnego sensu dla mnie: nie nawet jeden statycznie wpisane do Aprodukuje A-Output więcej!
dynamicWydaje się, że dodanie słowa kluczowego do definicji lub zastąpienia daje mi pożądane zachowanie `` od tego punktu w hierarchii klas w dół '' ...
Zmieńmy nasz przykład na coś nieco mniej skonstruowanego, co właściwie skłoniło mnie do postawienia tego pytania:
public class B: UIView {
}
extension B {
override public func layoutSubviews() { print("B") }
}
public class A: B {
}
extension A {
override public func layoutSubviews() { print("A") }
}
(A() as A).layoutSubviews()
(A() as B).layoutSubviews()
(A() as UIView).layoutSubviews()
Teraz mamy A B A. Tutaj nie mogę w żaden sposób nadać dynamiki layoutSubviews UIView.
Przeniesienie obu nadpisań do ich deklaracji klasy daje nam A A Aponownie, tylko A lub tylko B nadal nas dostaje A B A. dynamicznowu rozwiązuje moje problemy.
Teoretycznie mógłbym dodać dynamicdo wszystkiego, overrideco kiedykolwiek robię, ale czuję, że robię tu coś innego źle.
Czy naprawdę źle jest używać extensions do grupowania kodu, tak jak ja?