目录
知识点
封装 (PART 1)
- 定义: 封装是将数据(属性)和行为(方法)组合在一起的过程,通常封装在类中。
- 目的: 保护数据不被外部直接访问和修改,提高程序的安全性和可维护性。
- 类和对象:
- 类变量和实例变量:类变量属于类,所有实例共享;实例变量属于对象实例。
- 实例方法和类方法:实例方法可以访问和修改实例变量,类方法属于类本身。
- 构造器: 使用
__init__
方法初始化实例变量。- _fun:protected 类本身和子类可以访问 可以通过实例名访问
- _ _fun:private 类本身可以访问 不可以通过实例名访问
- _ _fun_ _:系统 __init__
- 私有属性: 通过两个下划线前缀定义私有属性,只能在类内部访问。
- print(p._Person__name) #在外访问私有属性
- 间接访问方法:
- 使用getter和setter方法间接访问私有属性。
- 为了更好的保存属性安全,即不能随意修改,一般的处理方式为: 将属性定义为私有属性(以两个下划线开头) 添加方法,间接访问私有变量。
- 说明: python 私有属性只能在类内部访问,类外面访问会出错。 python 保护属性更多的是一种语法上的标识,用来提醒直接修改改对象时候要小心
- 使用
@property
装饰器简化属性访问,提供属性值的获取和设置功能。- 作用:在新式类中返回属性值。
- 语法:class property([fget[, fset[, fdel[, doc]]]])
- fget -- 获取属性值的函数
- fset -- 设置属性值的函数
- fdel -- 删除属性值函数
- doc -- 属性描述信息
- 第一个参数是方法名,调用 对象.属性 时自动触发执行方法
- 第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法
- 第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法
- 第四个参数是字符串,调用 对象.属性.doc ,此参数是该属性的描述信息
- 功能是:property属性内部进行一系列的逻辑计算,最终返回计算结果。
- property属性的有两种方式:
- 类属性方式,创建值为property对象的类属性
- 在类的实例方法上应用@property装饰器
- @property 修饰获取的方法getter, 方法名必须和属性名一样
- @XXX.setter 修饰设置值的方法setter, 方法名必须和属性名一样
- 使用getter和setter方法间接访问私有属性。
- 私有方法:
- Python默认的成员函数和成员变量都是公开的。
- 在变量名或函数名前加上 “_ _"两个下划线,那么这个函数或变量就会为私有的了。
- 私有方法,不能在类的外部调用。但可以在类内部访问私有方法。
继承 (PART 2)
- 定义: 继承允许一个类(子类)继承另一个类(父类)的属性和方法。
- 单继承: 子类只继承一个父类。
- class 派生类名(基类名): 类体
- 在继承中,基类的构造方法(__init__()方法)不会被自动调用,它需要在其子类的构造方法中专门调用。
- 如果需要在子类中调用基类的方法,可以使用内置函数super()或者通过“基类名.方法名(参数)”的方式来实现。
- 多继承: 子类可以继承多个父类,方法查找顺序为从左到右。
- class 派生类名(基类1, 基类2,...., 基类n): 类体
- 需要注意圆括号中父类的顺序,若父类中有相同的方法名,在子类使用时未指定,Python会从左到右进行搜索。即若某个方法在子类中没有定义,则子类从左到右查找各个父类中是否包含这个方法。(即自己没有,看看父亲有没有)
- Python是动态语言,无法像静态语言那样根据参数的不同实现重载,所以在Python中,只要方法名相同就认为是同一个方法,先继承的父类同名方法会覆盖后继承的父类同名方法。
- 重写: 子类可以重写父类的方法,以实现不同的行为。子类会覆盖父类中同名且参数、返回类型都相同的方法。又称方法覆盖。
- super()函数: 用于在子类中调用父类的方法。
- 方法重载: Python不支持传统意义上的方法重载,但可以通过其他方式实现类似效果。在一个类下面有很多同名函数,但是这些函数的参数以及返回类型都不同。 python语法上不支持重载。
- 重载为解决: 可变参数类型 可变参数个数
- 这些python本身就支持,不需要重载。
重载和重写的区别:
重写(overiding method)指子类会覆盖父类中同名且参数、返回类型都相同的方法。又称方法覆盖。
重载(overloading method)指的就是在一个类下面有很多同名函数,但是这些函数的参数以及返回类型都不同。 python语法上不支持重载。
多态 (PART 3)
- 定义: 多态是指允许不同类的对象对同一消息做出响应,但具体方法的实现会根据对象的实际类型而有所不同。
- 应用场景: 多态可以在有继承关系或无继承关系的类之间实现。
- Python多态特点:
- 方法调用时只关注名称,不关注类型。只关心对象的实例方法是否同名,不关心对象所属的类型
- 继承关系不是必需的。对象所属的类之间,继承关系可有可无
- 提高代码的灵活性和通用性。
- 多态是调用方法的技巧,不会影响到类的内部设计。
- 拓展:Java中多态性的表现: 多态性,可以理解为一个事物的多种形态。同样python中也支持多态,但是是有限的的支持多态性,主要是因为python中变量的使用不用声明,所以不存在父类引用指向子类对象的多态体现。在python中多态的使用不如Java中那么明显,所以python中刻意谈到多态的意义不是特别大。
- 派生:派生就是子类在继承父类的基础上衍生出新的属性,重新定义的这些属性不会影响到父类。子类中独有的,父类中没有的;或子类定义与父类重名的东西。子类也叫派生类。
- 需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了
动态性 (PART 4)
- Python的动态性: 可以动态地添加和修改类和对象的属性和方法。
__slots__
: 用于限制实例的属性,提高内存效率。只对类的实例起作用。并不限制通过类来动态添加属性或方法,对该类派生出来的子类也不起作用。type()
函数: 可以用于查看类型或动态创建类。- type(obj) type
- (name, bases, dict)
- 第一种语法格式用来查看某个变量(类对象)的具体类型。 第二种语法格式用来创建类,其中 name 表示类的名称;bases 表示一个元组,其中存储的是该类的父类;dict 表示一个字典,用于表示类内定义的属性或者方法。
- 元类(metaclass): 是
type
的子类,可以控制类的创建过程,是一个高级特性。通过替换 type的__call__运算符重载机制,“超越变形”正常的类。
小结
- 强调了Python中一切皆对象,包括类和实例。类型(类,新的版本中类和类型是一样的)对象:可以被实例化和继承 非类型(实例)对象:不可以被实例和继承
- 介绍了类和实例之间的关系,以及
__class__
和__bases__
属性。 - 面向对象体系中的两种关系:
- 继承关系 类和实例之间关系
- 一个python对象可能拥有两个属性,__class__ 和 __bases__,__class__ 表示这个对象是谁创建的,__bases__ 表示一个类的父类是谁们。__class__和type()函数效果一样。
- type为对象的顶点,所有对象都创建自type。
- object为类继承的顶点,所有类都继承自object。
知识拓展
- 鸭子类型: 一种编程理念,即“如果它看起来像鸭子,游起来像鸭子,那么它可能就是鸭子”,关注行为而非类型。
实验
- 实验目的:
- 了解如何使用封装保护属性
- 了解多态的性质及作用
- 掌握单继承的使用
- 掌握方法重写的使用
- 实验内容:
- (基础题)
定义一个员工类Worker,私有属性:__sal(工资),拥有的方法有:
1)获取员工的工资:get_sal()
2)修改员工的工资:set_sal()
5)显示员工信息(工号,姓名,工种,工资):mess()
请编写程序,输出如下内容。
用3种方式:get\set方法、property类属性和装饰器,实现访问私有属性:__sal。
程序代码:
class Worker:
def __init__(self, worker_id, name, job, sal):
self.worker_id = worker_id
self.name = name
self.job = job
self.__sal = sal # 私有属性
def get_sal(self):
return self.__sal
def set_sal(self, sal):
self.__sal = sal
def mess(self):
print(f"工号:{self.worker_id}, 姓名:{self.name}, 工种:{self.job}, 工资:{self.__sal}")
# 使用get和set方法访问私有属性
worker1 = Worker("001", "张三", "工程师", 5000)
print(worker1.get_sal()) # 获取工资
worker1.set_sal(6000) # 修改工资
worker1.mess() # 显示员工信息
# 使用property类属性和装饰器访问私有属性
class Worker:
def __init__(self, worker_id, name, job, sal):
self.worker_id = worker_id
self.name = name
self.job = job
self.__sal = sal
@property
def sal(self):
return self.__sal
@sal.setter
def sal(self, value):
self.__sal = value
def mess(self):
print(f"工号:{self.worker_id}, 姓名:{self.name}, 工种:{self.job}, 工资:{self.sal}")
worker2 = Worker("002", "李四", "设计师", 5000)
print(worker2.sal) # 使用@property装饰器获取工资
worker2.sal = 6000 # 使用@property装饰器设置工资
worker2.mess() # 显示员工信息
- (基础题)
定义交通工具、汽车、火车、飞机这些类,注意它们的继承关系,为这些类提供构造器。
程序代码:
class Vehicle:
def __init__(self, brand, num_wheels):
self.brand = brand
self.num_wheels = num_wheels
class Car(Vehicle):
def __init__(self, brand, num_wheels, model):
super().__init__(brand, num_wheels)
self.model = model
class Train(Vehicle):
def __init__(self, brand, num_wheels, num_carriages):
super().__init__(brand, num_wheels)
self.num_carriages = num_carriages
class Airplane(Vehicle):
def __init__(self, brand, num_wheels, max_passengers):
super().__init__(brand, num_wheels)
self.max_passengers = max_passengers
# 示例
car = Car("Toyota", 4, "Corolla")
train = Train("China Railway", num_wheels=8, num_carriages=10)
airplane = Airplane("Boeing", 2, max_passengers=200)
- (基础题)
- 创建Person类,属性有姓名、年龄、性别,建立方法personInfo,打印这个人的信息。
- 创建Teacher类,继承Person类,属性有学院college,专业professional,重写父类personInfo方法,调用父类方法打印个人信息外,将老师的学院、专业信息也打印出来。建立teachObj方法,返回该教师所授的专业。
- 创建Student类,继承Person类,属性有学院college,班级class,重写父类personInfo方法,调用父类方法打印个人信息外,将学生的学院、班级信息也打印出来,创建方法study(参数为Teacher对象,调用Teacher类的teachObj方法,接收老师教授的知识点,然后打印‘X老师,***,我终于学会了!’,其中,X为老师的姓氏(假设是单姓),***为老师的teachObj方法返回的信息。
- 创建三个学生对象,分别打印其详细信息
- 创建一个老师对象,打印其详细信息
- 学生对象调用study方法
- 将三个学员添加至列表stu中,通过循环将列表中的对象打印出来,(stu[i].personInfo())。
程序代码:
class Person:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def personInfo(self):
print(f"姓名:{self.name}, 年龄:{self.age}, 性别:{self.gender}")
class Teacher(Person):
def __init__(self, name, age, gender, college, professional):
super().__init__(name, age, gender)
self.college = college
self.professional = professional
def personInfo(self):
super().personInfo()
print(f"学院:{self.college}, 专业:{self.professional}")
def teachObj(self):
return self.professional
# 示例
teacher = Teacher("王老师", 40, "男", "计算机学院", "人工智能")
teacher.personInfo()
print(teacher.teachObj())
抬走!下一位!!!
标签:__,10,sal,python,self,多态,父类,方法,属性 From: https://blog.csdn.net/wumingzei/article/details/140372538