一、继承

Python⾯向对象的继承指的是多个类之间的所属关系,即⼦类默认继承⽗类的所有属性和⽅法

继承作用:继承可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

在Python中,所有类默认继承object类,object类是顶级类或基类;其他⼦类叫做派⽣类。

class Being:  # 定义一个类Beingdef __init__(self):  #初始化实例属性self.num = 1  #在类里面添加实例属性self.属性名=值def info_print(self):  # 定义一个实例方法print(self.num)  # 在类里面访问实例属性self.属性名class People(Being):  # 定义一个类People,继承Being类passp1 = People()  # 创建People类的一个对象p1
p1.info_print()  # 对象调用父类实例方法
p1.num  # 对象访问父类实例属性输出:1
class Being(object):def __init__(self):self.num = 1def info_print(self):print(self.num)class People(Being):passp1 = People()
p1.info_print()输出:1

二、单继承

单继承:一个子类继承一个父类

class Master:def __init__(self):self.kongfu = "古法配方"def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class prentice(Master):passdaqiu = prentice()
print(daqiu.kongfu)
daqiu.make_cake()输出:
古法配方
古法配方制作煎饼果子

二、多继承

多继承:一个子类同时继承多个⽗类
当⼀个类有多个父类的时候,默认使用第⼀个父类的同名属性和方法。

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class School:def __init__(self):self.kongfu = "学校技术"self.name = "新东方"def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class prentice(Master, School):passdaqiu = prentice()
print(daqiu.kongfu)  # 同名属性,访问第一个父类的同名属性
daqiu.make_cake()  # 同名方法,访问第一个父类的同名方法print(daqiu.age)  # 不同名属性,第一个父类正常
print(daqiu.name)  # 不同名属性,非第一个父类报错

输出:

三、子类重写父类同名方法和属性

⼦类和父类具有同名属性和方法,默认使用子类的同名属性和方法。

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class School:def __init__(self):self.kongfu = "学校技术"self.name = "新东方"def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class prentice(Master, School):def __init__(self):self.kongfu = "独创配方"def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))daqiu = prentice()
print(daqiu.kongfu)  # 同名属性,重写父类
daqiu.make_cake()  # 同名方法,重写父类
#如果子类和父类有同名属性和方法,子类创建对象调用属性和方法,调用的是子类里面的同名属性和方法# print(daqiu.age)  # 不同名属性,报错
print(daqiu.name)  # 不同名属性,报错

输出:

四、___mro___

Python的MRO即Method Resolution Order(方法解析顺序),即在调用方法时,会对当前类以及所有的基类进行一个搜索,以确定该方法之所在,而这个搜索的顺序就是MRO。

类名.__mro__,返回一个元组。

可以清晰地看到类的层级关系。

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class School(Master):def __init__(self):self.kongfu = "学校技术"self.name = "新东方"def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class prentice(School):def __init__(self):self.kongfu = "独创配方"def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))print(prentice.__mro__)
print(type(prentice.__mro__))
print(list(prentice.__mro__))输出:
(<class '__main__.prentice'>, <class '__main__.School'>, <class '__main__.Master'>, <class 'object'>)
<class 'tuple'>
[<class '__main__.prentice'>, <class '__main__.School'>, <class '__main__.Master'>, <class 'object'>]

五、子类调用父类的同名属性和方法

子类里如果有与父类同名的属性方法,调用这个属性方法,调用的是子类里面的,调用不到父类里面的属性方法。

如何实现同名属性方法,既能调用子类里面的,也能调用父类里面的呢?

  • 1.在子类里定义一个函数
  • 2.再次初始化父类属性(参数self)
  • 3.调用父类方法(参数self)
