第六章 面向对象编程OOP

​ OOP将对象作为程序基本单元,一个对象包含了数据和操作数据的函数

面向过程把函数切分为子函数,把大块函数切割为小块函数降低系统复杂度

面向对象的程序设计把计算机程序视为一组对象的集合,每个对象可以接收其他对象发过来的消息并进行处理,计算机程序的执行就是一系列消息在各个对象之间传递。设计思想为抽象出class,根据class创建instance(实例、对象)。三大特点:封装、继承、多态

​ python中自定义的对象数据类型就是面向对象中的类的概念

一 面向对象三大特性

封装:将属性和方法书写到类的里面的操作;封装可以为属性和方法添加私有权限

继承:子类默认继承父类的所有属性和方法;子类可以重写父类的属性和方法

多态:传入不同的对象,产生不同的结果

二 类class和实例(对象)instance

类是创建实例(对象)的抽象的模板,实例是根据类创建出来的一个个具体对象,各个实例拥有的数据相互独立

是对一系列具有相同特征和行为的事物的统称,是一个抽象的概念,不是真实存在的事物,特征即属性,行为即方法

​ 类用来创建对象,对象是类创建出来的真实存在的事物,先有类,再有对象

1、定义类

​ 语法:class 类名(要继承的类名):,类名遵循大驼峰命名习惯

class Student1(object):		# 默认继承所有类的顶级类object
    def __init__(self,name,score):
        self.name=name
        self.score=score


​ class后是类名,通常大写开头。括号中表示从哪个类继承下来,如果没有则写object类

​2、创建实例(对象)

​ 语法:对象名 = 类名()

bart=Student1()


方法是与实例绑定的函数,可以直接访问实例的数据

2.1 定义类中的特殊方法
class Student1(object):
    def __init__(self,name,score):
        self.name=name
        self.score=score


​ 特殊方法名init前后有两个 ‘_’ 下划线,类中函数的第一个参数永远是self,表示创建实例的本身,在方法内部就可以将各种属性绑定到self,有了__init__方法后则不能传入空值,要传入与方法匹配的参数,但不用传self

bart=Student1('Bart',34)	# 为实例变量绑定属性


2.2 调用实例方法

​ 即在实例中的函数,语法为对象名.函数名()

class WashMashin():		# 默认继承所有类的顶级类object
    def wash(self):
        print("Washing")
haier=WashMashin()
haier.wash()		# 调用实例方法


2.3 self

​ self指调用该函数的对象

class WashMashin():
    def wash(self):
        print("Washing")
        print(self)			# <__main__.WashMashin object at 0x0000023682DFC940> —— 内存地址相同,self指代haier

haier=WashMashin()
print(haier)				# <__main__.WashMashin object at 0x0000023682DFC940>
haier.wash()


3、数据封装

​ 在类的内部定义访问数据的函数,把数据封装起来,无需知道方法内部的细节

class Student1(object):
    def __init__(self,name,score):
        self.name=name
        self.score=score
    def print_score(self):
        print('%s: %s' % (self.name,self.score))


​ 定义的方法print_score也是第一个参数为self,调用时就不用传参了

bart.print_score()			# Bart: 34


三 访问限制/私有权限

​ 在继承关系中,某些属性或者方法不想继承给子类,则将这些属性和方法设置为私有,即在属性名或方法名前加__

​ 在类中,若内部属性是公有的,则可以被外部访问并进行修改

bart.score=89
bart.print_score()			# Bart: 89


在属性名称前加两个__则将其变为私有变量,外部不能访问,只能在类里面访问和修改

class Student1(object):
    def __init__(self,name,score):
        self.__name=name
        self.__score=score
    def print_score(self):
        print('%s: %s' % (self.__name,self.__score))
        
bart=Student1('Bart',34)
bart.print_score()				# Bart: 34

bart.__score=89					# 无法修改与访问
bart.print_score()				# Bart: 34


若私有属性要获取,则在类中增加get_xx()方法,若私有属性要修改,则在类中增加set_xx()方法

class Student1(object):
    def __init__(self,name,score):
        self.__name=name
        self.__score=score
    def get_name(self):
        return self.__name
    def get_score(self):
        return self.__score
    def set_name(self,name):
        self.__name=name
    def set_score(self,score):
        if 0<=score<=100:
            self.__score=score
        else:
            raise ValueError('错误分数!')
       
bart=Student1('Bart',34)
bart.set_name('BART NAME')			# 修改名字
print(bart.get_name())				# 获取名字——BART NAME
bart.set_score(89)					# 修改分数
print(bart.get_score())				# 获取分数——89


​ 变量名__xxx__的是特殊变量,不是私有变量,可以直接访问,私有变量一定是后面没有__的

