Pythonのオブジェクト指向プログラミング - 継承と派生

Pythonのオブジェクト指向プログラミング - 継承と派生

まず、初期の継承しました

1.継承されている何

継承は、クラスとクラスの間の関係を指し、それは一種である什么“是”什么関係の、後継機能の一つは、コードの再利用の問題を解決するために使用されます。

継承は、新しいクラスを作成する方法ですが、Pythonで、新しいクラスは、1つまたは複数の親クラス、親を継承することができますし、基本クラスまたはスーパークラスになることができ、新しいクラスを派生クラスまたはサブクラスと呼ばれています

単一および多重継承:2は、Pythonのクラスの継承は、に分割されています

class ParentClass1: #定义父类
    pass

class ParentClass2: #定义父类
    pass

class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
    pass

class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
    pass

3、継承を表示

>>> SubClass1.__bases__ #__base__只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类
(<class '__main__.ParentClass1'>,)
>>> SubClass2.__bases__
(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)

4、クラシックと新しいスタイルのクラス

1.只有在python2中才分新式类和经典类,python3中统一都是新式类
2.在python2中,没有显式的继承object类的类,以及该类的子类,都是经典类
3.在python2中,显式地声明继承object的类,以及该类的子类,都是新式类
4.在python3中,无论是否继承object,都默认继承object,即python3中所有类均为新式类

注意:あなたは、基本クラスを指定しない場合は、Pythonのクラスは、デフォルトのオブジェクトクラスを継承する、オブジェクトクラスは、(のようないくつかの一般的な方法を提供し、すべてのpython、の基本クラスです__str__実装)。

>>> ParentClass1.__bases__
(<class 'object'>,)
>>> ParentClass2.__bases__
(<class 'object'>,)

第二に、継承と抽象的(遺伝再前抽象)

抽象即ち、抽出等の部品がより似ています。

要約は、次の2つのレベルに分かれています。

1、多分より多くの部分を抽出カテゴリにオブジェクトのようなオバマとマッセイ。

図2に示すように、親クラスへのヒト、ブタ、イヌ三つのクラス比較画像抽出部。

抽象最も重要な役割は、(あなたは、懸念を分離する複雑さを軽減することができます)のカテゴリに分かれて

継承:プログラミング言語は確かに継承の仕方によって抽象的構造を表現するために、抽象化のプロセスを受ける前に、それを実装するために、抽象的な結果に基づいています。

ただ、抽象プロセスの分析と設計、アクションやスキル、あなたは抽象クラスを介して取得することができます。

第三に、継承と再利用性

私たちはクラスAを定義した場合、プロセスの開発プロセスでは、あなたは別の新しいクラスBを構築したいのですが、同じクラスAとクラスBのほとんどは、我々は、クラスBを書くためにゼロからスタートすることはできません私たちは、クラスの継承の概念を使用します。

新しい継承クラスBとして、BはA、コードの再利用のため、B意志「遺伝」すべての属性(データ属性および機能属性)を継承することになります。

class Hero:
    def __init__(self,nickname,aggressivity,life_value):
        self.nickname=nickname
        self.aggressivity=aggressivity
        self.life_value=life_value

    def move_forward(self):
        print('%s move forward' %self.nickname)

    def move_backward(self):
        print('%s move backward' %self.nickname)

    def move_left(self):
        print('%s move forward' %self.nickname)

    def move_right(self):
        print('%s move forward' %self.nickname)

    def attack(self,enemy):
        enemy.life_value-=self.aggressivity
class Garen(Hero):
    pass

class Riven(Hero):
    pass

g1=Garen('草丛伦',100,300)
r1=Riven('锐雯雯',57,200)

print(g1.life_value) #结果:300
r1.attack(g1)
print(g1.life_value) #结果:243

注意:クラスはすでにので、すでに大部分設定のソフトウェアを持って再利用し、新しいクラスを確立している、プログラミングの労力を節約し、多くの場合、ソフトウェアの再利用は、独自のクラスを再利用することができないだけと言われて他の人もそう大幅に大規模なソフトウェア開発のソフトウェア開発サイクルを削減して、そのような新しいデータ型をカスタマイズするための標準ライブラリとして、継承された非常に重要であることができます。

第四に、見つけるために、プロパティを見て

リファレンスのようなプロパティg1.life_valueと同じように、あなたがして見つけるために、クラスに移動し、親クラスの最上部まで...親クラスを探しに行くlife_value例を探し始めます。それでは、どのように、次の印刷結果を説明していますか?

class Foo:
    def f1(self):
        print('Foo.f1')

    def f2(self):
        print('Foo.f2')
        self.f1()

class Bar(Foo):
    def f1(self):
        print('Bar.f1')


b=Bar()
b.f2()

# 打印结果:
# Foo.f2
# Bar.f1

第五に、派生

もちろん、あなたはまた、新しいプロパティの独自のサブクラスを追加したり、ここにあなた自身でこれらの属性を再定義することができますことに注意することは、もう一度自分の属性と親クラスと同じ名前を定義し、(親には影響しません)、その後、新しい呼び出しときに、プロパティ、対象自身について。

