PR

【Python】クラスの使い方を3分でわかりやすく解説

Python

Pythonのクラスとは、関連する変数とメソッドをまとめた設計図のようなもので、これにより新しいオブジェクト(インスタンス)を生成することができます。

参考 Pythonの特徴

Pythonのクラスはプログラミング初心者にとっては難しく感じるかもしれません。

クラスはPythonプログラミングの基本概念であり、Pythonを使ってソフトウェアを開発するためには、クラスを理解して活用することが重要です。このページでは、Python初心者がクラスの概念を理解し、自分自身でクラスを作成できるようになるための基本的なガイドを提供します。

クラスの基本概念から実際のサンプルコードまで1から丁寧に解説します。

このページで学べる内容
  • クラスとは何か?基本的な概念
  • クラスの定義方法
    • 属性 / メソッドの定義
    • コンストラクタの定義
    • デストラクタの定義
  • クラス変数 / インスタンス変数
  • インスタンス化とは?
  • 継承(親クラス・子クラスについて)
  • ポリモーフィズムとカプセル化

Pythonエンジニアを目指す方であれば知らないと恥ずかしい超・基本知識の1つです。是非最後までご覧ください。

参考 Pythonの基本的な書き方・構文ルール

スポンサーリンク

Python:クラスとは

クラスは、オブジェクト指向プログラミング言語における非常に重要な概念です。しかし、この「クラス」という単語が何を意味するのかを理解するのは、プログラミング初心者にとって少し難しいかもしれません。

参考 プログラミングとは?

まずはこのページの前提知識―。「クラスとは何か」を詳しく見ていきましょう。

簡単な日常生活の例を使ってご説明します。まず、クラスとは何かを理解するために、車を作る工程を思い浮かべてみてください。あなたは自動車メーカーに勤めていて、新型の車を作りたいと思ったとしましょう。

その際、最初に行う工程が「設計図を作成すること」になるはずです。いきなり車の部品を作り始めるのではなく、車の「形」や「サイズ」「色」や「部品の構成」に加えて、アクセルやブレーキなど、どのような機能を持つべきかを定義する必要があるでしょう。

自動車メーカーは車を1台だけ作ればよいわけではなく、100台~10000台と製造する必要があるので、設計図を作成することは重要な作業になります。

結論を言うと「クラスとは、この設計図のようなもの」です。

どのようなデータ(属性)を持ち、どのような動作(メソッド)をするべきかを定義するのが、クラスを定義するということになります。

車の設計図の例で言えば、データ(属性)とは「車の色」「車種」「製造年」などがそれに該当します。

動作(メソッド)とは「アクセルを踏む」、「ブレーキを踏む」、「ハンドルを切る」などを指します。

Python クラスとは
図1:クラスとは?

設計図があれば、その設計図に従って具体的な車を製造することができます。これがプログラミングにおける「インスタンス化」に相当します。設計図(クラス)をもとに具体的な車(インスタンス)を作るのです。

python クラス インスタンス
図2:インスタンス化
クラスの説明を他で例えると・・・

クラスを説明するための例は無数にあります。このページでは「車」を例に説明しましたが、他にもいろいろな説明が可能。

「車」ではちょっとわかりづらかった・・・という方に何個か例を挙げて補足します。

クラスの説明(例)
  • 銀行口座のクラス: 銀行口座のクラスは、銀行口座の特性(属性)と処理内容(メソッド)を定義します。属性としては、口座番号、口座名義、残高などがあります。メソッドとしては、預金する、引き出す、残高を確認するなどの銀行口座の操作が考えられます。
  • 動物のクラス: 動物のクラスは、動物の基本的な特性と行動を定義します。属性としては、名前、種類、体重、年齢などがあります。メソッドとしては、食べる、寝る、歩く、声を出すなどの動物の行動が考えられます。
  • 商品のクラス: 商品のクラスは、商品の基本情報と行動を定義します。属性としては、商品名、価格、在庫数、商品説明などがあります。メソッドとしては、在庫を増やす、在庫を減らすなどの商品管理の操作が考えられます。

これらの例から分かるように、クラスはそのオブジェクトが持つべき基本的な属性とメソッドを定義するための「設計図」のようなものだと理解しておきましょう!

以下にPythonにおけるクラス定義のサンプルコードを記載します。文法の詳細についてはページ後半で詳しく解説しているので、ここでは何となくPythonにおけるクラスのイメージを理解することができればOK。気軽に眺めてみてください。

