Python本人自学笔记(12) 面向对象三大特征

封装

隐藏内部细节,对外提供操作方式

权限控制:是通过对属性或方法添加单下划线、双下划线以及首尾双下划线来实现

  • 单下划线开头:以单下划线开头的属性或方法表示protected受保护的实例属性,这类实例属性被视为仅供内部使用,允许类本身和子类进行访问,但实际上它可以被外部代码访问。
  • 双下划线开头:表示private私有的实例属性,这类实例属性只允许定义该属性或方法的类本身进行访问。
  • 首尾双下划线:一般表示特殊的方法。
class Student():
    #首尾双下划线
    def __init__(self,name,age,gender):
        self._name = name# self._name受保护的实例属性,只能本类和子类访问
        self.__age = age#self.__age表示私有的实例属性,只能类本身去访问
        self.gender = gender#普通的实例属性,类的内部、外部、子类都可以访问

    def _fun1(self):
        print('子类及本身可以访问')

    def __fun2(self):
        print('只有定义的类可以访问')
    def show(self):
        self._fun1()#受保护的方法
        self.__fun2()#私有的方法
        print(self._name)#受保护的实例属性
        print(self.__age)#私有的实例属性
stu=Student('张三',20,'男')
print(stu._name)#在类外可以访问受保护的实例属性
#print(stu.__age)#AttributeError: 'Student' object has no attribute '__age'.
stu._fun1()#在类外可以访问受保护的方法
# stu.__fun2()#AttributeError: 'Student' object has no attribute '__fun2'.

在类外访问私有实例属性和方法需要在使用前加 _类名,但是不建议使用

print(stu._Student__age)
stu._Student__fun2()

可以使用修饰器 @property(设置方法,将其转换成属性)来访问私有属性,仅查看,不能修改

class Student:
    def __init__(self,name,gender):
        self.name = name
        self.__gender = gender #self.__gender是私有的实例属性
    #使用@property 修改方法
    @property
    def gender(self):
        return self.__gender
stu=Student('X','女')
print(stu.name,'的性别是',stu.gender)

 要再加 @已经设置的方法名.setter 再命名一个方法名相同,变量不同的方法(方法重载??)

class Student:
    def __init__(self,name,gender):
        self.name = name
        self.__gender = gender #self.__gender是私有的实例属性
    #使用@property 修改方法
    @property#使用@property 设置方法,将其转换成属性
    def gender(self):
        return self.__gender

    @gender.setter#这样写才能修改属性
    def gender(self,valye):
        self.__gender = valye

stu=Student('X','女')
stu.gender='男'#把女修改成男
print(stu.name,'的性别是',stu.gender)

继承

  •  在Python中一个子类可以继承N个父类
  • 一个父类也可以继承多个子类
  • 如果一个类没有继承任何类,那么这个类默认继承object类

 继承的语法结构:

class 类名(父类1,父类2,...,父类N):
    pass

举例:

class FatherA:#创建父类A
    def __init__(self,name):#初始化方法
        self.name=name#实例属性赋值
    def showA(self):
        print('父类A的方法')

class FatherB:#创建父类B
    def __init__(self,age):#初始化方法
        self.age=age#实例属性赋值
    def showB(self):
        print('父类B的方法')

class Son(FatherA,FatherB):#子类Son继承两个父类A、B
    def __init__(self,name,age,genter):#初始化方法,其中包含两个父类中的变量name、age,还有自己的genter
        FatherA.__init__(self,name)#使用父类A的初始化方法
        FatherB.__init__(self,age)#
        self.genter=genter
    def showS(self):
        print(f'我是{self.name},今年{self.age},是{self.genter}生')

son=Son('XX',18,'男')
son.showA()
son.showB()
son.showS()

 方法重写

  • 子类继承了父类就拥有了父类中公有成员和受保护的成员
  • 父类的方法并不能完全适应子类的需求,这时候子类就可以重写父类的方法
  • 子类在重写父类的方法时,要求方法名称必须与父类的名称相同,在子类重写后的方法中可以通过super().xxx()调用父类中的方法
class Father:#创建父类
    def __init__(self,name,age):#初始化方法
        self.name=name#实例属性赋值
        self.age=age
    def show(self):
        print(f'我是{self.name},今年{self.age}')
class Son(Father):
    def __init__(self,name,age,stuNo):
        super().__init__(name,age)
        self.stuno=stuNo
    def show(self):#重写父类的 show 方法
        super().show()#输出一遍父类
        print(f'学号是:{self.stuno}')
son=Son('XXX',21,'1001')
son.show()
class Doctor(Father):
    def __init__(self,name,age,room):
        super().__init__(name,age)
        self.room=room
    def show(self):
        print(f'我叫{self.name},今年{self.age},在{self.room}办公')

doctor=Doctor('YYY',30,1002)
doctor.show()

 多态

  • 指的就是“多种形态”,即便不知道一个变量所引用的对象到底是什么类型,仍可以通过这个变量调用对象的方法。
  • 在程序运行过程中根据变量所引用对象的数据类型,动态决定调用哪个对象中的方法。
  • Python语言中的堕胎,根本不关心对象的数据类型,也不关心类之间是否存在继承关系,只关心对象的行为(方法)。只要不同的类中有同名的方法,即可实现多态。
class Person:
    def eat(self):
        print('人吃五谷杂粮')
class Cat:
    def eat(self):
        print('猫吃鱼')
class Dog:
    def eat(self):
        print('狗吃骨头')

#这三个类中都有一个同名的方法 eat
#编写函数
def fun(obj):#obj是函数的形式参数,在定义处不知道形参的类型
    obj.eat()
#创建三个类的对象
per=Person()
cat=Cat()
dog=Dog()
#调用fun
fun(per)#Python中的多态,不关心对象的数据类型,只关心对象是否具有同名方法
fun(cat)
fun(dog)

 有点抽象....

调试打上断点

 先到 fun

 obj数据类型为Person

 然后输出了Person的函数eat()

下一步obj数据类型变成了Cat,然后输出.....

 接下来也一样。

 应该能理解为:

把类当参数传递,一般传递的是变量。有点像委托。

函数传递对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值