class Riven(Hero):
    camp='Noxus'
    def attack(self,enemy): #在自己这里定义新的attack,不再使用父类的attack,且不会影响父类
        print('from riven')
    def fly(self): #在自己这里定义新的
        print('%s is flying' %self.nickname)

サブクラスでその機能、すなわち、通常の関数を呼び出すために使用する必要があり、親クラス関数に同じ名前を再利用する必要があるかもしれない関数内に同じ名前の、新しい機能属性、編集機能:クラス名.func ()は、この時間は、それはそうであっても自己引数が値によって渡される必要があり、通常の関数呼び出しと違いはありません。

class Riven(Hero):
    camp='Noxus'
    def __init__(self,nickname,aggressivity,life_value,skin):
        Hero.__init__(self,nickname,aggressivity,life_value) #调用父类功能
        self.skin=skin #新属性
    def attack(self,enemy): #在自己这里定义新的attack,不再使用父类的attack,且不会影响父类
        Hero.attack(self,enemy) #调用功能
        print('from riven')
    def fly(self): #在自己这里定义新的
        print('%s is flying' %self.nickname)

r1=Riven('锐雯雯',57,200,'比基尼')
r1.fly()
print(r1.skin)

'''
运行结果
锐雯雯 is flying
比基尼
'''

第六に、実現と継承の原則

最終的にはPythonはPythonの会計処理方法解決順序(MRO)のリストを計算し、ユーザーが定義した各クラスのために、継承を実現する方法である、MROのリストは、例えば、基底クラスのすべての線状配列の単純なリストです

>>> F.mro() #等同于F.__mro__
[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, 
<class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

それは、このプロパティクラスの最初の一致が見つかるまで、継承を実現するためには、PythonはMROの基本クラスリストの左から右に見て開始します。このリストは、MROは、線形アルゴリズムC3によって達成されて構成されています。私たちは、このアルゴリズムの数学的な原則に行っていない、それは実際には、すべての親クラスのMROマージのリストであり、次の三つの基準に従ってください。

1は、親クラスが最初にチェックされますサブクラス化。

2、親クラスの複数のリスト内の順序に従ってチェックされます。

3、最初の親を選択し、次のクラスには2つの法的な選択肢がある場合。

のみをJavaとC#の中性子クラスの親クラスを継承し、Pythonの中性子クラスは、同時に複数の親クラスを継承することができ、複数の親クラスを継承場合は、[プロパティ]を見つけるには二つの方法、すなわちあります:深さ優先とは幅優先。

サンプルコード:

class A(object):
    def test(self):
        print('from A')

class B(A):
    def test(self):
        print('from B')

class C(A):
    def test(self):
        print('from C')

class D(B):
    def test(self):
        print('from D')

class E(C):
    def test(self):
        print('from E')

class F(D,E):
    # def test(self):
    #     print('from F')
    pass
f1=F()
f1.test()
print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性

#新式类继承顺序:F->D->B->E->C->A
#经典类继承顺序:F->D->B->A->E->C
#python3中统一都是新式类
#pyhon2中才分新式类与经典类

七、サブクラスで親クラスのメソッドを呼び出します

サブクラスを導出する新しい方法では、多くの場合、我々は2つの方法があり、親クラスのメソッドを再利用する必要があります

方法:名前、すなわち、親プロセスの親クラス名()。

class Vehicle: #定义交通工具类
     Country='China'
     def __init__(self,name,speed,load,power):
         self.name=name
         self.speed=speed
         self.load=load
         self.power=power

     def run(self):
         print('开动啦...')

class Subway(Vehicle): #地铁
    def __init__(self,name,speed,load,power,line):
        Vehicle.__init__(self,name,speed,load,power)
        self.line=line

    def run(self):
        print('地铁%s号线欢迎您' %self.line)
        Vehicle.run(self)  # 指名道姓的调用

line13=Subway('中国地铁','180m/s','1000人/箱','电',13)
line13.run()

第二の方法:スーパー()

class Vehicle: #定义交通工具类
     Country='China'
     def __init__(self,name,speed,load,power):
         self.name=name
         self.speed=speed
         self.load=load
         self.power=power

     def run(self):
         print('开动啦...')

class Subway(Vehicle): #地铁
    def __init__(self,name,speed,load,power,line):
        #super(Subway,self) 就相当于实例本身 在python3中super()等同于super(Subway,self)
        super().__init__(name,speed,load,power)
        self.line=line

    def run(self):
        print('地铁%s号线欢迎您' %self.line)
        super(Subway,self).run()

class Mobike(Vehicle):#摩拜单车
    pass

line13=Subway('中国地铁','180m/s','1000人/箱','电',13)
line13.run()

これらの2つの方法の違いは以下のとおりです。まず、道の継承とは何の関係もあり、方法2つのスーパーは()承継に依存している、とは直接の継承が存在しない場合でも、スーパーはMROに従って将来を探していきます。

#A没有继承B,但是A内super会基于C.mro()继续往后找
class A:
    def test(self):
        super().test()
class B:
    def test(self):
        print('from B')
class C(A,B):
    pass

c=C()
c.test() #打印结果:from B


print(C.mro())
#[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]

おすすめ

転載: www.cnblogs.com/Kwan-C/p/11535187.html