クラスはオブジェクト指向プログラミングの柱です。OOPは、コードの編成、再利用性、およびカプセル化に深く関わっています。
まず、免責事項:OOPは、 、Pythonでよく使用される別のパラダイムである関数型プログラミングです。Python(または確かにほとんどの言語)でプログラミングするすべての人がOOPを使用するわけではありません。Java 8では、オブジェクト指向ではない多くのことができます。OOPを使用したくない場合は、使用しないでください。二度と使用しないデータを処理するための1回限りのスクリプトを作成しているだけの場合は、現在の方法を続けてください。
ただし、OOPを使用する理由はたくさんあります。
いくつかの理由:
組織:OOPは、データとプロシージャの両方をコードで記述および定義する、よく知られた標準的な方法を定義します。データとプロシージャの両方を(異なるクラスの)定義のさまざまなレベルで格納でき、これらの定義について話す標準的な方法があります。つまり、OOPを標準的な方法で使用すると、後で自分や他の人がコードを理解、編集、使用するのに役立ちます。また、複雑な任意のデータストレージメカニズム(dictのdictまたはリスト、dictのセットまたはdictのセットのリストなど)を使用する代わりに、データ構造の一部に名前を付けて、それらを簡単に参照できます。
状態:OOPは、状態を定義して追跡するのに役立ちます。たとえば、古典的な例では、学生を処理するプログラム(たとえば、学年プログラム)を作成している場合、それらについて必要なすべての情報(名前、年齢、性別、学年、コース、成績、教師、仲間、食事療法、特別なニーズなど)。このデータは、オブジェクトが生きている限り保持され、簡単にアクセスできます。
カプセル化:カプセル化では、手順とデータが一緒に保存されます。メソッド(関数のOOP用語)は、メソッドが操作および生成するデータと一緒に定義されます。アクセス制御を可能にする Javaなどの言語、またはPythonでは、パブリックAPIの記述方法に応じて、メソッドとデータをユーザーから隠すことができます。つまり、コードを変更する必要がある場合、またはコードを変更したい場合は、コードの実装に対して何でも実行できますが、パブリックAPIは同じままにします。
継承:継承を使用すると、データとプロシージャを1つの場所(1つのクラス)で定義し、後でその機能をオーバーライドまたは拡張できます。たとえば、Pythonでは、dict
機能を追加するためにクラスのサブクラスを作成する人がよくいます。一般的な変更は、存在しない辞書からキーが要求されたときに例外をスローするメソッドをオーバーライドして、不明なキーに基づくデフォルト値を提供することです。これにより、自分のコードを今すぐまたは後で拡張したり、他の人が自分のコードを拡張したり、他の人のコードを拡張したりできるようになります。
再利用性:これらすべての理由およびその他の理由により、コードの再利用性が向上します。オブジェクト指向のコードを使用すると、確実な(テスト済みの)コードを1回記述してから、繰り返し再利用できます。特定のユースケースに合わせて何かを調整する必要がある場合は、既存のクラスから継承して、既存の動作を上書きできます。何かを変更する必要がある場合は、既存のパブリックメソッドシグネチャを維持しながらすべてを変更できます。
繰り返しますが、OOPを使用しない理由はいくつかありますが、使用する必要はありません。しかし、幸運なことに、Pythonのような言語では、少しでも多くでも使用できます。
学生の使用例(コードの品質は保証されず、例にすぎません):
オブジェクト指向
class Student(object):
def __init__(self, name, age, gender, level, grades=None):
self.name = name
self.age = age
self.gender = gender
self.level = level
self.grades = grades or {}
def setGrade(self, course, grade):
self.grades[course] = grade
def getGrade(self, course):
return self.grades[course]
def getGPA(self):
return sum(self.grades.values())/len(self.grades)
# Define some students
john = Student("John", 12, "male", 6, {"math":3.3})
jane = Student("Jane", 12, "female", 6, {"math":3.5})
# Now we can get to the grades easily
print(john.getGPA())
print(jane.getGPA())
標準辞書
def calculateGPA(gradeDict):
return sum(gradeDict.values())/len(gradeDict)
students = {}
# We can set the keys to variables so we might minimize typos
name, age, gender, level, grades = "name", "age", "gender", "level", "grades"
john, jane = "john", "jane"
math = "math"
students[john] = {}
students[john][age] = 12
students[john][gender] = "male"
students[john][level] = 6
students[john][grades] = {math:3.3}
students[jane] = {}
students[jane][age] = 12
students[jane][gender] = "female"
students[jane][level] = 6
students[jane][grades] = {math:3.5}
# At this point, we need to remember who the students are and where the grades are stored. Not a huge deal, but avoided by OOP.
print(calculateGPA(students[john][grades]))
print(calculateGPA(students[jane][grades]))