面向对象高级

0.继承
知识点:
继承:  子类默认能够使用父类的属性和方法

object:  所有类的父类,基类,超类,上帝类,祖宗类...

python3.x版本:  默认所有的类都继承了object类

子类:  也叫派生类


1.单继承
知识点:
单继承格式:  class 子类名(父类名): pass

注意: 一个类可以有多个子类
示例:
# 单继承格式:  class 子类名(父类名): pass
# 注意: 所有的类都默认继承了object类
# 先定义一个人类
class Person(object):
    def study(self):
        print('学习使我快乐')


# 学生类不想自己定义内容了,想用父类的属性和方法(前提父类需要存在)
class Student(Person):
    pass


# 创建学生对象
s = Student()
# 学生对象调用人类方法(因为继承了人类,所以默认能够使用人类的属性和方法)
s.study()
2.单继承一个类可以有多个子类
知识点:
单继承格式:  class 子类名(父类名): pass

注意: 一个类可以有多个子类
示例:
# 单继承格式:  class 子类名(父类名): pass
# 注意: 所有的类都默认继承了object类
# 先定义一个人类
class Person(object):
    def study(self):
        print('学习使我快乐')


# 学生类不想自己定义内容了,想用人类的属性和方法(前提人类需要存在)
class Student(Person):
    pass


# 教师类也可以去继承人类
class Teacher(Person):
    pass


# 创建学生对象
s = Student()
# 学生对象调用人类方法(因为继承了人类,所以默认能够使用人类的属性和方法)
s.study()

# 创建教师对象
t = Teacher()
# 教师对象调用人类方法(因为继承了人类,所以默认能够使用人类的属性和方法)
t.study()

3.单继承练习
需求:
需求: 已知一个师父类,有传统配方属性,有传统制作煎饼果子方法,有一个徒弟想去学习,可以使用继承来完成
示例:
# 1.定义师父类
class Master(object):
    def __init__(self):
        # 由于是独一份配方,不需要传参,直接赋值
        self.secret = '传统配方'

    def make(self):
        print(f'使用{self.secret}制作煎饼果子')


# 2.定义徒弟类
class Prentice(Master):
    pass


# 3.创建徒弟对象
p = Prentice()
# 4.徒弟对象获取从师父类继承下来的配方
print(p.secret)
# 5.徒弟对象使用从师父类继承下来的制作方法
p.make()

4.多继承
知识点:
多继承格式: class 子类名(父类名1,父类名2,父类名3...)

注意: 一个类可以有多个父类,但是默认使用第一个父类的同名属性和方法
示例:
# 需求: 有一个徒弟想去学习一开始目的是填饱肚子,继承了师父类,有传统配方属性,有传统制作煎饼果子方法,
# 填饱肚子后,想走上人生巅峰,选择继续去互联网创业,可以使用多继承来完成
# 1.1定义师父类
class Master(object):
    def __init__(self):
        # 由于是独一份配方,不需要传参,直接赋值
        self.secret = '传统煎饼果子配方'

    def make(self):
        print(f'使用{self.secret}制作煎饼果子填饱肚子')


# 1.2定义CSDN学校类
class School(object):
    def __init__(self):
        # 由于是独一份配方,不需要传参,直接赋值
        self.secret = '创业'

    def make(self):
        print(f'使用{self.secret}走上人生巅峰')

    def study(self):
        print('我现在在互联网深造')


# 2.定义徒弟类
# 注意: 如果继承多个父类,默认使用第一个父类的同名属性和方法
class Prentice(Master,School):
    pass


# 3.创建徒弟对象
p = Prentice()
# 4.徒弟对象获取从父类继承下来的配方
print(p.secret)
# 5.徒弟对象使用从父类继承下来的制作方法
p.make()
# 6.徒弟对象直接调用继承下来的其他方法
p.study()


5.子类重写父类属性和方法
知识点:
子类重写父类属性和方法的目的?: 为了在原有基础上拓展功能(父类继承下来的不能满足子类需求)

