首页 > 其他分享 >Day21笔记-封装&继承

Day21笔记-封装&继承

时间:2024-09-16 19:50:47浏览次数:3  
标签:__ 封装 name self Day21 笔记 print age def

复习面向对象基础语法

# 定义类
class Person():
    # 类属性
    num = 10
    # 限制对象属性的动态绑定
    __slots__ = ('name','age','hobby')
    # 定义实例属性
    def __init__(self,name,age,hobby):
        self.name = name
        self.age = age
        self.hobby = hobby
    # 类中的函数
    # 实例函数
    def func1(self,a,b):
        print('1111',a,b)
    # 类函数
    @classmethod
    def func2(cls,a):
        print('22222',a)
    # 静态函数
    @staticmethod
    def func3(num1,num2):
        print('333333',num1,num2)
​
# 创建对象/实例化对象/类的实例化
p = Person('aaa',10,'dance')
# 访问属性
print(Person.num)
print(p.num)
print(p.name,p.age,p.hobby)
# 调用函数
p.func1(5,8)
​
Person.func2(34)
p.func2(34)
​
Person.func3(45,7)
p.func3(45,8)

Day20作业

'''
1.设计两个类:
    a. 一个点Pointer类,属性包括x,y坐标。
    b. 一个Rectangle类(矩形),属性有左上角坐标,宽,高
        方法:1. 计算矩形的面积;2. 判断点是否在矩形内
    c.实例化一个点对象,一个正方形对象,输出矩形的面积,输出点是否在矩形
'''
class Pointer():
    __slots__ = ('x','y')
    def __init__(self,x,y):
        self.x = x
        self.y = y
class Rectangle():
    __slots__ =  ('left_top_point','width','height')
    # left_top_point:表示一个点Pointer的对象
    def __init__(self,left_top_point,width,height):
        self.left_top_point = left_top_point
        self.width = width
        self.height = height
    def area(self):
        return self.width * self.height
    def judge(self,point):
        # self:矩形对象  point:点的对象
        # x轴
        r0 = self.left_top_point.x < point.x < self.left_top_point.x + self.width
        # y轴
        r1 = self.left_top_point.y - self.height < point.y < self.left_top_point.y
        return r0 and r1
​
# 创建表示左上角点的对象
left_top_point = Pointer(2,19)
# 创建矩形对象
rect = Rectangle(left_top_point,10,10)
print(f'矩形的面积为:{rect.area()}')
​
# 创建一个某点的对象
point = Pointer(54,10)
print(rect.judge(point))

一、面向对象三大特征

1.封装

面向对象的三大特征:封装,继承和多态

广义的封装:函数的定义和类的定义

狭义的封装:一个类中的某些属性,如果不希望被外界直接访问,则可以将该属性私有化,该属性只能在当前类中被直接访问,如果在类的外面需要访问【获取或修改】,则可以通过暴露给外界的函数间接访问

封装的本质:将类中的属性进行私有化

【面试题】解释下面不同形式的变量出现在类中的意义
a:普通属性,也被称为公开属性,在类的外面可以直接访问             ****
_a:在类的外面可以直接访问,但是不建议使用,容易和私有属性混淆
__a:私有属性,只能在类的内部被直接访问。类的外面可以通过暴露给外界的函数访问    *****
__a__:在类的外面可以直接访问,但是不建议使用,因为系统属性和魔术方法都是这种形式的命名,
    如:__slots__  __init__  __new__  __del__,__name__,__add__,__sub__,__mul__等
# 封装的本质:将类中的属性进行私有化
'''
公开属性:可以在当前类之外的任何地方直接访问的属性
私有属性:只能在当前类中被直接访问的属性
'''
​
# 1.属性未被私有化
class Animal1():
    __slots__ = ('name','age')
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def show(self):
        print(self.name,self.age)
​
a1 = Animal1('大黄',3)
print(a1.name,a1.age)
a1.show()
​
a1.name = '小白'
​
print('*' * 30)
​
# 2.属性私有化     ******
# 作用:为了数据的安全性,不希望当前类以外的其他地方访问该属性
class Animal2():
    __slots__ = ('__name','__age')
    def __init__(self,name,age):
        # 当给对象动态绑定属性的时候,如果在属性名的前面添加两个下划线,则表示该属性被私有化了
        self.__name = name
        self.__age = age
    def show(self):
        print(self.__name,self.__age)
​
a2 = Animal2('大黄',3)
a2.show()
# print(a2.__name,a2.__age)  # AttributeError: 'Animal2' object has no attribute '__name'
​
print('*' * 30)
​
# 3.暴露给外界访问的函数
# a.
class Animal3():
    __slots__ = ('__name','__age')
    def __init__(self,name,age):
        self.__name = name
        self.__age = age
    def show(self):
        print(self.__name,self.__age)
​
    # 获取值
    def func1(self):
        return self.__name
    # 修改值
    def func2(self,a):
        self.__name = a