# クラスの定義(車の設計図)
class Car:
    def __init__(self, color, model, year):
        self.color = color
        self.model = model
        self.year = year

    def accelerate(self):
        print("アクセルを踏む")

    def brake(self):
        print("ブレーキを踏む")

# インスタンス化(自動車を製造する)
my_ferrari = Car('赤', 'フェラーリ', 2023)

参考 def文

Carクラス名(設計図の名前)を、colormodelyear属性(車の特性)。acceleratebrakeメソッド(車ができる動作)を表しています。このクラスを用いて、「赤色のフェラーリ、製造年は2023年」のような具体的な車を作ることができます。

このように、クラスとは一種の設計図であり、その設計図に基づいて同じ特性を持つオブジェクト(=新型の車)を繰り返し作成することができます。これにより、コードの再利用性の向上させたり、プログラム全体の構造化を行ったりすることが可能になります。

参考 プログラムの構造化(モジュール化)

クラスとは何か?が何となくイメージできたところで、ここからは実際のクラスの定義方法を詳しく解説していきます。

サンプルコード付きで1つ1つ丁寧に説明しますので、焦らずゆっくり学習していきましょう。

Python:クラスの定義方法

Pythonにおけるクラスの定義は以下の形式を基本とします。

class ClassName:
    def __init__(self, 属性1, 属性2, ...):
        self.属性1 = 属性1
        self.属性1 = 属性1
        ...

    def メソッド1(self, ...):
        # メソッド1の処理内容

    def メソッド2(self, ...):
        # メソッド2の処理内容
Python:クラス定義の基本ルール
  • classキーワードに続いてクラス名を記述。
    →クラス名の最初の文字は大文字にするのが一般的です。
  • クラス定義の内部には、そのクラスが持つ属性(データ)メソッド(動作)を記述します。
  • __init__メソッドは、クラスから新しいインスタンスを作成するときに自動的に呼び出される特別なメソッドです(初期化メソッドとも呼ばれます)。このメソッドで、インスタンスが持つ属性を初期化します。
  • selfはクラスのインスタンス自身を指す特別な引数です。各メソッドの最初の引数として必ず指定します。これにより、インスタンスが自身の属性や他のメソッドにアクセスすることができます。

以下に具体的な例を示します。

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def bark(self):
        print(f"{self.name}は吠えます。ワンワン!")

    def get_age(self):
        return self.age

参考 print関数とフォーマット文字列

この例では、Dogというクラスを定義しています。このクラスにはnameageという2つの属性と、barkget_ageという2つのメソッドが存在します。

これでクラスの定義は終了。ここからインスタンス化やメソッドの呼び出しといった具体的な処理を行っていくことになります。

Python:インスタンスの生成(インスタンス化)

インスタンスの生成(インスタンス化)とは、クラスからオブジェクトを生成することです。

つまり、先ほど定義したクラス(設計図)から具体的なオブジェクト(製品)を作成するプロセスがインスタンス化です。具体的なオブジェクトを作成することで、クラスに定義された属性とメソッドを利用することができるようになります。

つまり、クラスを定義しただけではまだ実際に「もの」は作られていないということ。インスタンス化をすることによって、はじめて「もの」がこの世に誕生するイメージです。

Pythonでクラスのインスタンス化を行うには、クラス名を関数のように呼び出します。この際、必要に応じて引数を渡すことができます。これらの引数は、クラスの__init__メソッドに渡され、インスタンスの初期化に使用されます。

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def bark(self):
        print(f"{self.name}は吠えます。ワンワン!")

    def get_age(self):
        return self.age

# クラスのインスタンス化
my_dog = Dog("ポチ", 5)

この例では、まずDogクラスを定義しています。次に、my_dog = Dog("ポチ", 5)の行でDogクラスの新しいインスタンスを作成(インスタンス化)しています。

これで my_dog という「犬」が実際に誕生したことになります。

この際、"ポチ"5という2つの引数を渡しています。これらの引数はDogクラスの__init__メソッドにmy_dogインスタンスのnameageに引き渡されます(=つまり、名前は「ポチ」で年齢は「5歳」という犬を誕生させていることになります。)

クラス:属性の参照

続いてこのインスタンスの属性を参照してみましょう。