四 继承和多态

​ 在OOP中,新的类称为子类,被继承的类称为基类、父类或超类。子类会获得父类的全部功能(默认继承父类所有属性和方法),还可以新增方法。当子类和父类存在相同方法时,子类的方法会覆盖父类的方法

1、单继承

​ 一个子类继承一个父类

class A(object):
    def __init__(self):
        self.num=1
    def info_print(self):
        print(self.num)

class B(A):
    pass

c=B()
c.info_print()


2、多继承

​ 一个子类同时继承多个父类,默认使用第一个父类的同名属性和方法

class A(object):
    def __init__(self):
        self.num=1
    def info_print(self):
        print(self.num)

class C(object):
    def __init__(self):
        self.num=3
    def info_print(self):
        print(self.num)

class B(A,C):		# 优先继承A类的同名属性和方法
    pass
son=B()
print(son.num)		# 1
son.info_print()	# 1

class D(C,A):		# 优先继承A类的同名属性和方法
    pass
son1=D()
print(son1.num)		# 3
son1.info_print()	# 3


3、多层继承

​ 父类继承给子类,子类继承给孙类

class A(object):
    def __init__(self):
        self.num=1
    def info_print(self):
        print(self.num)

class C(object):
    def __init__(self):
        self.num=3
    def info_print(self):
        print(self.num)

class B(A,C):
    def __init__(self):
        self.num = 5
    def info_print(self):
        self.__init__()
        print(self.num)
    def A_make(self):
        A.__init__(self)
        A.info_print(self)
    def C_make(self):
        C.__init__(self)
        C.info_print(self)

class E(B):		# 继承
    pass

grandson=E()
grandson.info_print()
grandson.A_make()


4、子类与父类同名方法和属性

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

​ 若子类和父类有同名方法和属性,用子类创建对象,调用同名方法和对象,调用的是子类的

class A(object):
    def __init__(self):
        self.num=1
    def info_print(self):
        print(self.num)

class C(object):
    def __init__(self):
        self.num=3
    def info_print(self):
        print(self.num)

class B(A,C):
    def __init__(self):
        self.num = 5
    def info_print(self):
        print(self.num)

son=B()
print(son.num)			# 5
son.info_print()		# 5


4.2 子类调用父类同名方法和属性

​ 将父类的同名属性和方法再次封装即可

class A(object):
    def __init__(self):
        self.num=1
    def info_print(self):
        print(self.num)

class C(object):
    def __init__(self):
        self.num=3
    def info_print(self):
        print(self.num)

class B(A,C):
    def __init__(self):
        self.num = 5
    def info_print(self):
    	# 加自己的初始化原因:num数性值是上一次调用的init内的属性,而不是自己的属性
        self.__init__()
        print(self.num)
    def A_make(self):
        # 再次调用初始化原因:如果不调用初始化,那么A的num就是5,而不是1。要调用父类同名方法和属性,属性在init初始化位置,因而要再次调用init
        A.__init__(self)
        # 父名类名.函数(self)
        A.info_print(self)
    def C_make(self):
        C.__init__(self)
        C.info_print(self)

son=B()
print(son.num)
son.A_make()
son.C_make()
son.info_print()


4.3 super()调用父类方法

​ 带参数语法:super(当前类名,self).函数()

class A(object):
    def __init__(self):
        self.num=1
    def info_print(self):
        print(f'A类:{self.num}')

class C(A):
    def __init__(self):
        self.num=3
    def info_print(self):
        print(f'C类:{self.num}')
        super(C,self).__init__()		# 父类带参数,当有这代码时,B类找到C类后可继续找到A类
        super(C,self).info_print()

class B(C):
    def __init__(self):
        self.num = 5
    def info_print(self):
        self.__init__()
        print(f'B类:{self.num}')
    def C_make(self):
        super(B,self).__init__()		# 父类带参数
        super(B,self).info_print()

son=B()
son.C_make()


​ 无参数用法:super().函数(),比较适合单继承使用

class A(object):
    def __init__(self):
        self.num=1
    def info_print(self):
        print(f'A类:{self.num}')

class C(A):
    def __init__(self):
        self.num=3
    def info_print(self):
        print(f'C类:{self.num}')

class B(C):
    def __init__(self):
        self.num = 5
    def info_print(self):
        self.__init__()
        print(f'B类:{self.num}')
    def C_make(self):
        super().__init__()			# 无参数,当C中无super时,只能追追到C而不能到A
        super().info_print()

son=B()
son.C_make()


5、查看类的继承关系

​ 语法:类名.__mro__

print(B.__mro__)	# (<class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>)


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值