​
    def func3(self):
        return self.__age
    def func4(self,b):
        if b < 0:
            b = -b
        self.__age = b
​
a3 = Animal3('大黄',3)
a3.show()
print(a3.func1())
a3.func2('旺财')
print(a3.func1())
​
print(a3.func3())
a3.func4(-45)
print(a3.func3())
​
print('*' * 30)
​
# b.装饰器实现
class Animal3():
    __slots__ = ('__name','__age')
    def __init__(self,name,age):
        self.__name = name
        self.__age = age
    def show(self):
        print(self.__name,self.__age)
​
    # 获取值
    '''
    @property用来装饰获取私有化属性的函数,将该函数处理成属性使用
    '''
    @property
    def name(self):
        return self.__name
    # 修改值
    '''
     @xxx.setter用来装饰修改私有化属性的函数,将该函数处理成属性使用
     xxx:一定得是被@property装饰的函数名
     
     一般情况下,func1和func2这两处的函数名不会随意命名,建议命名为被私有化的属性的属性名
    '''
    @name.setter
    def name(self,name):
        self.__name = name
​
    @property
    def age(self):
        return self.__age
    @age.setter
    def age(self,age):
        if age < 0:
            age = -age
        self.age  = age
​
a3 = Animal3('大黄',3)
a3.show()
print(a3.name)  # 大黄,调用的是被@property装饰的函数,a3.func1获取的是原func1函数的返回值
# print(a3.func1())   # TypeError: 'str' object is not callable
​
# print(a3.func2)
a3.name = '旺财'   # 调用的是被@xxx.setter装饰的函数
# a3.func2('旺财')     # TypeError: 'str' object is not callable
print(a3.name)
2.继承

如果两个或者两个以上的类具有相同的属性和方法,我们可以抽取一个类出来,在抽取出来的类中声明各个类公共的部分

​ 被抽取出来的类——父类【father class】 超类【super class】 基类【base class】

​ 两个或两个以上的类——子类 派生类

​ 他们之间的关系——子类 继承自 父类 或者 父类 派生了 子类

简单来说,

一个子类只有一个父类,被称为单继承

一个子类有多个父类,被称为多继承

语法:
class 子类类名(父类类名):
    类体
class 子类类名(父类类名1,父类类名2.......):
    类体

注意:object是Python中所有类的根类

​
# 1.单继承
# 在Python中,object是所有类的根类
# 父类
class Person():  # 在此处的()中什么都不写,默认的父类仍然是object
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def show(self):
        print('showing')
​
# 子类
class Worker(Person):
    pass
# a.当子类中未定义__init__,则创建子类对象,默认会调用父类中的构造函数,所以要注意和父类中的__init__的参数匹配【子类继承了父类中的__init__】
# w = Worker()  # TypeError: __init__() missing 2 required positional arguments: 'name' and 'age'
w = Worker('小王',20)
print(w.name,w.age)
w.show()
​
class Student(Person):
    def study(self):
        print('study~~~~')
stu = Student('小明',19)
print(stu.name,stu.age)
stu.show()
stu.study()
​
# b.如果子类中定义了__init__函数,则创建子类对象,优先会调用子类中的__init__
class Doctor(Person):
    def __init__(self,name,age,kind):
        # 在子类的__init__中调用父类的__init__
        # 方式一:super(当前类,self).__init__(参数列表)
        # super(Doctor,self).__init__(name,age)
        # 方式二:super().__init__(参数列表)
        # super().__init__(name,age)
        # 方式三:父类类名.__init__(self,参数列表)
        Person.__init__(self,name,age)
​
        self.kind = kind
    def assist(self):
        print('assist~~~~')
​
# d = Doctor() # TypeError: __init__() missing 3 required positional arguments: 'name', 'age', and 'kind'
d = Doctor('王大夫',45,'外科')
print(d.kind)
# 当子类对象需要访问父类中提取出来的属性时,无法访问,解决方案:在子类的__init__中调用父类中的__init__
print(d.name,d.age)  # AttributeError: 'Doctor' object has no attribute 'name'
d.show()
d.assist()
​
# 2.多继承
# a
class Flyable():
    def fly(self):
        print('flying')
class Runable():
    def run(self):
        print('running')
class Bird(Flyable,Runable):
    pass
​
bird = Bird()
bird.fly()
bird.run()
​
# b.
# class FatherClass1():
#     def __init__(self,num):
#         self.num = num
#     def func(self):
#         print('11111')
#
# class FatherClass2():
#     def __init__(self,value):
#         self.value = value
#     def func(self):
#         print('2222')
#
# class SubClass(FatherClass1,FatherClass2):
#     pass
​
# 当一个类有多个父类,且子类中未定义构造函数,则创建子类对象,默认情况下调用的时父类列表中第一个父类中的__init__,多个父类中出现重名的函数也是这种原理
# sc = SubClass(45)
# sc.func()
​
# c
class FatherClass1():
    def __init__(self,num):
        self.num = num
    def func(self):
        print('11111')