注意: 如果重写了属性和方法,子类默认调用的是子类自己的同名属性和方法
示例:
# 需求: 有一个徒弟想去学习一开始目的是填饱肚子,继承了师父类,有传统配方属性,有传统制作煎饼果子方法,
# 填饱肚子后,想走上人生巅峰,选择继续去CSDN学Python,可以使用多继承来完成
# 徒弟类CSDN学习毕业后,独创编程语言开创了上市煎饼果子全国连锁公司,实现财富自由...
# 1.1定义师父类
class Master(object):
    def __init__(self):
        # 由于是独一份配方,不需要传参,直接赋值
        self.secret = '传统煎饼果子配方'

    def make(self):
        print(f'使用{self.secret}制作煎饼果子填饱肚子')


# 1.2定义CSDN学校类
class School(object):
    def __init__(self):
        # 由于是独一份配方,不需要传参,直接赋值
        self.secret = 'CSDN'

    def make(self):
        print(f'使用{self.secret}走上人生巅峰')

    def study(self):
        print('我现在在学习Python')


# 2.定义徒弟类
# 注意1: 如果继承多个父类,默认使用第一个父类的同名属性和方法
# 注意2: 如果子类重写了父类的属性和方法,默认使用子类自己的同名属性和方法
class Prentice(Master, School):
    def __init__(self):
        self.secret = '独创编程语言'

    def make(self):
        print(f'使用{self.secret}开创了煎饼果子全国连锁上市公司,实现财富自由')


# 3.创建徒弟对象
p = Prentice()
# 4.徒弟对象调用同名属性
print(p.secret)
# 5.徒弟对象使用同名方法
p.make()
# 6.徒弟对象直接调用继承下来的其他方法
p.study()


6.子类调用父类的同名属性和方法
知识点:
子类调用父类同名属性和方法格式:   父类名.父类方法名(self)
示例:
# 需求: 有一个徒弟想去学习一开始目的是填饱肚子,继承了师父类,有传统配方属性,有传统制作煎饼果子方法,
# 填饱肚子后,想走上人生巅峰,选择继续去CSDN学python,可以使用多继承来完成
# 徒弟类CSDN学习毕业后,独创编程语言开创了上市煎饼果子全国连锁公司,实现财富自由...
# 实现了财务自由的时候,又回忆原来学习煎饼果子的经历或者CSDN的学习的经历
# 1.1定义师父类
class Master(object):
    def __init__(self):
        # 由于是独一份配方,不需要传参,直接赋值
        self.secret = '传统煎饼果子配方'

    def make(self):
        print(f'使用{self.secret}制作煎饼果子填饱肚子')


# 1.2定义CSDN学校类
class School(object):
    def __init__(self):
        # 由于是独一份配方,不需要传参,直接赋值
        self.secret = 'CSDN'

    def make(self):
        print(f'使用{self.secret}走上人生巅峰')

    def study(self):
        print('我现在在CSDN学习深造')


# 2.定义徒弟类
# 注意1: 如果继承多个父类,默认使用第一个父类的同名属性和方法
# 注意2: 如果子类重写了父类的属性和方法,默认使用子类自己的同名属性和方法
# 注意3: 如果子类重写后又想调用父类同名方法:  父类名.父类方法名(self)
class Prentice(Master, School):
    def __init__(self):
        self.secret = '独创编程语言'

    def make(self):
        print(f'使用{self.secret}开创了煎饼果子全国连锁上市公司,实现财富自由')
        # 想调用CSDN的同名属性和方法
        School.__init__(self)
        School.make(self)
        # 想调用师父的同名属性和方法
        Master.__init__(self)
        Master.make(self)


# 3.创建徒弟对象
p = Prentice()
# 4.徒弟对象调用同名属性
print(p.secret)
# 5.徒弟对象使用同名方法
p.make()
# 6.徒弟对象直接调用继承下来的其他方法
p.study()


7.多层继承
知识点:
多层继承:   父子孙等多代关系   

