www.56.net必嬴亚洲:Python面向对象,面向对象之继

作者:计算机知识

一、什么是承接

面向对象之多种承接

面向对象之继续和多态

三番五次 子类承袭父类全体机能

class Animal(object):
    def run(self):
        print('animal is running...')
# 创建Animal实例
animal = Animal()
animal.run()

# Dog类
class Dog(Animal):
    pass

# 创建Dog 实例

dog = Dog()

# 调用Dog类继承来自于Animal类的run方法
dog.run() 

近期自家有這样二个须求 正是分裂子类承继父类调用run(),输出不相同的音讯,那么大家就必要在子类里边重新定义该方法来掩盖父类中的方法,這叫做多态

# Cat类 继承 Animal
class Cat(Animal):
    def run(self):
        print('cat is running...')

cat = Cat()
cat.run()

class Monkey(Animal):
    def run(self):
        print('Monkey is running...')
monkey = Monkey()
monkey.run()
# 现在输出了不同信息,但是每次都要写這么多,感觉多态也挺麻烦的,那我们再优化下:

print('-------------------------------------')
def _run(animal):
    animal.run()
    animal.run()

_run(Dog())
_run(Cat())
_run(Monkey())

# 這样就体现出多态的好处了 
# 我们也可以还派生出一些类来, 比如:
class Tortoise(Animal):
    def run(self):
        print('Tortoise is running slowly...')
_run(Tortoise())

静态语言Java和动态语言Python的界别:
对于静态语言(比如Java)来讲,借使急需传入Animal类型,则传出的对象必须是Animal类型只怕它的子类,不然,将不大概调用run()方法
www.56.net必嬴亚洲:Python面向对象,面向对象之继承和多态。对此Python那样的动态语言来讲,则不必然必要传入Animal类型。我们只需求保障传入的目的有3个run()方法就足以了:
这便是动态语言的“鸭子类型”,它并不供给严厉的接轨种类,二个指标只要“看起来像鸭子,走起路来像鸭子”,那它就能够被视作是鸭子。 评释:

print('--------------------------------------')

class Rabbit(object):
    def run(self):
        print('Rabbit is running...')

_run(Rabbit()) # Rabbit is running...

接二连三介绍

雄起雌伏指的是类与类之间的涉及,是一种怎么样是怎么样的关联,功效之1正是用来化解代码重用难题。
一连是1种成立新类的章程,在python中,新建的类可以接二连三一个或四个父类,父类又可称为基类或超类,新建的类称为派生类或子类

继续是一种创造类的法子,在python中,四个类能够一而再来自三个或四个父。原始类称为基类或超类。

常用算法 Mro

宪章一下事例的拓扑排序:首先找入度为0的点,唯有三个A,把A拿出去,把A相关的边剪掉,再找下三个入度为0的点,
有多个点(B,C),取最左原则,拿B,那是排序是AB,然后剪B相关的边,那时候入度为0的点有E和C,取最左。
此刻排序为ABE,接着剪E相关的边,那时唯有多少个点入度为0,那正是C,取C,顺序为ABEC。剪C的边得到五个入度为0的点(DF),取最左D,顺序为ABECD,
下一场剪D相关的边,那么下三个入度为0的就是F,然后是object。
这正是说最后的排序就为ABECDFobject。

class D():
    pass
class E():
    pass
class F():
    pass
class B(E,D):
    pass
class C(D,F):
    pass
class A(B,C):
    pass

class a():
    pass
class b():
    pass
class c():
    pass
class d(b, c):
    pass
class e(a, b):
    pass
class f(e, d):
    pass

if __name__ == '__main__':
    print(1)
    print(A.__mro__ ) # ABECDF->Object
    print(f.__mro__) # feadbc->Object  跟继承参数顺序有关 先左后右


# 随意乱写

class _A():
    pass
class _B(_A):
    pass
class _C(_B):
    pass
class _D(_B):
    pass
class _E(_C, _D):
    pass
class _F(_A):
    pass
class _G(_E, _F):
    pass

if __name__ == '__main__':
    print(_G.__mro__) # _G_E_C_D_B_F_A

