分かったようで、分からない。でも分かった気分のままで放置されている、「クラス」。
オブジェクト指向プログラミングにおけるクラスとは一体どんなものなのか、Pythonで考えてみます。
「クラスが理解できない…私にはプログラミングのセンスがないのか」
初めはそう思っていました。しかしそれはもう過去の話。
昔の私に読んでもらいたいクラスの記事を書いてみます。
クラスは、変数と関数をまとめたもの
Pythonに限らず、オブジェクト指向プログラミング言語において、クラスは変数と関数をまとめた鋳型です。
本記事では、Person(人間)というクラスを作って解説してみます。
class Person(): #クラスの定義
def __init__(self, name): #コンストラクタの定義
self.name = name #引数をname属性に格納
def reverse(self, message): #名前を逆さまにするメソッドの定義
print(self.name[::-1]) #name属性に格納された名前を逆にする
print(message) #メソッドに渡された引数を表示
上のコードがクラスの定義です。クラスは鋳型なので、実際に使う場合はインスタンス化する必要があります。
インスタンス化とは
インスタンス化とは、クラスからオブジェクトを作ることです。例えば、先のコードをインスタンス化するには次にようにコードを記述します。
my_name = Person('Suzuki') #インスタンス化
ここで、my_nameのことをオブジェクト(物)と言います。
クラスという鋳型をもとに、オブジェクトという物が作られたということです。このように、オブジェクトを作ることをインスタンス化と言います。
- クラスとは、オブジェクトを作るための鋳型であり、変数と関数をまとめて持っている
- インスタンス化とは、クラスという鋳型をもとにオブジェクトを作ること
- オブジェクトとは、クラスをもとに作られた定数(変数)のこと
- インスタンスとはオブジェクトの別名
クラスの中身
クラスの中身を考える前に、インスタンス化したmy_nameというオブジェクトの挙動をみてみましょう。
class Person(): #クラスの定義
def __init__(self, name): #コンストラクタの定義
self.name = name #引数をname属性に格納
def reverse(self, message): #名前を逆さまにするメソッドの定義
print(self.name[::-1]) #name属性に格納された名前を逆にする
print(message) #メソッドに渡された引数を表示
my_name = Person('Suzuki') #インスタンス化
my_name.name #オブジェクトから属性地にアクセス
#出力→Suzuki
my_name.reverse('逆ですね') #オブジェクトからメソッドにアクセス
#出力→ikuzuS
# 逆ですね
メソッドと属性
クラスとは、関数と変数を同時に持っている物であると説明しました。クラスの中の関数をメソッドと言い、変数を属性と言います。
例のコードでは次の二つがメソッドです。
def __init__(self, name):
def reverse(self, message):
そして、次のコードが属性です。
self.name = name
メソッドを使ったり、属性にアクセスしたりするには、オブジェクトにドットで区切ってメソッド(属性)名を続けます。
my_name = Person('Suzuki') #インスタンス化
my_name.name #属性へアクセス
#出力:Suzuki
my_name.reverse('逆ですね') #メソッドへアクセス
#出力;ikuzuS
# 逆ですね
__init__()は初期化メソッド(コンストラクター)
メソッドとは、オブジェクトの中で使われる関数のことです。
__init__()はインスタンス化された時に実行される特殊関数です。一番初めに処理されるので「初期化メソッド」と呼ばれます。あるいはコンストラクター(建設の意味)とも呼ばれます。
先のコードの場合は、self.nameに、’Suzuki’という文字列を格納しています。
class Person(): #クラスの定義
def __init__(self, name): #コンストラクタの定義
self.name = name #引数をname属性に格納
my_name = Person('Suzuki') #インスタンス化
my_name.name #出力:'Suzuki'
selfとは、オブジェクト自身
selfとは英語で’自分自身’という意味ですが、この場合、オブジェクト自身という意味になります。
Pythonの場合、メソッドの第一引数には必ずオブジェクト自身が渡されます。なので、第一引数は必ずselfとする、というルールがあります。
別にselfではなくてもプログラムは動きますが、コードを書く人、読む人が分かりやすくするためにそのようなルールがあります。
my_name = Person('Suzuki')
と、インスタンス化するとmy_nameがオブジェクト自身ということになります。
引数のお話
インスタンス化するときに渡される引数は、全て__init__()関数が処理します。
本記事では’Suzuki’を、インスタンス化した時の引数として渡しています。それを、__init__()関数が、name属性に定義してるのです。
メソッドに引数を渡す場合は、次のようにすれば良いです。
class Person(): #クラスの定義
def __init__(self, name): #コンストラクタの定義
self.name = name #引数をname属性に格納
def reverse(self, message): #名前を逆さまにするメソッドの定義
print(self.name[::-1]) #name属性に格納された名前を逆にする
print(message) #メソッドに渡された引数を表示
my_name = Person('Suzuki') #インスタンス化
my_name.reverse('逆ですね') #メソッドに引数を渡す
#出力:ikuzuS
# 逆ですね
自分で定義したクラス内の関数である、reverse()メソッドのmessageとして、’逆ですね’という文字列が処理されます。
self.name[::-1]は、name属性の文字列をひっくり返す処理をしているだけです。
- クラスの中の関数をメソッドと言い、変数を属性という
- 属性やメソッドにアクセスするためには、オブジェクトにドットをつけてアクセスする
- __init__()は初期化メソッドといい、インスタンス化された時に実行される
- selfとはオブジェクト自身であり、必ずクラスの中のメソッドの第一引数として渡される
- インスタンス化の時に渡した引数は__init__()が処理する
まとめ
クラスのイメージが掴めたでしょうか?
ただの関数であれば、実行された時に値を1つだけ返すだけです。
複雑な処理をしたくなったら、多くの関数をごちゃごちゃと書かなければならないかもしれません。
しかし、クラスを用いれば、関数や変数を何個でもまとめることができるので、コードを綺麗に整理できて、再利用もしやすいものとなります。
また、他の人が機能を使いたい時に、大変使いやすいものとなります。