举例:  类A继承类B,类B继承类C    ABC的关系就是多层继承

方法解析顺序: mro(method resolve order)

两种方式:  属性:__mro__   方法:mro()
示例:
# 需求: 有一个徒弟想去学习一开始目的是填饱肚子,继承了师父类,有传统配方属性,有传统制作煎饼果子方法,
# 填饱肚子后,想走上人生巅峰,选择继续去CSDN学习Python,可以使用多继承来完成
# 徒弟类CSDN学习毕业后,独创编程语言开创了上市煎饼果子全国连锁公司,实现财富自由...
# 实现了财务自由的时候,又回忆原来学习煎饼果子的经历或者CSDN学习的经历
# 之前这些奋斗的东西,他的儿子直接继承(富二代)
# 1.1定义师父类
class Master(object):
    def __init__(self):
        # 由于是独一份配方,不需要传参,直接赋值
        self.secret = '传统煎饼果子配方'

    def make(self):
        print(f'使用{self.secret}制作煎饼果子填饱肚子')


# 1.2定义CSDN学校类
class School(object):
    def __init__(self):
        # 由于是独一份配方,不需要传参,直接赋值
        self.secret = 'CSDN'

    def make(self):
        print(f'使用{self.secret}走上人生巅峰')

    def study(self):
        print('我现在在CSDN学习深造')


# 2.定义徒弟类
# 注意1: 如果继承多个父类,默认使用第一个父类的同名属性和方法
# 注意2: 如果子类重写了父类的属性和方法,默认使用子类自己的同名属性和方法
# 注意3: 如果子类重写后又想调用父类同名方法:  父类名.父类方法名(self)
class Prentice(Master, School):
    def __init__(self):
        self.secret = '独创编程语言'

    def make(self):
        print(f'使用{self.secret}开创了煎饼果子全国连锁上市公司,实现财富自由')
        # 想调用CSDN的同名属性和方法
        School.__init__(self)
        School.make(self)
        # 想调用师父的同名属性和方法
        Master.__init__(self)
        Master.make(self)
# 2.1 徒弟有了自己的儿子,儿子直接继承使用
# 多层继承:  Son->Prentice->Master->School->object
class Son(Prentice):
    pass

# 3.创建徒弟的儿子对象
s = Son()
# 4.徒弟的儿子对象调用同名属性
print(s.secret)
# 5.徒弟的儿子对象使用同名方法
s.make()
# 6.徒弟对象的儿子直接调用继承下来的其他方法
s.study()
# 7.获取方法解析顺序
# 方法mro() [<class '__main__.Son'>, <class '__main__.Prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>]
print(Son.mro()) 
# 属性__mro__  (<class '__main__.Son'>, <class '__main__.Prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>)
print(Son.__mro__)  

8.super调用父类同名属性和方法
知识点:
super:  父类的代理
注意: super是根据mro顺序去查找 ,优先调用第一个父类同名方法

子类调用父类同名属性和方法3种方式:
方式1,通过父类名去调用: 父类名.父类方法名(self)
方式2,python3.x版本之前: super(当前类名,self).父类方法名()
方式3,python3.x版本:  super().父类方法名()
示例:
# 需求: 有一个徒弟想去学习一开始目的是填饱肚子,继承了师父类,有传统配方属性,有传统制作煎饼果子方法,
# 填饱肚子后,想走上人生巅峰,选择继续去CSDN学大数据,可以使用多继承来完成
# 徒弟类CSDN学习完毕后,独创编程语言开创了上市煎饼果子全国连锁公司,实现财富自由...
# 实现了财务自由的时候,又回忆原来学习煎饼果子的经历或者CSDN学习的经历
# 之前这些奋斗的东西,他的儿子直接继承(富二代)
# 1.1定义师父类
class Master(object):
    def __init__(self):
        # 由于是独一份配方,不需要传参,直接赋值
        self.secret = '传统煎饼果子配方'

    def make(self):
        print(f'使用{self.secret}制作煎饼果子填饱肚子')