class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class School:def __init__(self):self.kongfu = "学校技术"self.name = "新东方"def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class prentice(Master, School):def __init__(self):self.kongfu = "独创配方"def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))def make_master_cake(self):  # 调用父类方法,为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化,类名.__init__(self)Master.__init__(self)Master.make_cake(self)def make_school_cake(self):School.__init__(self)School.make_cake(self)daqiu = prentice()
print(daqiu.kongfu)
daqiu.make_cake()
daqiu.make_master_cake()
daqiu.make_school_cake()print(prentice.__mro__)输出:
独创配方  # 返回的是子类属性
独创配方制作煎饼果子  # 调用的是子类方法
古法配方制作煎饼果子  # 调用到了父类Master的方法
学校技术制作煎饼果子  # 调用到了父类School的方法
(<class '__main__.prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>)
class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class School:def __init__(self):self.kongfu = "学校技术"self.name = "新东方"def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class prentice(Master, School):def __init__(self):self.kongfu = "独创配方"def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))def make_master_cake(self):  # 调用父类方法,为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化,类名.__init__(self)Master.__init__(self)Master.make_cake(self)def make_school_cake(self):School.__init__(self)School.make_cake(self)daqiu = prentice()
daqiu.make_master_cake()
daqiu.make_school_cake()
print(daqiu.kongfu)
daqiu.make_cake()
print(prentice.__mro__)输出:
古法配方制作煎饼果子
学校技术制作煎饼果子
学校技术  # 如果先调用了父类的属性和方法,父类属性会覆盖子类属性
学校技术制作煎饼果子  # 如果先调用了父类的属性和方法,父类属性会覆盖子类属性
(<class '__main__.prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>)

代码修正,

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class School:def __init__(self):self.kongfu = "学校技术"self.name = "新东方"def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class prentice(Master, School):def __init__(self):self.kongfu = "独创配方"def make_cake(self):self.__init__()  # 如果先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用子类方法前,先调用子类自己的初始化print("{}制作煎饼果子".format(self.kongfu))def make_master_cake(self):  # 调用父类同名属性方法,为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化,类名.__init__(self)Master.__init__(self)  # 父类类名.__init__(self),父类初始化调用一次,注意不要漏写selfMaster.make_cake(self)  # 父类类名.函数(self), 父类方法调用一次,注意不要漏写selfdef make_school_cake(self):School.__init__(self)School.make_cake(self)daqiu = prentice()
daqiu.make_master_cake()
daqiu.make_school_cake()
print(daqiu.kongfu)
daqiu.make_cake()输出:
古法配方制作煎饼果子
学校技术制作煎饼果子
学校技术  # 因为先调用父类,这里子类同名属性仍然被父类属性覆盖
独创配方制作煎饼果子

六、多层继承


多层继承:大于两层的继承

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class School:def __init__(self):self.kongfu = "学校技术"self.name = "新东方"def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class prentice(Master, School):def __init__(self):self.kongfu = "独创配方"def make_cake(self):self.__init__()  # 如果先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用子类方法前,先调用子类自己的初始化print("{}制作煎饼果子".format(self.kongfu))def make_master_cake(self):  # 调用父类同名属性方法,为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化,类名.__init__(self)Master.__init__(self)  # 父类初始化调用一次,注意不要漏写selfMaster.make_cake(self)  # 父类方法调用一次,注意不要漏写selfdef make_school_cake(self):School.__init__(self)School.make_cake(self)class TuShun(prentice):passxiaoqiu = TuShun()  # 说明子类可以继承父类所有属性和方法
xiaoqiu.make_cake()  # 调用父类prentice方法
xiaoqiu.make_master_cake()  # 调用父类prentice的父类方法
xiaoqiu.make_school_cake()  # 调用父类prentice的父类方法
print(xiaoqiu.make_cake)  # 前一步调用父类prentice的父类school类,school类初始化后,属性是school类的属性输出:
独创配方制作煎饼果子
古法配方制作煎饼果子
学校技术制作煎饼果子
print(TuShun.__mro__)输出:
(<class '__main__.TuShun'>, <class '__main__.prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>)

七、super()调用父类方法

方法一:在子类里定义一个函数,在里面初始化父类属性、调用父类方法
⽅法⼀特点:代码冗余;⽗类类名如果变化,这⾥代码需要频繁修改。如果有多个父类,代码量重复增加。

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class School(Master):def __init__(self):self.kongfu = "学校技术"self.name = "新东方"def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class prentice(School):def __init__(self):self.kongfu = "独创配方"def make_cake(self):self.__init__()  # 如果先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用子类方法前,先调用子类自己的初始化print("{}制作煎饼果子".format(self.kongfu))# def make_master_cake(self):  # 调用父类同名属性方法,为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化,类名.__init__(self)#     Master.__init__(self)  # 父类初始化调用一次,注意不要漏写self#     Master.make_cake(self)  # 父类方法调用一次,注意不要漏写self## def make_school_cake(self):#     School.__init__(self)#     School.make_cake(self)# ⽅法⼀:代码冗余;⽗类类名如果变化,这⾥代码需要频繁修改def make_old_cake(self):Master.__init__(self)Master.make_cake(self)School.__init__(self)School.make_cake(self)daqiu = prentice()
daqiu.make_old_cake()  # 从输出可以看到,两个父类的同名方法都调用到了
daqiu.make_cake()
print(prentice.__mro__)输出:
古法配方制作煎饼果子
学校技术制作煎饼果子
独创配方制作煎饼果子
(<class '__main__.prentice'>, <class '__main__.School'>, <class '__main__.Master'>, <class 'object'>)

方法二:super()方法,带参数写法, super(当前类名, self).函数()
方法二特点:super里的类名是当前类名,自己可以控制,防止改了类名而未改super里的类名。缺点是仍然需要注意上下保持一致,而且如果有多个父类,需要在多个父类里加入super代码。

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class School(Master):def __init__(self):self.kongfu = "学校技术"self.name = "新东方"def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))# 方法二(一):super(当前类名,self).函数()super(School, self).__init__()super(School, self).make_cake()class prentice(School):def __init__(self):self.kongfu = "独创配方"def make_cake(self):self.__init__()  # 如果先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用子类方法前,先调用子类自己的初始化print("{}制作煎饼果子".format(self.kongfu))# def make_master_cake(self):  # 调用父类同名属性方法,为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化,类名.__init__(self)#     Master.__init__(self)  # 父类初始化调用一次,注意不要漏写self#     Master.make_cake(self)  # 父类方法调用一次,注意不要漏写self## def make_school_cake(self):#     School.__init__(self)#     School.make_cake(self)# ⽅法⼀:代码冗余;⽗类类名如果变化,这⾥代码需要频繁修改# def make_old_cake(self):#     Master.__init__(self)#     Master.make_cake(self)#     School.__init__(self)#     School.make_cake(self)# 方法二(一):super(当前类名,self).函数()def make_old_cake(self):  # 需要同时在当前类prentice的父类School里也加super()super(prentice, self).__init__()super(prentice, self).make_cake()daqiu = prentice()
daqiu.make_old_cake()
daqiu.make_cake()
print(prentice.__mro__)输出:
学校技术制作煎饼果子
古法配方制作煎饼果子
独创配方制作煎饼果子
(<class '__main__.prentice'>, <class '__main__.School'>, <class '__main__.Master'>, <class 'object'>)