关怀一波!喜欢一波!本身是前端菜鸟,正在做团结的个人博客邓鹏的博客,应接来沟通学习, 使用的技能 vue koa二 mysql php nginx!

小结

再而三可以把父类的保有机能都一贯拿过来,那样就不要重零做起,子类只须求新添本人故意的方法,也能够把父类不合乎的法子覆盖重写。

动态语言的野鸭类型特点决定了接二连三不像静态语言那样是必须的。

关心一波!喜欢一波!本身是前端菜鸟,正在做团结的私房博客邓鹏的博客,接待来沟通学习, 使用的本事 vue koa二 mysql php nginx!

python 中分为单承接和多承继

python中类能够一而再多少个类.

class ParentClass1: #定义父类
    pass

class ParentClass2: #定义父类
    pass

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

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

翻看承袭的类:

res=SubClass2.__bases__
print(res)
#__base__只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类

输出:
(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
#创建父类
class Parent1:
    pass

class Parent2:
    pass

# 继承父类,单继承
class Obj1(Parent1):
    pass

#继承父类,多继承
class Obj2(Parent1,Parent2):
    pass

美貌类和新型类

1.只有在python2中才分新式类和经文类,python三中联合都以新型类
二.在python第22中学,未有显式的继承object类的类,以及该类的子类,都以经典类
三.在python第22中学,显式地声称承袭object的类,以及该类的子类,都以风靡类
三.在python三中,无论是不是承继object,都暗许承继object,即python三中保有类均为新式类

唤醒:若是未有一点点名基类,python的类会暗许承袭object类,object是具有python类的基类,它提供了有的广大格局(如str)的实现。

res=ParentClass1.__bases__
print(res)
# 输出:
(<class 'object'>,)

在开垦顺序的进度中,要是大家定义了二个类A,然后又想新创造其余一个类B,不过类B的绝大很多剧情与类A的①致时

大家不容许从头开端写3个类B,这就用到了类的后续的概念。

通过接二连三的点子新建类B,让B继承A,B会‘遗传’A的全部属性(数据属性和函数属性),达成代码重用
在不借助承袭属性的景色下,子类在调用父类的属性时,能够一直通过函数调用的格局调用父类的品质:

class ParentClass: #定义父类
    def __init__(self,name,age):
        self.name=name
        self.age=age
class SubClass(ParentClass): 
    def __init__(self,name,age,hobby,title):
        ParentClass.__init__(self,name,age) # 直接以函数的方式调用父类的属性
        self.hobby=hobby
        self.title=title

obj=SubClass('tom',22,'reading','Student')
print(obj.__dict__)

只顾:类的天性引用,会先从实例中找,然后去类中找,然后再去父类中找...直到最拔尖的父类。

2、何时使用持续

组合

组成指的是,在3个类中以此外多少个类的目的作为数据属性,称为类的构成
组合与后续都以立竿见影地运用已有类的能源的第三方法。可是相互的概念和行使意况皆区别:

一.后续的措施

透过一连创建了派生类与基类之间的涉嫌,它是一种'是'的涉嫌,举个例子白马是马,人是动物。

当类之间有广吉安1的效劳,提取那些共同的遵循做成基类,用持续相比好,比如老师是人,学生是人

二.结缘的不二秘籍

用整合的法子确立了类与组合的类之间的涉及,它是1种‘有’的关联,举例教授有出生之日,教师教python和linux课程,教师有学员s一、s2、s3...

示例:

# coding=utf-8

class People:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex

class Course:
    def __init__(self,name,period,price):
        self.name=name
        self.period=period
        self.price=price
    def tell_info(self):
        print('%s %s %s' %(self.name,self.period,self.price))

class Teacher(People):
    def __init__(self,name,age,sex,job_title):
        People.__init__(self,name,age,sex)
        self.job_title=job_title
        self.course=[]
        self.students=[]


class Student(People):
    def __init__(self,name,age,sex):
        People.__init__(self,name,age,sex)
        self.course=[]


egon=Teacher('egon',18,'male','advance')
s1=Student('bob',18,'female')

python=Course('python','3mons',3000.0)
linux=Course('linux','3mons',3000.0)

#为老师egon和学生s1添加课程
egon.course.append(python)
egon.course.append(linux)
s1.course.append(python)

#为老师egon添加学生s1
egon.students.append(s1)


#使用
for obj in egon.course:
    obj.tell_info()
print(egon.__dict__)

出口结果:

python 3mons 3000.0
linux 3mons 3000.0
{'name': 'egon', 'age': 18, 'sex': 'male', 'job_title': 'advance', 'course': [<__main__.Course object at 0x000000410AF46CC0>, <__main__.Course object at 0x000000410AF46CF8>], 'students': [<__main__.Student object at 0x000000410AF46C88>]}

  在早就成立的多少个类中,这几哥类中的方法和变量有同1的,这种时候我们就足以接纳类的延续,将别的类中已有的艺术和变量通过持续的主意,在新创设的类中,使用正规的秘诀就能够调用父类中的方法。剩下本人特有的章程只要在团结类中定义就能够。

承袭达成的规律

一、承接顺序
* python 类可以承袭多少个类,java和C#中则只可以三番五次多少个类
* Python 的类尽管继续了多少个类,那么其找出父类的逐一有两种:深度优先广度优先
* 当类是精粹类时,多一连意况下,会根据深度优先的办法查找
* 当类是新型类时,多再三再四情形下,会根据广度优先的诀窍查找
推荐使用新式类,假如当前类依然父类承袭了object类,那么该类正是二个新式类,不然就是精湛类。(优异类之存在于python第22中学)

2、承接原理(python怎样完毕的继续)
python完成持续的规律是: 对于定义的每三个类,python都会揣摸出3个方式分析顺序(MRO)列表,那么些MRO列表就是三个简短的具有基类的线性顺序表。

class A:
    pass

class B(A):
    pass

class C:
    pass

class D(C,B):
    pass

obj=D()
print(D.mro())

# 输出列表:
[<class '__main__.D'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]

为了完结持续,python会在MRO列表上从左到右开首查找基类,直到找到第一个门户大致这几个特性的类结束。
而那几个MRO列表的构造是经过叁个C三线性化算法来兑现的。大家不去探究那些算法的数学原理,它事实上便是联合全数父类的MRO列表并遵守如下叁条规则:

  • 子类会先于父类被检查
  • 多少个父类会依照它们在列表中的顺序被检查
  • 举个例子对下一个类存在多个官方的选料,选用第三个父类

  举个列子:人都会吃,喝,玩,小明也是一位,所以小明也会,所以小明承袭了人的质量,特别的是小明还会背古诗,就依据以上的传教写二个类的接轨。

子类中调用父类的艺术

1、通过点名父类方法名的方法去调用。(不行使连续的特性)
二、通过应用super()

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)   # 调用父类的init方法.
        self.line=line