# 1.2定义CSDN学校类
class School(object):
    def __init__(self):
        # 由于是独一份配方,不需要传参,直接赋值
        self.secret = 'CSDN'

    def make(self):
        print(f'使用{self.secret}走上人生巅峰')

    def study(self):
        print('我现在在CSDN学习深造')


# 2.定义徒弟类
# 注意1: 如果继承多个父类,默认使用第一个父类的同名属性和方法
# 注意2: 如果子类重写了父类的属性和方法,默认使用子类自己的同名属性和方法
# 注意3: 如果子类重写后又想调用父类同名方法:  父类名.父类方法名(self)
class Prentice(Master,School):
    def __init__(self):
        self.secret = '独创编程语言'

    def make(self):
        print(f'使用{self.secret}开创了煎饼果子全国连锁上市公司,实现财富自由')
        # 想调用CSDN的同名属性和方法
        School.__init__(self)
        School.make(self)

        # 想调用师父的同名属性和方法
        Master.__init__(self)
        Master.make(self)
        # 使用super调用父类同名方法:
        # 注意:按照mro方法解析顺序找,默认找的是第一个父类的同名属性和方法
        super().__init__()
        super().make()
        # python3.x版本: 优化了python3.x版本之前的方式
        # python3.x版本之前:  super(当前类名,self).父类方法名()
        super(Prentice,self).__init__()
        super(Prentice,self).make()


# 2.1 徒弟有了自己的儿子,儿子直接继承使用
# 多层继承:  Son->Prentice->Master->School->object
class Son(Prentice):
    pass


# 3.创建徒弟的儿子对象
s = Son()
# 4.徒弟的儿子对象调用同名属性
print(s.secret)
# 5.徒弟的儿子对象使用同名方法
s.make()
# 6.徒弟对象的儿子直接调用继承下来的其他方法
s.study()
# 7.获取方法解析顺序
# 方法mro() [<class '__main__.Son'>, <class '__main__.Prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>]
print(Son.mro())
# 属性__mro__  (<class '__main__.Son'>, <class '__main__.Prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>)
print(Son.__mro__)


9.私有权限
知识点:
私有属性: _ _属性名
私有方法: _ _方法名()

私有属性和私有方法的效果:  隐藏到类中
1: 不能被外界直接访问
2: 不能被子类继承
示例:
# 私有权限能够达到隐藏效果:  类外不能直接访问属性和方法,本类中可以访问的
# 私有权限:  私有属性:__属性名    私有方法:__方法名()
# 1.定义类(类中定义私有属性和私有方法)
class Master(object):
    def __init__(self):
        self.name = '大师'
        self.__money = 1000  # 私有属性

    # 私有方法
    def __house(self):
        print('师父的私人别墅...')


# 徒弟类
class Prentice(Master):
    def show(self):
        print(self.name)  # name是从Master类中继承下来的
        print(self.__money)  # 此行运行报错,因为私有属性和私有方法都不能被子类继承


# 2.创建大师对象
m = Master()
print(m.name)  # 非私有属性能直接访问
# print(m.__money) # 测试是否能够直接访问私有属性? 不能  此行报错
# m.__house() # 测试是否能够直接方式私有方法? 不能  此行报错

# 3.创建徒弟对象
p = Prentice()
p.show()


10.修改和获取私有属性和调用私有方法
知识点:
私有属性: _ _属性名
私有方法: _ _方法名()

私有属性和私有方法的效果:  隐藏到类中,本类中是可以访问的
1: 不能被外界直接访问
2: 不能被子类继承

