Podstawy rzutowania w górę i w dół
Przechodzenie między typami nadklas i podklas.
Podstawy rzutowania w górę i w dół to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Swift Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Swift Academy zawiera 4 lekcji w sumie.
Wprowadzenie do rzutowania typów
Rzutowanie typów pozwala traktować instancję jako obiekt innego typu w obrębie jego hierarchii klas. Polega na sprawdzeniu lub zmianie typu statycznego, a nie na konwersji danych.
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let d = Dog(name: "Rex")
print(d.bark())Hierarchia klas
Rzutowanie wymaga hierarchii. W tym przypadku Dog i Cat dziedziczą po Animal. Dog jest obiektem typu Animal.
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let pet: Animal = Dog(name: "Rex")
print(pet.name)Rzutowanie w górę za pomocą as
Rzutowanie w górę traktuje instancję podklasy jako instancję klasy bazowej. Zawsze się udaje, dlatego używa się zwykłego operatora as.
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let dog = Dog(name: "Rex")
let asAnimal = dog as Animal
print(asAnimal.name)Po co stosować rzutowanie w górę
Rzutowanie w górę jest przydatne do przechowywania różnych podklas razem, na przykład w jednej tablicy, której typ określono jako wspólną klasę bazową.
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let zoo: [Animal] = [Dog(name: "Rex"), Cat(name: "Mia")]
for a in zoo { print(a.name) }Rzutowanie w górę jest zawsze bezpieczne
Ponieważ każda instancja podklasy jest również prawidłową instancją klasy bazowej, kompilator akceptuje operator as przy rzutowaniu w górę, bez ryzyka niepowodzenia.
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let cat = Cat(name: "Mia")
let animal = cat as Animal
print("Treated as Animal:", animal.name)Utrata dostępu po rzutowaniu w górę
Po zapisaniu obiektu jako instancji typu klasy bazowej można wywoływać tylko elementy członkowskie tej klasy. Charakterystyczna dla Dog metoda bark() jest ukryta do czasu wykonania rzutowania w dół.
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
print(a.name)
// a.bark() would not compile hereWprowadzenie do rzutowania w dół
Rzutowanie w dół działa w przeciwnym kierunku: traktuje odwołanie do klasy bazowej jako odwołanie do konkretnej podklasy, aby ponownie uzyskać dostęp do jej elementów. Może się nie powieść, dlatego wymaga użycia as? lub as!.
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
if let dog = a as? Dog {
print(dog.bark())
}Dlaczego rzutowanie w dół może się nie powieść
Kompilator nie może zagwarantować, że dany obiekt Animal jest rzeczywiście obiektem typu Dog. Może być obiektem typu Cat. Ta niepewność sprawia, że rzutowanie w dół musi być sprawdzane.
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let a: Animal = Cat(name: "Mia")
let maybeDog = a as? Dog
print("Is it a Dog?", maybeDog != nil)Rzutowanie w dół w pętli
Typowy schemat polega na iterowaniu po tablicy typu klasy bazowej i rzutowaniu każdego elementu w dół, aby różnie obsługiwać poszczególne podklasy.
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let zoo: [Animal] = [Dog(name: "Rex"), Cat(name: "Mia")]
for a in zoo {
if let dog = a as? Dog { print(dog.bark()) }
if let cat = a as? Cat { print(cat.meow()) }
}Podsumowanie rzutowania w górę i w dół
Rzutowanie w górę (as) prowadzi w stronę typu bazowego i zawsze się udaje. Rzutowanie w dół (as? lub as!) prowadzi w stronę konkretnego typu i może się nie powieść.
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let d = Dog(name: "Rex")
let up = d as Animal
let down = up as? Dog
print(up.name, down?.bark() ?? "no")Rzutowanie tylko w obrębie jednej hierarchii
Można rzutować tylko między typami powiązanymi w ramach tej samej hierarchii. Typów niepowiązanych nie można rzutować na siebie nawzajem.
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
print(a is Animal)
print(a is Dog)Szybkie sprawdzenie
Proszę przypomnieć sobie, który kierunek rzutowania zawsze kończy się powodzeniem.
Podsumowanie: rzutowanie w górę i w dół
Dowiedział się Pan / Dowiedziała się Pani, że rzutowanie działa w obrębie hierarchii klas, że rzutowanie w górę za pomocą as w stronę typu bazowego zawsze się udaje, a rzutowanie w dół w stronę konkretnej podklasy może się nie powieść i dlatego wymaga operatorów sprawdzających przedstawionych w następnej części.
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let pets: [Animal] = [Dog(name: "Rex"), Cat(name: "Mia")]
for p in pets {
if let d = p as? Dog { print(d.bark()) } else { print(p.name) }
}Często zadawane pytania
Czy lekcja „Podstawy rzutowania w górę i w dół” jest bezpłatna?
Tak — pełny tekst „Podstawy rzutowania w górę i w dół” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Swift Academy, przejdź na CoddyKit PRO. Kurs Swift Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Podstawy rzutowania w górę i w dół”?
Przechodzenie między typami nadklas i podklas. Ćwiczysz Swift Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Swift Academy?
Nie wymagamy żadnego doświadczenia. Swift Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Podstawy rzutowania w górę i w dół”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Swift Academy?
Tak. Każda lekcja Swift Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Podstawy rzutowania w górę i w dół
- Warunkowe rzutowanie za pomocą as?
- Wymuszone rzutowanie za pomocą as! i jego zagrożenia
- Sprawdzanie typów za pomocą is