<推荐使用以下方法>
方法三:super()方法,无参数写法, super().函数()
方法三特点:super()无参数写法,自动查找直接父类
使⽤super() 可以⾃动查找⽗类。调⽤顺序遵循 mro 类属性的顺序。⽐较适合单继承使⽤。
.

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class School(Master):def __init__(self):self.kongfu = "学校技术"self.name = "新东方"def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))# 方法二(一):super(当前类名,self).函数()#     super(School, self).__init__()#     super(School, self).make_cake()# 方法二(二):super(当前类名,self).函数()super().__init__()super().make_cake()class prentice(School):def __init__(self):self.kongfu = "独创配方"def make_cake(self):self.__init__()  # 如果先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用子类方法前,先调用子类自己的初始化print("{}制作煎饼果子".format(self.kongfu))# def make_master_cake(self):  # 调用父类同名属性方法,为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化,类名.__init__(self)#     Master.__init__(self)  # 父类初始化调用一次,注意不要漏写self#     Master.make_cake(self)  # 父类方法调用一次,注意不要漏写self## def make_school_cake(self):#     School.__init__(self)#     School.make_cake(self)# ⽅法⼀:代码冗余;⽗类类名如果变化,这⾥代码需要频繁修改# def make_old_cake(self):#     Master.__init__(self)#     Master.make_cake(self)#     School.__init__(self)#     School.make_cake(self)# 方法二(一):super(当前类名,self).函数()# def make_old_cake(self):  # 需要同时在当前类prentice的父类School里也加super()#     super(prentice, self).__init__()#     super(prentice, self).make_cake()# 方法二(二):super(当前类名,self).函数()def make_old_cake(self):super().__init__()super().make_cake()daqiu = prentice()
daqiu.make_old_cake()
daqiu.make_cake()
print(prentice.__mro__)输出:
学校技术制作煎饼果子
古法配方制作煎饼果子
独创配方制作煎饼果子
(<class '__main__.prentice'>, <class '__main__.School'>, <class '__main__.Master'>, <class 'object'>)

