🚀 ニフティ’s Notion

クラスとインスタンス

👍
オブジェクト指向でよく出てくるワードを整理

目次

オブジェクト指向で出てくる用語

クラス
  • クラスとはオブジェクトの設計図にあたるもの。
  • クラスにはデータと振る舞いが定義される
      • Human(人クラス)が定義されている。
        • データとしてname(人の名前)を持つ。
        • say_nameというメソッドを定義し、人の名前を画面に出力するようにしている
      class Human:
      	def __init__(self, name): # インスタンス化する際の初期処理(コンストラクタ)
      		self.name = name # データ
      	
      	def say_name(self): # 振る舞い(メソッド)
      		print(self.name)
  • 抽象データ型の一つ
    • データ型とそのデータ型に対する
インスタンス
  • クラス定義に基づいてメモリ上に領域が確保され、クラスを実体化したもの。
  • 生成されたデータの集合体を「インスタンス」と呼ぶ。
属性
  • インスタンスは、固有の姿・形・性質などを持っており、このようなインスタンスの状態を属性(attribute)として表現する。
    • 人間で例えると「名前」「身長」「体重」などがそれにあたる。
メソッド
  • オブジェクトが持っている処理・ふるまいのこと。
    • そのオブジェクトに関する操作
  • 人間で例えると「話す」「歩く」などがそれにあたる。

クラスとインスタンスとオブジェクトの違い
  • クラス
    • データとメソッド(手続)を定義したもの
    • インスタンスの設計図
    • インスタンスが持つことができる性質を規定
    • コード上でクラスを定義する(=静的)
      • あくまでも設計図のため、実行時にクラスそのものをいじることはない
    • 可能なデータ構造の集合を示している
  • インスタンス
    • クラスを実体化したもの
    • 実行時に、クラスを元にメモリに展開され使用される(=動的)
    • クラスとインスタンスは1対多の関係
      • 異なる属性値を持つ実体を複数作ることができる
      • クラスによって定義された可能なデータ構造の集合の要素の一つを示している
  • オブジェクト
    • 実体の総称
    • クラスだけでなく、整数、実数にも適用
    • オブジェクト指向では、インスタンスと同じ意味で使われることもあるが、オブジェクトはインスタンスをより抽象的にした用語

クラスを作る上で大事なポイント

  • クラス単体で正常に動作するように設計する
    • クラスが自分自身を守る
  • 自分自身を守るためには?
    • インスタンス変数を守る、つまりデータが不正な状態に陥らないようにする
  • インスタンス変数を守るためには?
    • クラス内に入力値をバリデーションする仕組みを導入し、インスタンス変数に不正なデータが混入しないようにする
    • メソッド内部でインスタンス変数を変更する場合も、不正なデータを扱わないようにする
  • クラスは単なるデータの入れ物ではない
    • メソッドを使って内部状態を防御する

その他

プロパティ
  • メソッドを変数のように使えるようにしたもの。代入はできないので、安全。
    • データを返すものはgetterと呼ばれる
    • 代入したい場合は別途setterを使う。
  • 注意点
    • むやみにgetter/setterを作らない方が良い
      • 特にsetter
        • オブジェクトは単なるデータの入れ物ではない
          • getter/setterを作るとオブジェクトが単なるデータの入れ物になりがち
        • メソッドを通じてオブジェクトに処理を任せられないか検討する
    • クラスの利用者からすると気軽に使える印象を受けるので、あまり重い処理をプロパティに書き込まない方が良い。
import math


class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    @property
    def distance(self):
        return math.sqrt(self.x * self.x + self.y * self.y)
p = Point(1,2)
print(p.distance) # p.distance()ではない
クラスメソッド・インスタンスメソッド
  • インスタンスメソッド:インスタンス化しないと使えないメソッド
    • インスタンス変数(=self.~~によって参照される変数)を必要とするときはこちらを選ぶ
  • クラスメソッド:インスタンス化しなくとも使えるメソッドのこと
    • クラス変数(クラス直下に宣言されている変数)だけを参照するときにはこちらを選ぶ
class Human:
    __kind = "mammal"

    @classmethod
    def kind(cls):
        return __kind

    def __init__(self):
        self.__name = "uehara"  # データ

    def say_name(self):  # 振る舞い(メソッド)
        print(self.__name)


Human.kind()  # インスタンス化しなくても呼び出せる
Human.say_name()  # 呼び出せない
h = Human()
h.say_name() # 呼び出せる