注意:
当你使用super()函数时,Python会在MRO列表上接轨搜寻下三个类。只要每个重定义的情势统一使用super()并只调用它贰回,那么调节流最终会遍历完全部MRO列表,每种方法也只会被调用三次(注意小心小心:使用super调用的兼具属性,都是从MRO列表当前的职位今后找,千万不要通过看代码去找承接关系,必须要看MRO列表)

class Man:

    def eat(self):
        print('吃')

    def drink(self):
        print('喝')

    def play(self):
        print('玩')


class XiaoMing(Man):

    def recite(self):
        print('背古诗')

xm = XiaoMing()
xm.eat()
xm.recite()


输出结果:
吃
背古诗

绑定方法与非绑定方法

类中的函数能够定义为两大类,壹种是绑定方法,另一种是非绑定方法。

一、绑定方法:绑定给什么人,什么人来调用就自动将它自个儿作为第多少个参数字传送入:
  - 绑定到类的措施:用classmethod装饰器装饰的艺术。
为类量身定制,自动将类当作第壹个参数字传送入。(其实对象也可调用,但仍将类当作第二个参数字传送入)
  - 绑定到指标的主意:未有被别的装饰器装饰的法门。、
为对象量身定制对象,自动将对象当作第多个参数字传送入(属于类的函数,类能够调用,不过必须比照函数的规则来,未有自动传值那么1说)

本文由bwin必赢发布,转载请注明来源

关键词: 随笔 Python