アップキャストとダウンキャストの基礎
スーパークラス型とサブクラス型の間で変換します。
「アップキャストとダウンキャストの基礎」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。
型キャストの概要
型キャストを使うと、クラス階層内でインスタンスを別の型として扱えます。これはデータを変換するのではなく、静的型を確認または変更するものです。
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())クラス階層
キャストには階層が必要です。ここではDogとCatがどちらもAnimalを継承しています。Dogは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)as によるアップキャスト
アップキャストは、サブクラスのインスタンスをスーパークラスとして扱います。必ず成功するため、通常の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)アップキャストする理由
アップキャストは、異なるサブクラスをまとめて格納する場合に便利です。たとえば、共通のスーパークラス型を指定した1つの配列に格納できます。
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) }アップキャストは常に安全
すべてのサブクラスのインスタンスは有効なスーパークラスのインスタンスでもあるため、コンパイラは失敗のリスクなしにアップキャストへの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 cat = Cat(name: "Mia")
let animal = cat as Animal
print("Treated as Animal:", animal.name)アップキャスト後に使えなくなるメンバー
スーパークラス型として格納すると、呼び出せるのはスーパークラスのメンバーだけです。Dog固有のbark()は、ダウンキャストするまで隠れた状態になります。
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 hereダウンキャストの概要
ダウンキャストはその逆で、スーパークラスへの参照を特定のサブクラスとして扱い、そのメンバーを再び使えるようにします。失敗する可能性があるため、as?または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())
}ダウンキャストが失敗する理由
あるAnimalが本当にDogであることを、コンパイラは保証できません。Catかもしれないためです。この不確実性があるので、ダウンキャストは確認して行う必要があります。
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)ループ内でのダウンキャスト
よく使われるパターンは、スーパークラスの配列を反復処理し、各要素をダウンキャストしてサブクラスごとに異なる処理を行うことです。
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()) }
}アップキャストとダウンキャストのまとめ
アップキャスト(as)は基底型の方向へ変換するもので、常に成功します。ダウンキャスト(as?または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 d = Dog(name: "Rex")
let up = d as Animal
let down = up as? Dog
print(up.name, down?.bark() ?? "no")キャストできるのは同じ階層内だけ
キャストできるのは、同じ階層内の関連する型の間だけです。無関係な型同士をキャストすることはできません。
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)確認問題
どちらのキャスト方向が常に成功するかを思い出してください。
復習:アップキャストとダウンキャスト
キャストはクラス階層内で行うこと、基底型に向かう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 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) }
}AI チューターと学ぶ Swift — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 122
- レッスン
- 409
よくある質問
「アップキャストとダウンキャストの基礎」レッスンは無料ですか?
はい。「アップキャストとダウンキャストの基礎」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。
「アップキャストとダウンキャストの基礎」で何を学びますか?
スーパークラス型とサブクラス型の間で変換します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Swift Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「アップキャストとダウンキャストの基礎」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSwift Academyレッスンでコードを書いて実行できますか?
はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- アップキャストとダウンキャストの基礎
- as?による条件付きキャスト
- as!による強制キャストとそのリスク
- isによる型の確認