用語比較
オーバーライドとオーバーロードの違い|Pythonで使えるのはどちらか(Python3基礎)
オーバーライドは、派生クラスが基底クラスのメソッドを同じ名前で書き直すことです。オーバーロードは、同じ名前の関数やメソッドを、引数の違いで使い分ける仕組みです。
継承で上書きするのがオーバーライド、引数で使い分けるのがオーバーロードと区別するのが出発点です。Pythonの公式チュートリアルは、派生クラスでは基底クラスのどのメソッドもオーバーライドでき、メソッドから基底クラスの同名のメソッドも呼び出せると述べています。
この記事の目次
この記事の根拠と出典
各セクションの見出しの下に、公式資料で確認した内容か編集部の整理かをラベルで示しています。 試験日・料金・申込条件・試験方式は変わることがあるため、申込前に公式サイトで確認してください。
オーバーライドとオーバーロードの要点
オーバーライド
派生クラスが、基底クラスと同じ名前のメソッドを書き直すこと。Pythonで普通に使える。
オーバーロード
同じ名前を、引数の違いで使い分けること。Pythonでは、同名のdefを並べても使い分けられない。
違いを表で確認
| 比較軸 | オーバーライド | オーバーロード |
|---|---|---|
| 何をする仕組みか | 継承した基底クラスのメソッドを、派生クラスで書き直す | 同じ名前の定義を、引数の数や型で使い分ける |
| 同名の定義を置く場所 | 基底クラスと派生クラスの2つのクラスに置く | 同じクラスの中に、引数の違う定義を並べる |
| Pythonでの動き | 派生クラスのメソッドが呼ばれる。基底クラスのメソッドも、名前を指定して呼び出せる | 後に書いたdefが名前を束縛し直す。前の定義は呼び出せなくなる |
| 引数の数を変えて呼んだとき | 書き直したメソッドの引数に従う | 後の定義の引数に従い、合わなければTypeErrorになる |
| 公式文書での扱い | チュートリアルが、派生クラスは基底クラスのメソッドをオーバーライドできると述べる | 関数定義は、関数名を関数オブジェクトに束縛すると、リファレンスが述べる |
Python3エンジニア認定基礎試験の学習に使う書籍(Amazon)
PRどこで迷っているかを切り分ける
派生クラスで、親のメソッドの動きを変えたい人
派生クラスに同じ名前のメソッドを書けば、そのクラスのインスタンスではそちらが呼ばれます。これがオーバーライドです。
引数の数を変えた同名メソッドを2つ書いたが、片方しか動かない人
Pythonでは、同じクラスの中で同名のdefを2つ書くと、後に書いたものが前のものを置き換えます。前の定義は呼ばれません。
試験で、同名メソッドを書いた結果を問われた人
基底クラスと派生クラスにあるのか、同じクラスの中にあるのかを、まず確かめます。前者は派生クラスが優先され、後者は後の定義が残ります。
具体例で使い分ける
例 1
基底クラスと派生クラスに、同名のhelloがある場合
Baseのhelloはbaseを返し、Baseを継承したChildのhelloは、Base.hello(self)の結果の前にchild+を付けて返します。
- Childのインスタンスで呼ぶと、Childのhelloが使われます。
- Childのhelloの中で、Base.hello(self)を呼んでいるため、基底クラスの結果も使われます。
結論: Child().hello()はchild+base、Base().hello()はbaseになります。これがオーバーライドです。
例 2
同じクラスの中に、引数の違うfを2つ書いた場合
クラスAの中に、f(self, x)がone、f(self, x, y)がtwoを返す定義を、この順に書いた場面です。
- 後に書いたf(self, x, y)が、名前fを束縛し直します。
- A().f(1)は、引数が足りないため
TypeErrorになり、A().f(1, 2)はtwoを返します。
結論: 引数で使い分けられず、後の定義だけが残ります。Pythonで使えるのはオーバーライドです。
問題文から答えを選ぶ手順
- 1
同名の定義がどこにあるか確かめる
基底クラスと派生クラスにあるのか、同じクラスの中に並んでいるのかを見ます。
- 2
継承の関係なら、派生クラスが優先される
派生クラスのインスタンスから呼ぶと、派生クラスの定義が使われます。
- 3
同じクラスの中なら、後の定義が残る
引数の数が違っても、前の定義は置き換えられます。
- 4
呼び出しの引数を確かめる
残った定義の引数に合わない呼び方は、
TypeErrorになります。
試験での見分け方
- 1オーバーライドは、派生クラスで基底クラスのメソッドを書き直すこと。Pythonで普通に使える。
- 2同じクラスの中の同名のdefは、引数が違っても、後の定義が前の定義を置き換える。
- 3型によって処理を切り替えたい場合の仕組みとして、標準ライブラリのfunctools.singledispatchがある。
誤答しやすい選択肢
オーバーロードを、Pythonの同名メソッドの使い分けだと考える
修正: 同じクラスに同名のdefを書いても、後の定義が残るだけです。引数の違いで自動的に選ばれることはありません。
オーバーライドすると、基底クラスのメソッドが消えると考える
修正: 派生クラスのメソッドが優先されるだけです。派生クラスの中から、基底クラスの同名メソッドを呼び出すこともできます。
オーバーライドとオーバーロードを、同じ意味の言葉だと考える
修正: 前者は継承の関係での書き直し、後者は引数による使い分けです。Pythonで普通に動くのは前者です。
確認問題
Q1派生クラスが、基底クラスと同じ名前のメソッドを書き直すことを何といいますか?
答え: オーバーライド
公式チュートリアルは、派生クラスでは基底クラスのどのメソッドもオーバーライドできると述べています。
Q2同じクラスの中に、f(self, x)とf(self, x, y)をこの順に定義しました。f(1)と呼ぶとどうなりますか?
答え: TypeErrorになる
後に書いたf(self, x, y)が名前fを束縛し直すため、引数yが足りずTypeErrorになります。
Q3Childのhelloが、Base.hello(self)を呼んでいる場合、基底クラスのhelloは使えなくなりますか?
答え: 使えなくならない
メソッドから基底クラスの同名のメソッドを呼び出せると、公式チュートリアルが述べています。
到達チェック
- オーバーライドとオーバーロードの定義を言い分けられる
- 同じクラスの中の同名のdefの結果を説明できる
- 派生クラスの同名メソッドが優先されることを説明できる
- 引数が合わないときに
TypeErrorになることを説明できる
関連ページで確認する
同じ資格で次に知りたいこと
- 内包表記のifの位置の違い|末尾のif句(絞り込み)と先頭のif-else(値の切り替え)
リスト内包表記の末尾にif句を置く書き方と、先頭にif-elseの条件式を置く書き方の違いを、要素数が変わるかどうか、elseを書けるかどうかから解説。Python 3 エンジニア認定基礎試験での読み取り手順と確認問題つきです。
- isinstanceとtypeの違い|派生クラスを含めて判定するか、型そのものを返すか(Python3基礎)
isinstance()とtype()の違いを、返す値、派生クラスの扱い、boolとintの例、複数の型の判定で解説。Python3エンジニア認定基礎試験で問われるクラスの継承と型判定の確認問題つきです。
- リスト内包表記とfor文の使い分け
リスト内包表記とfor文の使い分けを、同じ処理の書き比べ、ifの位置、ループ変数の扱い、Python 3 エンジニア認定基礎試験での読み取り手順と確認問題まで解説します。
よくある質問
Qオーバーライドとオーバーロードの違いは何ですか?
オーバーライドは、派生クラスが基底クラスのメソッドを書き直すことです。オーバーロードは、同名の定義を引数の違いで使い分けることで、Pythonではdefを並べても使い分けられません。
QPythonで同名のメソッドを2つ書くとどうなりますか?
後に書いた定義が名前を束縛し直し、前の定義は呼ばれません。Pythonのリファレンスは、関数定義が関数名を関数オブジェクトに束縛すると述べています。
Qオーバーライドしたメソッドから、基底クラスのメソッドを呼べますか?
呼べます。公式チュートリアルは、メソッドから基底クラスの同名のメソッドを呼び出せると述べています。
Q型によって処理を分けたいときはどうしますか?
標準ライブラリのfunctools.singledispatchは、関数をシングルディスパッチジェネリック関数に変換します。ただし、基礎試験の範囲を超える話です。
次に見る比較
- G検定・DS検定・統計検定2級で重なる用語10語の比較
同じ名前の用語の定義と収録章を、資格ごとに並べます。
- ベイズの定理と条件付き確率の違い(統計検定2級の式と計算例)
求める確率の向きの違いと、陽性になる確率の計算例を確かめます。
- 紛らわしい用語ペア早見表
混同しやすい用語の違いと判定の手掛かりを、資格別の一覧で確かめます。
執筆: AI資格ドリル編集部(運営者情報を見る)
