「親クラスの機能はだいたいそのままで、ここだけ自分用に変えたい…」そんなときに使えるのが、オブジェクト指向のオーバーライド(Override)です。
Pythonのクラスと継承を使えば、既存の振る舞いを活かしながら必要な部分だけを上書きできます。 IT初心者の方でも安心して読み進められるよう、基本から丁寧に解説していきます。
オーバーライドとは、親クラスにあるメソッドと同じ名前のメソッドを子クラスで書き直すことです。 同じ「speak」という名前でも、犬なら犬らしく、猫なら猫らしく振る舞ってほしいですよね?その「同じ名前だけど中身は違う」を実現するのがオーバーライドです。
「同じメソッド名なのに結果が変わるってどういうこと?」と不思議に感じるかもしれませんが、これがオブジェクト指向の強みです。
コードの再利用と柔軟なカスタマイズを両立できます。
次のコードでは、共通の親クラス Animal と、子クラス Dog と Cat を用意します。 Dog と Cat は、同じ speak というメソッドをそれぞれのルールで上書きします。
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "ワーワーと鳴きます。"
class Dog(Animal):
def speak(self):
return f"{self.name}はワンワンと鳴きます。"
class Cat(Animal):
def speak(self):
return f"{self.name}はニャーニャーと鳴きます。"
pochi = Dog("ポチ")
mike = Cat("ミケ")
print(pochi.speak()) # 出力: ポチはワンワンと鳴きます。
print(mike.speak()) # 出力: ミケはニャーニャーと鳴きます。
まず Animal クラスが基準になります。__init__ で名前を受け取り、インスタンスの属性として保存します。speak は「動物の一般的な鳴き方」を返すだけの、いわばデフォルトの実装です。
そのうえで、Dog クラスは Animal を継承しながら speak を「犬らしく」書き換えます。インスタンスに保存してある name を使って「ポチはワンワン」と返すようにしています。同様に、Cat クラスも speak を「猫らしく」上書きします。
結果として、同じ speak という呼び出しでも、どのクラスのインスタンスかによって返り値が変わります。
「同じ名前で違う動作」——これがオーバーライドの基本です。
オーバーライドしないとどうなるでしょうか? 試しに、Animal を継承するけれど speak を上書きしないクラスを作ってみましょう。
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "ワーワーと鳴きます。"
class Bird(Animal):
pass
tori = Bird("ハト")
print(tori.speak()) # 出力: ワーワーと鳴きます。
Bird は speak を定義していないので、親クラス Animal の実装がそのまま使われます。
つまり、オーバーライドは必要なときだけすればよく、何もしなければ親の振る舞いを引き継げる、というわけです。ここが継承とオーバーライドの便利なところです。
Pythonは「今、どのクラスのインスタンスが使われているか」を見て、最も近いところ(子クラス側)にあるメソッドを優先して呼び出します。
この仕組みによって、同じ speak() という呼び出しでも、Dog なら犬用、Cat なら猫用の処理が実行されます。難しい用語では「メソッド解決」や「動的ディスパッチ」と呼ばれますが、要するに「その子に合ったやり方を選んでくれる」イメージでOKです。
「名前を同じにするだけでいいの?」と思うかもしれません。 基本的にはその通りですが、実務でつまずきやすいポイントをやさしく押さえておきましょう。
次に別のクラスを使って実践してみましょう! たとえば新しい動物 Fox を作って、speak をキツネらしく書き換えてみます。
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "ワーワーと鳴きます。"
class Fox(Animal):
def speak(self):
return f"{self.name}はコンコンと鳴きます。"
kon = Fox("コン吉")
print(kon.speak()) # 出力: コン吉はコンコンと鳴きます。
Dog や Cat のときと同じ要領で書けましたか?この「同じ型の手順で増やせる」というのが、オブジェクト指向とオーバーライドの強力さです。
今回学習した内容をまとめます。
「同じ名前で、違う動きをさせる」——この感覚が身につくと、クラス設計が一気に楽になります。 次は super() を使って、上書きと「親の呼び出し」を上手に組み合わせる方法を学びましょう。