通过类中的公共方法间接访问私有属性:  设置,放: set_属性名    获取,拿: get_属性名
通过类中的公共方法间接调用私有方法:  展示: show_私有方法名
示例:
# 私有权限能够达到隐藏效果: 类外不能直接访问属性和方法,本类中可以访问的
# 封装:  把属性和方法隐藏起来,对外提供公共的方法,让外界通过公共方法访问
# 私有权限:  私有属性:__属性名    私有方法:__方法名()
# 1.定义类(类中定义私有属性和私有方法)
class Master(object):
    def __init__(self):
        self.name = '大师'
        self.__money = 1000  # 私有属性

    # 公共方法1:set_属性名()用于修改私有属性   set: 放  设置
    def set_money(self, money):
        self.__money += money  # 存钱

    # 公共方法2:get_属性名()用于获取私有属性   get: 拿 获取
    def get_money(self):
        return self.__money

    # 私有方法
    def __house(self):
        print('师父的私人别墅...')

    # 共有方法3: show_house用于调用私有方法  show: 展示
    def show_house(self):
        self.__house()


# 2.创建师父对象
m = Master()
print(m.name)  # 非私有属性能直接访问
# print(m.__money) # 测试是否能够直接访问私有属性? 不能  此行报错,因为私有属性不能被外界直接访问
# m.__house() # 测试是否能够直接方式私有方法? 不能  此行报错,因为私有方法不能被外界直接访问

# 3.通过公共的接口间接访问私有属性
# 部队: 军事重地,闲人免进    通过门卫间接找到你朋友
# 通过get方法间接获取私有属性(查询)
print('保险箱原来的金额:', m.get_money())
# 通过set方法间接修改私有属性(存钱)
m.set_money(2000)
# 通过get方法间接获取私有属性(查询)
print('存了2000后的金额:', m.get_money())

# 4.通过公共的接口间接访问私有方法
m.show_house()


11.面向对象三大特性
知识点:
封装: 把属性和方法隐藏到类中,对外提供公共的接口(方法)

继承: 子类默认能使用父类的公共属性和方法,子类如果想拓展功能,可以去重写父类属性和方法

多态(了解): python中多态是伪多态: 同一个方法,传入不同的对象,实现不同的结果
示例:
# 定义基类:狗类
class Dog(object):
    def work(self):
        print('狗看家')


# 定义派生类: 军犬
class ArmyDog(Dog):
    # 重写目的? 拓展功能
    def work(self):
        print('狗看家')
        print('追击敌人...')


# 定义派生类: 缉毒犬
class DrugDog(Dog):
    # 重写目的? 拓展功能
    def work(self):
        print('狗看家')
        print('追查毒品...')


# 多态的前提: 继承   注意python中是伪多态
# 体验python中伪多态: 同一方法,传入不同对象,达到不同结果
class Person(object):
    def dog_work(self, dog):  # 引用地址传递: dog=ad    dog=dd
        dog.work()  # ad.work() 或者  dd.work()


# 测试
zs = Person()
# dog_work方法中传递军犬对象
ad = ArmyDog()
zs.dog_work(ad)
# dog_work方法中传递缉毒犬对象
dd = DrugDog()
zs.dog_work(dd)


12.实例属性和类属性
知识点:
类属性
访问方式1:  类名.类属性名
方法方式2:  对象名.类属性名

1.内存存储不同:
实例属性: 每次都会给每个对象单独开辟一块空间,如果有一个属性是所有对象都一样的,实例属性就会浪费内存
类属性:  类属性是所有对象都会共享, 只会开辟一块空间, 相对节省内存,如果有一个属性是所有对象都一样的,建议使用类属性

2.位置不同:
实例属性: 方法内: self.实例属性 = 值
类属性: 类中方法外:   类属性 = 值

3.调用方式不同:
实例属性: 只能通过  对象名.实例属性   或者  self.实例属性   获取
类属性: 除了可以通过对象名或者self获取, 还可以通过  类名.类属性  获取
实例属性示例:
# 定义一个狗类
class Dog(object):
    def __init__(self,name):
        # 实例属性: 每个对象都会单独创建一次
        self.name = name
        self.tooth = 10  # 二哈和金毛都各自有一个实例属性tooth数量都是10,浪费内存

    # 实例方法
    def show(self):
        print(self.name)