インスタンスの属性にアクセスするためには、.(ドット)を使い、インスタンス名の後に属性名を書きます。

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def bark(self):
        print(f"{self.name}は吠えます。ワンワン!")

    def get_age(self):
        return self.age

# クラスのインスタンス化
my_dog = Dog("ポチ", 5)

# インスタンスの属性にアクセスする
print(my_dog.name)  # my_dogインスタンスのname属性にアクセスします。出力:ポチ

my_dog の name属性は「ポチ」でインスタンス化されているため、それを出力した結果は勿論「ポチ」となります。

クラス:メソッドの呼び出し

最後にインスタンスのメソッドを呼び出す方法です。メソッドを呼び出すためには、インスタンス名の後に.(ドット)とメソッド名を書きます

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def bark(self):
        print(f"{self.name}は吠えます。ワンワン!")

    def get_age(self):
        return self.age

# クラスのインスタンス化
my_dog = Dog("ポチ", 5)

# インスタンスの属性にアクセスする
print(my_dog.name)  # my_dogインスタンスのname属性にアクセスします。出力:ポチ

# インスタンスのメソッドを呼び出す
print(my_dog.bark())  # my_dogインスタンスのbarkメソッドを呼び出します。出力:ポチ says woof!

メソッド名の後には()(括弧)が必要で、これがないとメソッドは呼び出されない点に注意しましょう!

Python:__init__(コンストラクタ / 初期化メソッド)

初期化メソッドとは、クラスから新しいインスタンスが生成されるときに自動的に呼び出される特別なメソッドのことを指します。Pythonでは、このメソッドは__init__という名前で定義されます。

言い換えると、インスタンスが作られる場合に、一番最初に一度だけ必ず呼び出されるメソッドが「初期化メソッド」ということになります。

初期化メソッドは主に、インスタンスが持つ属性を初期化するために使用されます。以下に具体的な例を示します。

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

この例では、Dogクラスの初期化メソッドがnameageという2つの引数を受け取り、それぞれをインスタンスの属性として設定しています。

Python:selfの意味

selfは特別な引数で、Pythonが自動的にその値を提供します。具体的には、selfはメソッドを呼び出したオブジェクト(インスタンス)自身を指します。

たとえば、以下のようなDogクラスを定義し、新しいインスタンスを作成したとしましょう。

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

my_dog = Dog("ポチ", 5)

この場合、Dog("ポチ", 5)というコードを実行するとき、Pythonはまず新しいDogインスタンスを作成し(これがselfになります)、次にその新しいインスタンスと一緒に"ポチ"5__init__メソッドに渡します。

したがって、クラスを利用する人から見ると、Dogクラスの初期化メソッドは2つの引数("ポチ"5)を取りますが、クラスの定義者(クラスを書く人)から見ると、__init__メソッドは3つの引数(selfnameage)を取るということになります。

このself引数の存在はPythonのクラス定義の特徴的な部分であり、メソッド内でそのインスタンス自身にアクセスするための手段を提供するために必須となります。

selfがないと、インスタンスメソッドが自分が属するインスタンス自体にアクセスできなくなります。これにより、そのメソッドはインスタンスの属性や他のメソッドを参照したり変更したりすることができなくなります。

class Dog:
    def __init__(self, name, age):
        name = name
        age = age

my_dog = Dog("ポチ", 5)
print(my_dog.name)  # エラー:'Dog' object has no attribute 'name'

このクラスの定義ではselfを使用していません。

その結果、nameage__init__メソッドのローカル変数となります。それらはメソッドの実行が終わると消えてしまい、インスタンスの他のメソッドからはアクセスできません。また、クラスの外からもアクセスできません。

参考 ローカル変数とグローバル変数

Python:__del__(デストラクタ)

デストラクタとは、クラスのインスタンスが不要になり、メモリから消去されるときに自動的に呼び出される特別なメソッドのことを指します。Pythonでは、このメソッドは__del__という名前で定義されます。

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        print(f"{self.name}が生まれました。")

    def __del__(self):
        print(f"{self.name}はこの世を去りました。")

この例では、Dogクラスのデストラクタが__del__メソッドとして定義されています。

このメソッドは、Dogインスタンスが消去されるときに自動的に呼び出されます。ただし、この例はあくまでもサンプルであり、実際のプログラムではデストラクタの使用は通常推奨されないという点に注意。