八、定义私有(实例)属性和方法

默认情况下,只要继承关系建立,子类默认继承父类所有的属性和方法,这些能够继承给子类的属性方法叫共有权限。

如果有些属性和方法不想继承给子类了,私有权限,可以添加私有属性方法来实现。

注意:私有属性和私有方法只能在类里面访问和修改。,对某些属性方法起到保护作用。

.

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class School:def __init__(self):self.kongfu = "学校技术"self.name = "新东方"def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class prentice(School, Master):def __init__(self):self.kongfu = "独创配方"self.__money = "一个亿"  # 定义私有属性def __printinfo(self):  # 定义私有⽅法print(self.kongfu)print(self.__money)def make_cake(self):self.__init__()  # 如果先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用子类方法前,先调用子类自己的初始化print("{}制作煎饼果子".format(self.kongfu))class TuShun(prentice):passxiaoqiu = TuShun()
print(xiaoqiu.kongfu)  # 独创配方
print(xiaoqiu.money)  # AttributeError: 'TuShun' object has no attribute 'money'
print(xiaoqiu.__money)  # AttributeError: 'TuShun' object has no attribute '__money'
xiaoqiu.printinfo  # AttributeError: 'TuShun' object has no attribute 'printinfo'
xiaoqiu.__printinfo  # AttributeError: 'TuShun' object has no attribute '__printinfo'
# ⼦类⽆法继承⽗类的私有属性和私有⽅法

九、获取和修改私有属性值

在Python中,在类里面,定义函数 get_属性名 ⽤来获取私有属性,定义 set_属性名 ⽤来修改私有属性值。

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class School:def __init__(self):self.kongfu = "学校技术"self.name = "新东方"def make_cake(self):print("{}制作煎饼果子".format(self.kongfu))class prentice(School, Master):def __init__(self):self.kongfu = "独创配方"self.__money = "私有:一个亿"def get_money(self):print(self.__money)  # 或者这里用 return self.__money,调用时用printdef set_money(self):self.__money = "私有更新:十个亿"def __printinfo(self):print(self.kongfu)print(self.__money)def make_cake(self):self.__init__()  # 如果先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用子类方法前,先调用子类自己的初始化print("{}制作煎饼果子".format(self.kongfu))class TuShun(prentice):passxiaoqiu = TuShun()
xiaoqiu.get_money()
xiaoqiu.set_money()
xiaoqiu.get_money()print(prentice.__mro__)输出:
私有:一个亿
私有更新:十个亿
(<class '__main__.prentice'>, <class '__main__.School'>, <class '__main__.Master'>, <class 'object'>)

十、私有类属性

class Dog:__age = 3@classmethoddef get_age(cls):return cls.__agewangcai = Dog()
result = wangcai.get_age()
print(result)  # 3

十一、继承知识小结


PS: source,itheima

