一、类
类的定于语法:
class 类名称:
类属性(字段)
类行为(函数)
创建类对象的语法:
对象 = 类名称()
python
"""
学生类
"""
import json
# 定义一个学生类
class Student:
name = None # 姓名
gender = None # 性别
nationality = None # 国籍
native_place = None # 籍贯
age = None # 年龄
# 创建一个对象
stu = Student()
stu.name = '张三'
stu.gender = '男'
stu.nationality = '中国'
stu.native_place = '北京'
stu.age = 30
# 获取对象内的信息
stu_str = json.dumps(stu.__dict__, ensure_ascii=False)
print(stu_str)
1.1 类的成员方法
python
class Student:
name = None # 姓名
gender = None # 性别
nationality = None # 国籍
native_place = None # 籍贯
age = None # 年龄
# 无参方法
def say_hi(self):
print(f'Hi, 我是{self.name}')
# 有参方法
def say(self, msg):
print(f'大家好,我叫{self.name},{msg}')
stu = Student()
stu.name = '坤坤'
stu.gender = '男'
stu.nationality = '中国'
stu.native_place = '北京'
stu.age = 30
# 调用类方法
stu.say_hi()
stu.say('我喜欢,唱,跳,rap,篮球')
1.2 构造方法
类的构造方法作用:
- 创建类对象的时候,构造方法会自动执行
- 创建类对象的时候,将传入参数自动传递给
__init__
方法使用
python
class Student:
# 构造函数内声明成员变量,不需要再定义成员变量
def __init__(self, name, age, tel):
self.name = name
self.age = age
self.tel = tel
def print_info(self):
print(f'姓名:{self.name}, 年龄:{self.age},电话:{self.tel}')
s = Student('张三', 19, '12345678910')
s.print_info()
s1 = Student('李四', 22, '12345678911')
s1.print_info()
1.3 练习题
开学了有一批学生信息需要录入系统,请设计一个类,记录学生的:姓名、年龄、地址,这3类信息
请实现:
- 通过for循环,配合input输入语句,并使用构造方法,完成学生信息的键盘录入
- 使用print语句,完成信息的输出
python
class Stud:
def __init__(self, idx, name, age, address):
self.idx = idx
self.name = name
self.age = age
self.address = address
# 打印学生的信息
def print_info(self):
print(f'学生信息{self.idx}录入完成,信息为【姓名:{self.name},'
f' 年龄:{self.age},地址:{self.address}】')
# 输入学生的信息
def trigger():
for i in range(1, 3):
name = input('请输入学生姓名:')
age = input('请输入学生年龄:')
address = input('请输入学生地址:')
stud = Stud(i, name, age, address)
stud.print_info()
if __name__ == '__main__':
trigger()
1.4 魔术方法(内置方法)
上文中
__init__
方法就是 python 内置方法之一,这些内置方法各自有各自的特殊功能,统称为:魔术方法
__init__
构造方法__str__
字符串方法__lt__
小于,大于符号比较__le__
小于等于,大于等于符号比较__eq__
==
比较符号
python
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
# 对象的 tostring 方法
def __str__(self):
return f'对象to string, name:{self.name}, age:{self.age}'
# 比较函数定义
def __lt__(self, other):
return self.age < other.age
# 小于等于
def __le__(self, other):
return self.age <= other.age
# equals 方法,不实现则是比较内存地址
def __eq__(self, other):
return (self.name == other.name
and self.age == other.age)
st1 = Student('张三', 32)
print(f"对象1:{st1}") # 对象1:对象to string, name:张三, age:32
st2 = Student('张三', 32)
print(f"对象2:{st2}") # 对象2:对象to string, name:张三, age:32
print(f'st1 < st2: {st1 < st2}') # st1 < st2: False
print(f'st1 <= st2: {st1 <= st2}') # st1 <= st2: True
print(f'st1 == st2: {st1 == st2}') # st1 == st2: True
二、面向对象的三大特性
2.1 封装
封装:将现实世界事物在类中描述为属性和方法,即为封装
私有的变量,方法定义规则:
__
两个下划线开头的定义为私有的
python
"""
演示私有变量和私有方法的访问限制
"""
class Phone:
# 私有成员
__current_voltage = None
# 私有方法
def __keep_single_core(self):
a = self.__current_voltage
print(f'CPU以单核运行, 当前电压:{a}...')
p = Phone()
# 这里调用对象的私有方法会报错
# 'Phone' object has no attribute '__keep_single_core'. Did you mean: '_Phone__keep_single_core'?
p.__keep_single_core()
python
"""
私有变量和私有方法的正确访问姿势
私有的函数并非是不能使用,而是在 class 外部不能使用,但是在 class 内部可以被使用
如下案例中:call_by_5g 函数调用了私有方法 __keep_single_core,实现了在 class 内部调用
"""
class Phone:
__current_voltage = 0.5
def __init__(self, cv):
self.__current_voltage = cv
def __keep_single_core(self):
a = self.__current_voltage
print(f'CPU以单核运行, 当前电压:{a}...')
def call_by_5g(self):
if self.__current_voltage > 3.5:
print('5g通话开启')
else:
self.__keep_single_core()
print('电压不足,无法开启5g,并使用单核运行 ...')
p = Phone(3)
p.call_by_5g()
综合案例
设计一个手机类,内部包含:
私有成员变量:
__is_5g_enable
,类型bool
,True
表示开启5g
,False
表示关闭5g
私有成员方法:
__check_5g()
,会判断私有成员__is_5g_enable
的值
- 若为
True
,打印输出:5g开启
- 若为
False
,打印输出:5g关闭,使用4g网络
公开成员方法:
call_by_5g()
,调用它会执行
- 调用私有成员方法:
__check_5g()
,判断5g
网络状态- 打印输出: 正在通话中
运行结果:
5g关闭,使用4g网络
正在通话中
python
class Phone:
# True表示开启5g,False表示关闭5g
__is_5g_enable = None
def __init__(self, enable):
self.__is_5g_enable = enable
def __check_5g(self):
if self.__is_5g_enable:
print('5g开启')
else:
print('5g关闭,使用4g网络')
def call_by_5g(self):
self.__check_5g()
print('正在通话中')
p = Phone(False)
p.call_by_5g()
2.2 继承
单继承
语法:class 类名(父类名):
python
# Phone2021 2021年的手机,只支持 4g 通话
class Phone2021:
IMEI = None
product = None
def __init__(self, IMEI, product):
self.IMEI = IMEI
self.product = product
def call_by_4g(self):
print(f'Phone2021 4g 通话, {self.IMEI}')
# 单继承
# Phone2022 2022年的手机,继承了2021年的手机
# 新增了人脸识别 和 5g 通话
class Phone2022(Phone2021):
face_id = True
def __init__(self, face_id, IMEI, product):
super().__init__(IMEI, product)
self.face_id = face_id
def call_by_5g(self):
print(f'Phone2022 支持 5g 通话:{self.face_id}')
p = Phone2022(face_id='zyred', IMEI='AKJL23KHH2', product='苹果')
p.call_by_4g()
p.call_by_5g()
多继承
语法:class 类名(父类名1,父类名2, ...):
python
class Phone:
IMEI = '100000'
producer = None
def __init__(self, IMEI, producer):
self.IMEI = IMEI
self.producer = producer
def call(self):
print(f'{self.producer}: 开始打电话')
class NFC:
nfc_type = '第五代'
producer = 'GM'
def read_card(self):
print(f'{self.nfc_type} 读卡')
def write_card(self):
print(f'{self.nfc_type} 写卡')
class RemoteControl:
rc_type = '红外遥控'
def control(self):
print(f'{self.rc_type} 开启')
class MyPhone(Phone, NFC, RemoteControl):
# 补全语法,不发生错误
pass
mf = MyPhone('100000', '苹果')
mf.control()
mf.call()
mf.read_card()
mf.write_card()
# 多继承相同属性名,那个类继承在前面,哪个的优先级高
print(f'多继承相同属性名的内容:{mf.producer}') # 输出 "苹果"
重写父类的方法和成员属性
python
class Phone:
IMEI = '100000'
producer = '苹果'
def call(self):
print(f'{self.IMEI}: 开始打电话')
class MyPhone(Phone):
# 重写父类的属性
producer = '华为'
# 重写父类的 call 方法
def call(self):
print(f'开启单核CPU工作 ...')
print(f'访问父类的属性:{Phone.producer}')
# 调用父类的方法,方式1
Phone.call(self)
# 调用父类的方法,方式2
super().call()
print(f'关闭单核CPU工作 ...')
mf = MyPhone()
mf.call()
"""
开启单核CPU工作 ...
访问父类的属性:苹果
100000: 开始打电话
100000: 开始打电话
关闭单核CPU工作 ...
"""
2.3 多态
父类引用指向子类对象
python
class Animal:
# 定义一个没有任何实现的方法
def speak(self):
pass
class Cat(Animal):
def speak(self):
print('喵喵喵')
class Dog(Animal):
def speak(self):
print('汪汪汪')
# 定义一个方法,传入 Animal 抽象类
# 并且调用 animal 的抽象方法
def make_nise(animal: Animal):
animal.speak()
d: Animal = Dog()
c: Animal = Cat()
make_nise(d)
make_nise(c)
python
class AC:
def cool_wind(self):
"""制冷"""
pass
def hot_wind(self):
"""制热"""
pass
def swing_l_r(self):
"""左右摆风"""
pass
# 美的空调
class Midea_AC(AC):
def cool_wind(self):
print('美的,制冷就是爽')
def hot_wind(self):
print('美的,制热就是快')
def swing_l_r(self):
print('美的,左右无感摆风')
# 格力空调
class GREE_AC(AC):
def cool_wind(self):
print('格力,制冷就是爽')
def hot_wind(self):
print('格力,制热就是快')
def swing_l_r(self):
print('格力,左右无感摆风')
def make_cool(ac: AC):
ac.cool_wind()
ac.hot_wind()
ac.swing_l_r()
midea: AC = Midea_AC()
gree: AC = GREE_AC()
make_cool(midea)
make_cool(gree)
"""
美的,制冷就是爽
美的,制热就是快
美的,左右无感摆风
格力,制冷就是爽
格力,制热就是快
格力,左右无感摆风
"""