# print(Dog.tooth) #此行报错,实例属性只能通过实例对象访问
# 创建实例对象
eh = Dog('二哈')
# 通过对象名.实例属性获取年龄
print(eh.name,eh.tooth)
# 痛过对象名.实例方法名获取
eh.show()

jm = Dog('金毛')
print(jm.name,jm.tooth)
jm.show()
类属性示例:
# 定义一个狗类
class Dog(object):
    # 类属性: 位置: 类中方法外    特点: 所有对象共有
    tooth = 10  # 二哈和金毛共用一个类属性tooth,节省内存

    def __init__(self, name):
        # 实例属性位置: 方法内
        # 实例属性: 每个对象都会单独创建一次
        self.name = name

    # 实例方法
    def show(self):
        print(self.name)


# 类属性可以 类名.类属性 直接访问,也可以实例对象访问 对象名.类属性
# 类属性只能通过类对象修改,不能通过实例对象修改
print(Dog.tooth)
# 实例对象1
eh = Dog('二哈')
print(eh.name, eh.tooth)
eh.show()
# 实例对象2
jm = Dog('金毛')
print(jm.name, jm.tooth)
jm.show()
print('---------------------------------')
# 修改类属性:只能通过类对象修改
Dog.tooth = 12
print(Dog.tooth)  # 12
print(eh.name, eh.tooth) # 12
print(jm.name, jm.tooth) # 12
print('---------------------------------')
# 注意: 如果实例对象试图去修改类属性,不会报错,会给该对象单独创建一个和类属性同名的实例属性
eh.tooth = 22
print(Dog.tooth) # 12
print(eh.name, eh.tooth) # 22
print(jm.name, jm.tooth) # 12


13.类方法
知识点:
类方法装饰器:  @classmethod  

类对象: cls

注意: 类方法一般都是为了配合类属性使用

访问方式1:  类名.类方法名()
方法方式2:  对象名.类方法名()
示例:
# 定义类
class Dog(object):
    # 定义类属性,私有化类属性
    __tooth = 10

    # 实例方法: self: 代表实例对象
    def show1(self):
        print(self.__tooth)

    # 类方法 : cls: 代表类对象
    @classmethod  # 装饰器
    def show2(cls):
        print(cls.__tooth)


# 访问私有类属性
# 方式1: 类名.类属性
# print(Dog.tooth) # 报错,因为私有类属性不能被外界直接访问
# 方式2: 对象名.类属性
eh = Dog()
# print(eh.tooth)  # 报错,因为私有类属性不能被外界直接访问

# 通过实例方法间接访问私有类属性
Dog.show1(eh)  # 类名调用实例方法,必须手动传入实例对象
eh.show1() # python解释器自动传入

# 通过类方法间接访问私有类属性
# 方式1: 类名.类方法名()
Dog.show2()
# 方式2: 对象名.类方法名()
eh.show2()


14.静态方法
知识点:
为什么学静态方法?: 不用传递self,不用传递cls,相对节省内存

静态方法装饰器: @staticmethod

访问方式1:  类名.静态方法名()
方法方式2:  对象名.静态方法名()
示例:
# 定义类
class Dog(object):
    # 定义静态方法 :使用装饰器 @staticmethod
    # 为什么学静态方法? 实例方法必须传self
    def show1(self):
        print('这是一个实例方法')

    # 为什么学静态方法? 类方法必须传cls
    @classmethod
    def show2(cls):
        print('这是一个类方法')

    # 为什么学静态方法? 不用传递self,不用传递cls
    @staticmethod
    def show3():
        print('这是一个静态方法')

# 创建对象
d = Dog()
# 1.调用实例方法 :对象名.方法名()
d.show1()
# Dog.show1()  #此行报错,实例方法不能直接通过类名访问
Dog.show1(d) # 实例方法通过类名调用时,必须手动传入实例对象

# 2.调用类方法 : 对象名.方法名()   类名.方法名()
d.show2()
Dog.show2()

# 3.调用静态方法 : 对象名.方法名()   类名.方法名()
d.show3()
Dog.show3()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值