はじめに
今回はオブジェクト指向プログラミングでは必ずと言っていいほど出てくる「クラス(class)」の文法について解説していきます。もちろんKrita以外のPython3でも全く同じ文法です。
クラスは簡単に言えば飛行機などの「設計図」です(図1)。設計図をもとに作った本物の飛行機が「インスタンス(実体)」に当たります。飛行機のプロペラを回すなどの操作が「メソッド」に当たり、飛行機のスピードなどの状態が「プロパティ」に当たります。
図1:クラスは設計図
クラスについて
クラスは機能を1つにまとめる働きをします。クラスに属する「関数」を「メソッド」と言い、クラスに属する「変数」を「プロパティ」と言い、どちらも何個でも持つことができます。クラス内のメソッド内にあってクラスに属する変数は「self.変数名」と書きますが、メソッド内にあってクラスに属さない変数はそのまま「変数名」で書きます(図2)。
図2:クラスの文法
最小限のクラス
クラスのインスタンスを生成するには「変数 = クラス名()」と書くとインスタンスを生成する際に初期化メソッド「__init__」が呼ばれ、インスタンスが変数に代入されます。
・サンプルスクリプト「class_init.py」
【サンプルスクリプトの解説】
MyClassクラスのインスタンスを生成し、ターミナルに"初期化"を表示してインスタンスを「ins」変数に代入します。
クラスのプロパティ
クラスのプロパティはクラス内のメソッド外では「変数名」のみで、メソッド内では「self.変数名」で、クラス外では「インスタンス.変数名」でアクセスできます。ここではクラス内のメソッド外で変数に値を代入して初期化していますが、そうしなくても最初にメソッド内で「self.変数名 = 値」を書いた時点でも初期化できます。
・サンプルスクリプト「class_property.py」
4 | print("初期化:"+self.strings) |
【サンプルスクリプトの解説】
「MyClass」クラスのインスタンスを生成し、ターミナルに"初期化:文字列プロパティ"を表示してインスタンスを「ins」変数に代入します。
ターミナルに"文字列プロパティ"を表示します。
クラスのメソッド
初期化メソッド以外にも任意のメソッドを作ることができます。メソッドはクラス内で「def メソッド名(self,引数,…)」というように書き「関数」とほとんど同じです。関数と1つ違うのは第1引数に「self」がくることです。これでクラス内のメソッドやプロパティにアクセスできます。
また「__init__」メソッドでも引数を持つことができますし、他のメソッドでself引数のみにすることもできます。
・サンプルスクリプト「class_def.py」
5 | def printSpeed(self,s): |
6 | print(s+str(self.speed)) |
【サンプルスクリプトの解説】MyClassクラスのインスタンスを生成し、インスタンスを「ins」変数に代入します。
MyClassクラスの「printSpeed」メソッドを呼び出してターミナルに"スピードは100"を表示します。
クラスの継承
クラスを「継承(派生させるとも言う)」することで、他のクラスのメソッドとプロパティを内包することもできます。例えばClassAクラスとClassBクラスがあり、ClassBクラスがClassAクラスを継承すればClassBクラスの中でClassAクラスのメソッドとプロパティを使いまわすことができます。具体的にはサンプルスクリプトを見ればすぐに分かるでしょう。
このサンプルスクリプトでClassBクラスの__init__メソッドで親クラスの「super」を呼び出していますが、これはClassBクラスの__init__メソッドでClassAクラスの__init__メソッドが上書きされたので、superを使って実行されなかったClassAクラスの__init__メソッドを呼び出しています。
・サンプルスクリプト「class_derive.py」
05 | def printSpeed(self,s): |
06 | print(s+str(self.speed)) |
13 | def printSize(self,s): |
14 | print(s+str(self.size)) |
17 | ins.printSpeed("スピードは") |
【サンプルスクリプトの解説】
「class ClassB(ClassA)」と書いて、ClassBクラスはClassAを継承します。
「ClassB」クラスのインスタンスを生成し、インスタンスを「ins」変数に代入します。
「ClassA」クラスの「printSpeed」メソッドを呼び出してターミナルに"スピードは100"を表示します。
「ClassB」クラスの「printSize」メソッドを呼び出してターミナルに"サイズは75"を表示します。
クラスメソッド
「クラスメソッド」はクラスのメソッドの前に「@classmethod」を書きます。クラスメソッド名の第1引数に「cls」を書いて「cls」を使えばクラス内のインスタンスも生成できます。クラスメソッドはインスタンスを生成しなくても呼べるクラスのメソッドです。「クラス名.クラスメソッド名()」と書きます。
・サンプルスクリプト「class_method.py」
10 | MyClass.printStr("文字列") |
【サンプルスクリプトの解説】
MyClassクラスのクラスメソッド「printStr」を呼び出してターミナルに"クラスメソッド:文字列"を表示し、「cls(s)」でMyClassクラスのインスタンスを生成してターミナルに"メソッド:文字列"を表示します。
スタティックメソッド
「スタティックメソッド」はクラスのメソッドの前に「@staticmethod」を書きます。クラスメソッドと異なりスタティックメソッド名の第1引数に「cls」は書きません。スタティックメソッドはインスタンスを生成しなくても呼べるクラスのメソッドです。「クラス名.スタティックメソッド名()」と書きます。
・サンプルスクリプト「class_static.py」
07 | return "スタティックメソッド:"+s |
09 | variable = MyClass.printStr("文字列") |
【サンプルスクリプトの解説】
MyClassのスタティックメソッド「printStr」を呼び出し、戻り値として"スタティックメソッド:文字列"を「variable」変数に代入し、その文字列をターミナルに表示します。
おわりに
今回はプログラミングする上で避けては通れない、より高度な仕組みであるクラスの文法について解説しました。次回以降はクラスを使ってKritaでお絵描きしていきます。