day11
一、类的跨类调用
需求:用面向对象的方式描述“老张开车去东北”。
题目分析:老张与车彼此有行为,所以需要构建两个类。
构建类的原因:(1)需要承担行为(2)需要封装数据
共有三种跨类调用的方式:
1、直接创建对象
# 语义: 老张每次去东北都用一辆新车
class Person:
def __init__(self, name=""):
self.name = name
def go_to(self, position):
print("去" + position)
car = Car()
car.run()
class Car:
def run(self):
print("汽车在行驶")
lz = Person("老张")
lz.go_to("东北")
2、构造函数创建对象
# 语义:老张每次开自己的车去东北
class Person:
def __init__(self, name=""): # 创建对象时执行1次
self.name = name
self.car = Car()
def go_to(self, position):
print("去" + position)
self.car.run()
class Car:
def run(self):
print("汽车在行驶")
lz = Person("老张")
lz.go_to("东北")
3、通过参数传递对象
优势:不将Person和Car绑死,代码更灵活
# 语义:老张每次用交通工具去东北
class Person:
def __init__(self, name=""):
self.name = name
def go_to(self, vehicle, position):
print("去" + position)
vehicle.run()
class Car:
def run(self):
print("汽车在行驶")
lz = Person("老张")
bc = Car()
lz.go_to(bc, "东北")
二、类变量与类方法
类变量:在类内使用的变量,使用类名来访问。
对比实例变量:用实例来访问。
类方法:操作类变量的方法
class ICBC:
total_money = 1000000 # 类变量
@classmethod # 类方法
def print_total_money(cls):
# print("总行的钱",ICBC.total_money)
# cls 存储的就是类地址,与类名相同,通常命名短于类名,所以建议使用
print("总行的钱", cls.total_money)
def __init__(self, name="", money=0):
# 实例变量:对象不同的数据
self.name = name
# 支行的钱
self.money = money
# 总行的钱减少
ICBC.total_money -= self.money
tt = ICBC("天坛支行", 100000)
ICBC.print_total_money()
xd = ICBC("西单支行", 200000)
ICBC.print_total_money()
三、Python语言所有变量的小结
# 全局变量:整个文件可用
a = 10
def func01():
# 局部变量:一个函数内部可用
b = 20
class Myclass:
# 类变量:使用类名访问
d = 40
def __init__(self):
# 实例变量:使用对象访问
self.c = 30
m01 = Myclass()
print(m01.c)
print(Myclass.d)
四、私有成员
1、语法: 开头用两个下划线命名
class MyClass:
def __init__(self):
# 私有实例变量
self.__data = 10
def __func01(self):
print("func01")
def func02(self):
print(self.__data)
self.__func01()
m01 = MyClass()
# print(m01.__data)
# m01.__func01()
m01.func02()
print(m01.__dict__) # {'_MyClass__data': 10}
2、作用:类外无法访问
3、原理:障眼法
表面:__data
实际:_MyClass__data
五、属性
1、原理
作用:保护实例变量取值在有效范围内
步骤:
(1)私有化实例变量
(2)提供公开的读取方法
(3)提供公开的写入方法
定义:
@property
def 属性名(self):
return self.__属性名
@属性名.setter
def 属性名(self,value):
self.__属性名= value
2、过渡版本
# 过渡版本
class Wife:
def __init__(self, name="", age=0):
self.name = name
# self.__age = age
self.set_age(age)
def get_age(self):
return self.__age
def set_age(self, value):
if value < 0:
value = 0
elif value > 120:
value = 120
self.__age = value
# 年龄:0~120
ak = Wife("阿珂", 999)
print(ak.name)
print(ak.get_age())
3、最终版本
class Wife:
def __init__(self, name="", age=0):
self.name = name
self.age = age # 本身是实例变量 现在变为属性了
@property # age = property(age) 读
def age(self):
return self.__age
@age.setter # age = age.setter(age) 改
def age(self, value):
if value < 0:
value = 0
elif value > 120:
value = 120
self.__age = value
# 年龄:0~120
ak = Wife("阿珂", 999)
ak.age = 8889
print(ak.age)