Pythonの場合、ガベージコレクション(不要なオブジェクトの自動消去)のメカニズムにより、デストラクタが正確なタイミングで呼び出されることは保証されません。そのため、デストラクタを使用するよりも、リソースの解放などを行うための明示的なメソッドを提供する方が一般的に推奨されます。

Python:クラス変数とインスタンス変数

Pythonのクラスには、クラス変数インスタンス変数という2種類の変数があります。これらはそのスコープと生存期間、そして使い方により異なります。

Pythonのクラスをマスターするために重要なポイントとなるので、以下にそれぞれの変数の意味・役割・概念を詳しく解説します。

参考 Python 変数の基本

Python:クラス変数

クラス変数は、クラス定義の中で直接定義されます。つまり、メソッドの外側で、そしてクラスブロック内で定義されます。

class Dog:
    species = "Canis familiaris"  # クラス変数

    def __init__(self, name, age):
        self.name = name  # インスタンス変数
        self.age = age  # インスタンス変数

クラス変数は、そのクラスから生成されたすべてのインスタンス間で共有されます。つまり、ひとつのインスタンスで行われた変更は他のすべてのインスタンスに影響を及ぼす可能性があります。

これはすべてのインスタンスが同一のクラス変数を参照しているためです。したがって、クラス変数は一般的にすべてのインスタンスに共通する値を保持するのに使用されます。

この例では、speciesはクラス変数です。したがって、すべてのDogインスタンスは同じspeciesを共有します。

Python:インスタンス変数

インスタンス変数は特定のクラスのインスタンスに属する変数で、そのスコープはそのインスタンスに限定されます。つまり、インスタンス変数はそのインスタンスによってのみアクセス可能であり、そのインスタンスで行われた変更はそのインスタンスにのみ影響します。

これは、インスタンス変数が各インスタンスに属しているためで、そのため、各インスタンスは独自の値を保持できます。インスタンス変数は通常、__init__メソッド内で、selfを用いて初期化されます。このselfは現在のインスタンスを参照します。

以下のDogクラスの例で言えば、nameageはインスタンス変数です。したがって、Dogクラスの各インスタンスはそれぞれ独自のnameageを持ちます。

class Dog:
    species = "Canis familiaris"  # クラス変数

    def __init__(self, name, age):
        self.name = name  # インスタンス変数
        self.age = age  # インスタンス変数

これらの変数の使い方を理解することは、Pythonでのオブジェクト指向プログラミングを理解する上で非常に重要です。クラス変数は、すべてのインスタンスが共有するデータを表現するのに適しています。一方、インスタンス変数はインスタンスごとに固有の情報を表現するのに最適です。

サンプル クラス変数とインスタンス変数

class Dog:
    # クラス変数
    species = "Canis familiaris"

    def __init__(self, name, age):
        # インスタンス変数
        self.name = name
        self.age = age

# インスタンスの作成
dog1 = Dog("ポチ", 3)
dog2 = Dog("シロ", 4)

print("----- クラス変数 -----")
print(dog1.species)  # Canis familiaris
print(dog2.species)  # Canis familiaris

print("----- インスタンス変数 -----")
print(dog1.name)  # ポチ
print(dog2.name)  # シロ

print("----- クラス変数を変更 -----")
Dog.species = "Canis lupus"
print(dog1.species)  # Canis lupus
print(dog2.species)  # Canis lupus

print("----- インスタンス変数を変更 -----")
dog1.name = "タロウ"
print(dog1.name)  # タロウ
print(dog2.name)  # シロ(変更なし)

この例では、speciesはクラス変数として定義されています。したがって、この変数の値はすべてのDogインスタンスで共有されます。Dog.speciesを変更すると、全てのDogインスタンスのspeciesが変わります。

一方、nameage__init__メソッド内で定義されたインスタンス変数です。したがって、これらの変数の値はそれぞれのDogインスタンスに固有であり、一つのインスタンスでこれらの変数の値を変更しても、他のインスタンスには影響を及ぼしません。

クラスの定義やメソッドの呼び出し、変数のスコープなどについて学習してきました。

覚える内容がたくさんあったと思うので、ひとまずここでクラス定義の基本を復習しておきましょう!

復習

パート1 クラスの定義

class Musician:
    # クラス変数: すべてのMusicianオブジェクトで共有
    genre = "Music"

    # 初期化メソッド: インスタンスが生成されるときに自動的に呼び出される
    def __init__(self, name, instrument):
        # インスタンス変数: 個々のMusicianオブジェクトごとに異なる
        self.name = name
        self.instrument = instrument

    # メソッド: クラスに属する関数
    def play(self):
        return f"{self.name} is playing the {self.instrument}."

