Menu
Coddy logo textTech

メソッドのオーバーライド

CoddyのSwiftジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 23/57。

サブクラスは、継承したメソッドを独自のバージョンで置き換えることができます。キーワード override が必要で、これにより誤ってメソッドを置き換えることを防げます。

class Animal {
    func sound() -> String { "..." }
}

class Dog: Animal {
    override func sound() -> String { "Woof" }
}

class Cat: Animal {
    override func sound() -> String { "Meow" }
}

print(Dog().sound())
print(Cat().sound())
print(Animal().sound())

出力:

Woof
Meow
...

super.method()はオーバーライド内からスーパークラスのバージョンを呼び出すため、サブクラスは継承した動作をすべて置き換えるのではなく、そこに処理を追加できます。

class Report {
    func text() -> String { "Sales: 120" }
}

class SignedReport: Report {
    override func text() -> String {
        super.text() + " (signed by Ada)"
    }
}

print(SignedReport().text())

出力:

Sales: 120 (signed by Ada)

計算プロパティも、override var を使ってオーバーライドできます。

class Shape {
    var sides: Int { 0 }
    var summary: String { "\(sides) sides" }
}

class Triangle: Shape {
    override var sides: Int { 3 }
}

print(Triangle().summary)

出力:

3 sides

オーバーライドは、メソッドが継承されたコードから呼び出された場合でも実行されます。上記の summary は Shape 内に記述されていますが、Triangle の sides を使用します。Swift は常に実際のオブジェクトのバージョンを呼び出すため、オーバーライドが便利なのです。

class Greeter {
    func name() -> String { "someone" }
    func greet() -> String { "Hello, \(name())" }
}

class AdaGreeter: Greeter {
    override func name() -> String { "Ada" }
}

let g: Greeter = AdaGreeter()
print(g.greet())

出力:

Hello, Ada
challenge icon

チャレンジ

簡単

Notification には [info] text を返す render() メソッドがあります。render() が [warn] TEXT(テキストを大文字にしたもの)を返すサブクラス Warning と、保存された minutes を追加し、super を使用してスーパークラスの結果の後に (in 10 min) を続けて返す Reminder を宣言してください。

提供されたコードは、info,text、warn,text、または remind,text,10 の行を読み取り、Notification の配列に適切なオブジェクトを構築し、それぞれに対して render() を出力します。

コードは Notification.swift、Warning.swift、Reminder.swift に記述してください。main.swift には提供された入出力コードが含まれており、編集できません。

自分で試してみよう

// 提供された入出力コード: そのままにしておく
var input: [String] = []
while let line = readLine() { input.append(line) }
var all: [Notification] = []
for line in input {
    let p = line.split(separator: ",").map(String.init)
    switch p[0] {
    case "warn": all.append(Warning(text: p[1]))
    case "remind":
        let r = Reminder(text: p[1])
        r.minutes = Int(p[2])!
        all.append(r)
    default: all.append(Notification(text: p[1]))
    }
}
for n in all { print(n.render()) }
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Swiftプレイグラウンド