Jak others have noted Swift ma (jeszcze) nie pozwalają przesłonić metodę zadeklarowaną w rozszerzeniu klasy. Jednak nie jestem pewien, czy kiedykolwiek uzyskasz pożądane zachowanie, nawet jeśli/kiedy Swift pewnego dnia pozwoli ci na zastąpienie tych metod.
Zastanów się, jak Swift radzi sobie z protokołami i rozszerzeniami protokołów. Biorąc pod uwagę protokół wydrukować kilka metasyntactic nazw zmiennych:
protocol Metasyntactic {
func foo() -> String
func bar() -> String
}
rozszerzeniem zapewniają domyślne implementacje:
extension Metasyntactic {
func foo() -> String {
return "foo"
}
func bar() -> String {
return "bar"
}
}
oraz klasę, która jest zgodna z protokołem:
class FooBar : Metasyntactic {
func foo() -> String {
return "FOO"
}
func bar() -> String {
return "BAR"
}
}
Swift użyje dynamiczna wysyłka wywoływanie odpowiednich implementacji foo()
i bar()
ba sed na każdej zmiennej typu wykonawczego zamiast typu wywnioskowane przez kompilator:
let a = FooBar()
a.foo() // Prints "FOO"
a.bar() // Prints "BAR"
let b: Metasyntactic = FooBar()
b.foo() // Prints "FOO"
b.bar() // Prints "BAR"
Jeśli jednak możemy rozszerzyć protokół ponadto, aby dodać nową metodę:
extension Metasyntactic {
func baz() -> String {
return "baz"
}
}
i jeśli zastąpić naszą nową metodę w klasie, który jest zgodny z protokołem:
class FooBarBaz : Metasyntactic {
func foo() -> String {
return "FOO"
}
func bar() -> String {
return "BAR"
}
func baz() -> String {
return "BAZ"
}
}
Swift będzie teraz używać statycznego wysyłki aby wywołać odpowiednią realizację baz()
na podstawie typu wywnioskowane przez kompilator:
let a = FooBarBaz()
a.baz() // Prints "BAZ"
let b: Metasyntactic = FooBarBaz()
b.baz() // Prints "baz"
Alexandros Salazar a fantastic blog post explaining this behavior in depth, ale wystarczy powiedzieć, że tylko Swift wykorzystuje dynamiczne wysyłkę dla metod zadeklarowanych w oryginalnym protokole, nie dla metod zadeklarowanych w rozszerzeniach protokołu. Wyobrażam sobie, że to samo dotyczy rozszerzeń klas.
Próbowałem również dodać nadpisanie, ale nadklasa nie ma tej właściwości –
W jakiej wersji Swift używasz? Tutaj z Swift 1.2 i Xcode 6.3.1 pojawia się następujący błąd podczas kompilacji, gdy próbujesz przesłonić właściwość _extension_: "Deklaracje z rozszerzeń nie mogą być jeszcze zastąpione" ... i _yet_ sugeruje mi, że będą one w przyszłości. –
Interesujące, więc wygląda na to, że ta funkcja pojawi się w przyszłej wersji. –