Musicianクラスを定義。このクラスは、名前(name)と楽器(instrument)という2つのインスタンス変数を持ち、音楽を演奏するメソッド(play)を持つとします。

パート2 インスタンス化

# Musicianクラスのインスタンスを作成
john = Musician("John Lennon", "guitar")
paul = Musician("Paul McCartney", "bass")

パート3 インスタンスの属性の参照

インスタンスの属性を参照するには、インスタンス名の後に.(ドット)をつけて属性名を記述します。

print(john.name)  # "John Lennon"
print(paul.instrument)  # "bass"

パート4 メソッドの呼び出し

メソッドを呼び出すにも同様に、インスタンス名の後に.(ドット)をつけてメソッド名を記述します。

print(john.play())  # "John Lennon is playing the guitar."
print(paul.play())  # "Paul McCartney is playing the bass."

Python:継承

クラスの基本を学習したところで、さらに実践的なコーディングが行えるようにより専門的な内容である「継承」という概念について解説します。

継承とは、あるクラスの特性を別のクラスが受け継ぐという概念で、これによりすでに定義されたクラスのコードを再利用し、必要に応じてそのクラスを拡張またはカスタマイズすることが可能になります。

クラスからさらに別のクラスを作る、というイメージ。

継承するクラス(新しいクラス)を派生クラスまたは子クラス、継承されるクラス(既存のクラス)を基底クラスまたは親クラスと呼びます。

Pythonでは、継承を行うためには以下の構文を使用します。

class DerivedClassName(BaseClassName):
    <statement-1>
    .
    .
    .
    <statement-N>

ここでBaseClassNameは既存のクラス(親クラス)の名前で、DerivedClassNameは新しく作成するクラス(子クラス)の名前です。この構文により、子クラスは親クラスの属性やメソッドを引き継ぎます。

例として、先ほど定義したDogクラスを親クラスとして、新しいBulldogクラスを作成してみます。

# 親クラスの定義
class Dog:
    species = "Canis familiaris"

    def __init__(self, name, age):
        self.name = name
        self.age = age

# 子クラスの定義
class Bulldog(Dog):
    pass

# インスタンスの作成
my_dog = Bulldog("Max", 5)
print(my_dog.name)  # Max
print(my_dog.age)  # 5
print(my_dog.species)  # Canis familiaris

ここで、Bulldogクラスは親クラスであるDogクラスからspecies属性と__init__メソッドを継承しています。したがって、Bulldogのインスタンスを作成したときにnameageを渡すことができ、またspecies属性にアクセスすることができます。

なお、継承したクラスでは新たにメソッドを追加したり、親クラスのメソッドを上書き(オーバーライド)することも可能です。これにより、既存のクラスを基にして新しい振る舞いを持つクラスを効率的に作成することができます。

サンプル 継承(新たなメソッドを追加)

class Dog:
    species = "Canis familiaris"

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def description(self):
        return f"{self.name} is {self.age} years old"

class Bulldog(Dog):
    def run(self, speed):
        return f"{self.name} runs at {speed}km/h"

# Bulldogクラスのインスタンスを作成
jim = Bulldog("Jim", 5)
print(jim.description())  # Jim is 5 years old
print(jim.run(10))  # Jim runs at 10km/h

この例では、Bulldogクラスは親クラスDogからdescriptionメソッドを継承しています。さらに、新たにrunメソッドを追加しています。

サンプル 継承(親クラスのメソッドを上書き(オーバーライド))

class Dog:
    species = "Canis familiaris"

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def description(self):
        return f"{self.name} is {self.age} years old"

class Bulldog(Dog):
    def description(self):
        return f"{self.name} is a cool dog!"

# Bulldogクラスのインスタンスを作成
jim = Bulldog("Jim", 5)
print(jim.description())  # Jim is a cool dog!

この例では、Bulldogクラスは親クラスDogからdescriptionメソッドを継承していますが、同じ名前のメソッドを新たに定義することでオーバーライドしています。したがって、Bulldogクラスのインスタンスでdescriptionメソッドを呼び出すと、新しく定義したメソッドが使われます。

継承とは・・・?