Python OOP:继承、单继承、多继承、__mro__、子类重写父类同名属性和方法、子类调用父类同名属性和方法、多层继承、super()、私有(实例)属性和方法、获取修改私有属性值、私有类属性相关推荐

  1. layUI数据表格可编辑表格单元格值修改之后获取修改前的值

    table.on('edit(data_table)', function(obj){ //注:edit是固定事件名,test是table原始容器的属性 lay-filter="对应的值&q ...

  2. JavaScript 技术篇-简单的两行js代码获取password不可见密码实例演示,js获取密码输入框里的值

    如下图,chrome 控制台. 先获取到密码框的dom节点,再通过value就能获取到不可见的值. 密码框如下,其id是password. 右键检查元素可以定位到该元素的 dom 节点,里面直接会显示 ...

  3. 【轻松学】Python面向对象编程——类的设计、基础语法、继承、多态、类属性和类方法、单例设计

    文章目录 1. 类的设计 大驼峰命名法 1.1 类名的确定 1.2 属性和方法的确定 练习 1.1 练习 1.2 2. 面相对象基础语法 2.1 定义简单的类(只包含方法) 2.1.1 定义只包含方法 ...

  4. 27、Python 面向对象(创建类、创建实例对象、访问属性、内置类属性、对象销毁、类的继承、方法重写、基础重载方法、运算符重载、类属性与方法、下划线双下划线)

    27Python面向对象(Python2) Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.本章节我们将详细介绍Python的面向对象编程. ...

  5. Python 类属性和类方法、单例、异常

    文章目录 一.类的结构 1.术语 -- 实例 2.类是一个特殊的对象 二.类属性和实例属性 1. 概念和使用 2.属性的获取机制(科普) 三.类方法和静态方法 1. 类方法 2. 静态方法 四. 方法 ...

  6. Python类与对象技巧(1):字符串格式化、封装属性名、可管理的属性、调用父类方法

    1. 自定义字符串的格式化 _formats = {'ymd' : '{d.year}-{d.month}-{d.day}','mdy' : '{d.month}/{d.day}/{d.year}', ...

  7. Python 面向对象编程:类的创建与初始化、实例属性与方法、类属性与方法

    1. 类的创建并实例化 类的定义:在Python中,类通过 class 关键字定义.按照 Python 的编程习惯,类名以大写字母开头,紧接着是(object),表示该类是从哪个类继承下来的.下面是一 ...

  8. python实例属性与类属性_Python 面向对象编程:类的创建与初始化、实例属性与方法、类属性与方法...

    1. 类的创建并实例化 类的定义:在Python中,类通过class 关键字定义.按照 Python 的编程习惯,类名以大写字母开头,紧接着是(object),表示该类是从哪个类继承下来的.下面是一个 ...

  9. 【python】类属性以及实例属性、实例方法的介绍

    1. 类的组成 class Demo():var = 'demo' # 类属性,公有__num = 100 # 类属性,私有def __init__(self,name='muzi',age=18): ...

最新文章

  1. Linux基础(二)--基础的命令ls和date的详细用法
  2. C# 判断字符串是否符合十六进制,八进制,二进制和十进制整数格式的正则表达式...
  3. 杭电ACM刷题(1):1002,A + B Problem II
  4. Jfinal 对象列表返回前台json数据
  5. cctype 定义的函数 (记忆)
  6. JavaScript 数据类型检测终极解决方案
  7. Hosts文件与域名解析
  8. linux课程--实验三 vi 基本操作
  9. 将数字金额转换成大写金额
  10. TI深度学习(TIDL)--1
  11. js遍历(js遍历json对象)
  12. 操作系统笔记 第一章
  13. 学计算机没有女朋友绕口令,十句以上绕口令
  14. 可见首发《模式识别与智能计算:MATLAB技术实现(第2版)》 百度网盘 下载 分享
  15. 文件管理服务器win7,Win7如何取得文件管理所有权
  16. 什么是等级保护?为什么要开展等级保护?
  17. java + Selenium实现12306自动购票
  18. iCheck插件的全选、反选、获取值操作
  19. 微软学术搜索项目10个版本的历程 - 分析流程
  20. HTML+CSS实现渐变色标签,鼠标经过效果

热门文章

  1. NMEA码详解【转】
  2. 工具--常见eclipse配置导入web工程(tomcat容器)步骤
  3. mac下java环境变量配置
  4. 使用mysql++写入BLOB数据
  5. 计算机naf类型是什么,计算机系统结构课后习题答案
  6. php 上传100m文件,PHP向MySQL中insert100M以上的文件
  7. mysql like in 数组_Web前端学习教程之常用的MySQL优化技巧
  8. python中用turtle绘制正方形_在Python-Turtle图形中创建正方形和旋转正方形的简单方法...
  9. 中关村企业 大数据_中关村大数据产业联盟秘书长赵国栋:数字经济区别于传统经济 是企业转型升级的顶层战略...
  10. mac 无法识别android,mac 无法识别android真机