​
class FatherClass2():
    def __init__(self,value):
        self.value = value
    def func(self):
        print('2222')
​
class SubClass(FatherClass1,FatherClass2):
    def __init__(self,num,value,a,b):
        # 在多继承中,在子类的__init__中调用父类的__init__,只能使用方式三,可以区分父类
        FatherClass1.__init__(self, num)
        FatherClass2.__init__(self, value)
        self.a = a
        self.b = b
​
sc = SubClass(34,6,7,8)
print(sc.a,sc.b)
print(sc.num,sc.value)

标签:__,封装,name,self,Day21,笔记,print,age,def
From: https://blog.csdn.net/m0_61388098/article/details/142306311

相关文章

  • MQ学习笔记(一)Kafka简介
    什么是MQ?MessageQueue消息队列,在消息的传递过程中保存消息的容器。父亲==》书架《==儿子好处:应用解耦,异步提速,限流削峰使用成本:引入复杂度,最终一致性,高可用性何时使用:生产者不需要从消费者处获得反馈能够容忍短暂的不一致性效果要大于副作用应用场景应用解耦场......
  • 龙芯+FreeRTOS+LVGL实战笔记(新)——08RGB闪烁灯
            本专栏是笔者另一个专栏《龙芯+RT-Thread+LVGL实战笔记》的姊妹篇,主要的区别在于实时操作系统的不同,章节的安排和任务的推进保持一致,并对源码做了完善与优化,各位可以先到本人主页下去浏览另一专栏的博客列表(目前已撰写36篇,图1所示),再决定是否订阅。此外,也可以前......
  • 小林coding学习笔记(内存页面置换算法)
    缺页中断示意图1在CPU里执行一条查找某个页面A的指令,首先是虚拟内存,会到虚拟内存和物理内存的映射关系的页表中查询。2页表中不存在需要查找的页面A的有效信息。3则触发缺页中断信号给操作系统,操作系统收到缺页中断信号后,就会去磁盘里面查找该页面。4操作系统在磁盘中查......
  • 408五级流水线强化课笔记
    408强化课录播五级流水线相关内容笔记指令流水线基本概念:简单的概念题指令流水线基本实现:指令按序发射,按序完成各种冒险:结合MIPS指令序列分析并处理冒险超标量和动态流水线:简单的概念题五级流水线五级流水线的设计是为了通过并行提高处理器的吞吐量。图片来自CSAPP。......
  • 小林coding学习笔记(进程调度算法)
    //进程调度算法进程调度算法是CPU通过进程调度算法决定某个时刻去调用哪个进程到CPU上运行的算法1、先来先服务调度算法每次从就绪队列的队头调度到CPU上运行,直到进程退出或被阻塞,才会继续从队列中调度进程运行。特点:对短作业不利,对长作业有利,无法平衡短作业与长作业。2、最......
  • 小林coding学习笔记(1)-2024.09.16
    HTTP版本的区别变化HTTP1.1相较于HTTP1.0,多了长连接,可以支持同一个HTTP会话的复用,避免了频繁的建立与关闭的资源开销。//SSL/TLS的建立过程-四次握手1、客户端Hello客户端发送1支持的TLS协议版本2一个随机数用于后续产生会话密钥3支持的密码套件,如非对称加密RSA算法2、服......
  • 苍穹外卖学习笔记(六)
    文章目录一.公共字段自动填充方法一:使用AOP切面编程方式方法二:使用mybatis-plus自带的公共字段自动填充二.新增菜品1.图片上传2.具体新增菜品三.菜品分页查询一.公共字段自动填充方法一:使用AOP切面编程方式自定义注解AutoFill,用于标识需要进行公共字段自动填......
  • 苍穹外卖学习笔记(七)
    四.删除菜品业务规则:可以一次删除一个菜品,也可以一次删除多个菜品起售中的菜品不能删除被套餐关联得菜品不能删除删除菜品后,关联得口味数据也需要删除掉一共需要操作三个表,注意加@Transactional事物注解Controller/***删除菜品*/@DeleteMapping......
  • 前端工程化学习笔记-02(webpack基础用法)
    前端工程化学习笔记-02(webpack基础用法)webpack基础用法快速搭建一个简易的webpack项目使用npminit初始化一个项目;mkdirwebpack-democdwebpack-demonpminit-y本地安装webpack;npminstallwebpackwebpack-cli--save-dev修改package.json文件#删除"main"......
  • 用笔记来记录遇到的问题:发布版本和非发布版本遇到的问题
    这两天接到一个任务,把中秋节的的宣传广告发到app上去。没想到一个项目运营了这么久,竟然没有这种功能我给他们做了3个:开屏广告、首页弹出广告和客服机器人形象换成小兔子。搞完之后,我发布版本给他们测试谁知道我本地运行得好好的,为啥发布给他们的版本没有效果!我震惊了,以为我......