既存のクラス(親クラス)の属性やメソッドを新しいクラス(子クラス)が引き継ぎ、その上で新たな属性やメソッドを追加すること。

以下は、既存のMusicianクラスを基にして新たなクラスBandを作り、その中で継承を活用する例です。

class Musician:
    def __init__(self, name, instrument):
        self.name = name
        self.instrument = instrument

    def play(self):
        return f"{self.name} is playing the {self.instrument}."

# BandクラスはMusicianクラスを継承します
class Band(Musician):
    def __init__(self, band_name, members):
        self.band_name = band_name
        self.members = members  # membersはMusicianクラスのインスタンスのリストです

    def perform(self):
        performance = f"The {self.band_name} starts their performance:\n"
        for member in self.members:
            performance += member.play() + "\n"
        return performance

このクラスを使って具体的なバンドを作成し、メソッドを呼び出してみます。

# Musicianクラスのインスタンスを作成
john = Musician("John Lennon", "guitar")
paul = Musician("Paul McCartney", "bass")
george = Musician("George Harrison", "guitar")
ringo = Musician("Ringo Starr", "drums")

# MusicianクラスのインスタンスをリストとしてBandクラスのインスタンスを作成
beatles = Band("The Beatles", [john, paul, george, ringo])

# バンドのパフォーマンスを開始
print(beatles.perform())


### 出力結果 ###
# The Beatles starts their performance:
# John Lennon is playing the guitar.
# Paul McCartney is playing the bass.
# George Harrison is playing the guitar.
# Ringo Starr is playing the drums.

参考 for文

Python:ポリモーフィズム(Polymorphism)

続いてクラスを理解するために重要な「ポリモーフィズム」という概念について解説します。

ポリモーフィズムとは、「多態性」を意味する言葉で、同一のインターフェースで異なる動作をする能力を指します。Pythonでは、異なるクラスのオブジェクトでも、それぞれが同じ名前のメソッドを持っていれば、そのメソッドを共通のインターフェースとして扱うことができます。これにより、クラスの実装に依存せずにオブジェクトを一貫した方法で扱うことが可能になります。

例えば、以下のような異なるクラスがあるとします。

class Dog:
    def make_sound(self):
        return "Woof!"

class Cat:
    def make_sound(self):
        return "Meow!"

ここでは、DogクラスとCatクラスの両方がmake_soundメソッドを持っています。これらのクラスのインスタンスを作成し、それぞれに対してmake_soundメソッドを呼び出すことができます。

dog = Dog()
print(dog.make_sound())  # Woof!

cat = Cat()
print(cat.make_sound())  # Meow!

このように、異なるクラスのオブジェクトでも、それぞれが同じメソッド名を持っていれば、そのメソッドを同じように呼び出すことができます。これがポリモーフィズムの一例です。

ポリモーフィズムの有用性

上記の説明だけでは、結局何がうれしいの・・・?と思った方へより詳しくポリモーフィズムについて説明しておきます。

ポリモーフィズムを持つということは、一度定義した関数やメソッドを、異なるクラスのオブジェクトに対して共通に適用することができる!ということを意味します。

以下に具体的なサンプルコードを示します。まず、異なる2つのクラス、DogCatを作成しましょう。これらのクラスは、それぞれvoiceというメソッドを持つこととします。

class Dog:
    def voice(self):
        return "Woof!"

class Cat:
    def voice(self):
        return "Meow!"

次に、これらのクラスを使用するmake_voiceという関数を定義します。

def make_voice(animal):
    return animal.voice()

参考 関数(def文)

この関数は、引数としてDogまたはCatクラスのオブジェクト(インスタンス)を受け取り、そのvoiceメソッドを呼び出します。以下に使用例を示します。

dog = Dog()
cat = Cat()

print(make_voice(dog))  # "Woof!"
print(make_voice(cat))  # "Meow!"

この例では、DogクラスとCatクラスは異なりますが、どちらもvoiceというメソッドを持っています。そのため、make_voice関数はどちらのクラスのオブジェクトに対しても呼び出すことができます。

これがポリモーフィズムの基本的な考え方であり、その有用性を示す一例です。これにより、異なるクラスのオブジェクトを同一の方法で扱うことができ、コードの再利用性と柔軟性が大いに向上します。

Python:カプセル化(Encapsulation)

最後にカプセル化という概念について。

カプセル化とは、オブジェクトの状態(データ)と振る舞い(メソッド)を一つにまとめ、データを外部から直接操作することを制限するプログラミングの手法を指します。これにより、クラスの内部構造や処理手順を外部から隠蔽することが可能になります。

Pythonでは、クラスのメソッドや変数の名前の前にアンダースコア(_)を1つまたは2つ付けることで、それらを外部から隠蔽することが一般的に行われます。アンダースコアを2つ付けた場合は、クラスの外部から直接アクセスすることができなくなります。

class BankAccount:
    def __init__(self, name, balance):
        self.__name = name
        self.__balance = balance

    def deposit(self, amount):
        self.__balance += amount

    def withdraw(self, amount):
        if self.__balance >= amount:
            self.__balance -= amount
        else:
            print("Insufficient balance")

    def get_balance(self):
        return self.__balance

この例では、BankAccountクラスの__name__balance変数は、クラスの外部から直接アクセスすることができません。また、depositメソッドとwithdrawメソッドを通じて、その変数の値を適切な方法で操作することができます。これがカプセル化の一例です。

カプセル化の利点
  • データの保護:カプセル化によりクラスの内部データを外部から直接変更されることを防ぐことができます。これにより、データの不正な操作や予期しない変更から保護することができます。
  • クラスの詳細を隠蔽:クラスの使用者にとっては、そのクラスがどのように動作しているのかを知る必要はありません。彼らが必要とするのは、どのメソッドを呼び出すべきなのか、そのメソッドが何を返すのかだけです。この詳細の隠蔽がカプセル化によって可能となります。
  • モジュール性の向上:カプセル化により、各クラスは独立したモジュールとして扱うことが可能になります。これにより、コードの再利用やテスト、メンテナンスが容易になります。

しかし、注意点として、カプセル化を行うと、一部の機能がクラスの外部から利用できなくなる可能性があります。そのため、どの属性やメソッドを公開するか、どの程度までアクセスを制限するかは慎重に決定する必要があります。また、カプセル化を行いすぎると、クラスの柔軟性が損なわれる場合もあります。

Python:クラスのまとめ

パート1 クラスの定義

class Musician:
    # クラス変数: すべてのMusicianオブジェクトで共有
    genre = "Music"

    # 初期化メソッド: インスタンスが生成されるときに自動的に呼び出される
    def __init__(self, name, instrument):
        # インスタンス変数: 個々のMusicianオブジェクトごとに異なる
        self.name = name
        self.instrument = instrument

    # メソッド: クラスに属する関数
    def play(self):
        return f"{self.name} is playing the {self.instrument}."

Musicianクラスを定義。このクラスは、名前(name)と楽器(instrument)という2つのインスタンス変数を持ち、音楽を演奏するメソッド(play)を持つとします。

パート2 インスタンス化

# Musicianクラスのインスタンスを作成
john = Musician("John Lennon", "guitar")
paul = Musician("Paul McCartney", "bass")

パート3 インスタンスの属性の参照

インスタンスの属性を参照するには、インスタンス名の後に.(ドット)をつけて属性名を記述します。

print(john.name)  # "John Lennon"
print(paul.instrument)  # "bass"

パート4 メソッドの呼び出し

メソッドを呼び出すにも同様に、インスタンス名の後に.(ドット)をつけてメソッド名を記述します。

print(john.play())  # "John Lennon is playing the guitar."
print(paul.play())  # "Paul McCartney is playing the bass."

始めてPythonを勉強するのは結構難しいですよね。

でもその悩みを抱えているのは一人じゃありません。全てのPython使いが同じ道を進んできました。

Pythonをはじめとするプログラミングスキルを武器に、時間と場所に捉われない自由な生き方を目指してみませんか?今すぐ行動したい方は以下の記事をチェック!

読者料典 Python入門:学習カリキュラム ←こちらから!

このWebサイトは現役のエンジニアが以下3点を目的として運営しています。

  1. 勉強:一度理解した内容を忘れないように。
    → アウトプットは「最強のインプット」である! 
  2. 備忘:忘れたとしても後から見返せるように。
    → 未来の自分への「お手紙」を書いています。 
  3. 共有:〇〇ってこうだったんだ!の感動をシェアできるように。
    → あなたの知識は誰かにとっての「価値ある情報」です。 

副業ブログの始め方はこちらから

スポンサーリンク
Python
シェアする
ビズドットオンラインをフォローする
タイトルとURLをコピーしました