封装、继承、多态是面向对象的三大特征
命名:
class Person:
"""类:人"""
def __init__(self, name, action):
self.name = name
self.__action = action
私有属性方法:
私有属性赋值:
def set_action(self, action):
"""设置私有属性action"""
self.__action = action
# 也有写成双下划线的(一般用单下划线):
def set__action(self, action):
"""设置私有属性action"""
self.__action = action
获取私有属性数据:
def get_action(self):
"""获取私有属性action"""
return self.__action
# 双下划线写法(一般用单下划线)
def get__action(self):
"""获取私有属性action"""
return self.__action
外部需要通过set和get方法调用私有属性:
class Person:
"""类:人"""
def __init__(self, name, action):
self.name = name
self.__action = action
def set_action(self, action):
"""设置私有属性action"""
self.__action = action
def get_action(self):
"""获取私有属性action"""
return self.__action
# 创建对象
an = Person("安禄山", "叛乱")
# print(an.action) # name 'action' is not defined # 私有属性不能直接访问,会报错
print(an.get_action()) # 叛乱 # 通过get方法获取
an.set_action("胡旋舞") # 修改私有属性
print(an.get_action()) # 胡旋舞
# 用以下方法修改并不能修改原私有属性,只是新增了一个属性
an.__action = "跳舞"
print(an.get_action()) # 胡旋舞 # 属性值没有改变
set方法与__init__区别:
在set/get方法中添加条件限制
def set_action(self, action):
if 2 <= len(action) <= 10:
self.__action = action
else:
print("长度不符合要求")
def get_action(self, action):
return __action
def __test():
pass
通过继承语法,让两个类型之间产生继承关系,子类可以使用父类的属性和方法,达到复用目的
父类和子类:
- class 子类(父类)
class Person(object):
"""人的类"""
pass
class Emperor(Person):
"""皇帝的类"""
pass
调用父类的__init__():
# 单继承时是三种写法都可以
# __init__()中需要传递父类相应参数,不需带self
super().__init__()
父类名称.__init__() (多继承用此写法)
super(子类名称, self).__init__() # 子类名称即当前类名
子类不写__init__()方法默认继承父类的__init__()方:
class Person(object):
"""人的类"""
def __init__(self, name, position):
"""初始化类型"""
self.name = name
self.position = position
class Emperor(Person):
"""皇帝的类"""
pass
# 子类不写__init__()方法默认继承父类
li = Emperor("李隆基", "皇帝")
子类中写的__init__()方法中,都会显式的调用父类的__init__(),初始化父类数数据,否则父类的数据就不会被 正确的继承过来:
```python
class Person(object):
"""人的类"""
def __init__(self, name, position):
"""初始化类型"""
self.name = name
self.position = position
class Emperor(Person):
"""皇帝的类"""
def __init__(self, name, position, gender):
super().__init__(name, position) # 主动调用父类__init__(),单继承时三种写法皆可,不需带self
self.gender = gender # 写新增的
# 创建子类对象按照子类的的属性
li = Emperor("李隆基", "皇帝", "男")
即子类中重新声明定义了和父类中名称和参数相同的方法
class Person(object):
"""人的类"""
def run(self):
print("逃跑")
class Emperor(Person):
"""皇帝的类"""
pass
# 创建对象
li = Emperor()
# 没有重新的方法,则使用父类的方法
li.run() # 逃跑
class Person(object):
"""人的类"""
def run(self):
print("逃跑")
class Emperor(Person):
"""皇帝的类"""
# 重写父类方法
def run(self):
print("九重城阙烟尘生,千乘万骑西南行")
# 创建对象
li = Emperor()
# 方法被重写,使用子类方法
li.run() # 九重城阙烟尘生,千乘万骑西南行
三种访问形式:
super().方法名称()
super(子类名称, self).方法名称() # 子类名称即当前类名
父类名称.方法名称() # 注意是否需要带参数self,另外两种方法不需带
class Person(object):
"""宫殿类"""
def dream(self):
print("做梦")
class Emperor(Person):
"""皇帝的类"""
# 重写父类方法
def dream(self):
super().dream() # 访问类方法,并拓展功能
print("鸳鸯瓦冷霜华重,翡翠衾寒谁与共?")
print("悠悠生死别经年,魂魄不曾来入梦。")
# 创建对象
li = Emperor()
# 方法被重写,且在父类基础上拓展
li.dream()
# 做梦
# 鸳鸯瓦冷霜华重,翡翠衾寒谁与共?
# 悠悠生死别经年,魂魄不曾来入梦。
class Flower:
def test(self):
print("芙蓉如面柳如眉")
def open(self):
print("春风桃李花开夜")
class Tree:
def test(self):
print("对此如何不泪垂")
def leaf(self):
print("秋雨梧桐叶落时")
class Plant(Flower, Tree):
pass
plant = Plant()
# 继承所有类型的公共属性和方法
plant.open() # 春风桃李花开夜
plant.leaf() # 秋雨梧桐叶落时
# 方法重名按继承顺序查找
plant.test() # 芙蓉如面柳如眉
class Plant:
def shape(self):
print("不同的东西的不同状态")
def desc(self):
self.shape()
class Hibiscus(Plant):
def shape(self):
print("芙蓉如面柳如眉")
class PeachBlossom(Plant):
def shape(self):
print("春风桃李花开夜")
class ChineseParasol(Plant):
def shape(self):
print("秋雨梧桐叶落时")
# 根据不同对象调用对象里的继承的同名方法,但结果不同(类似策略模式)
plant = Plant()
plant.desc() # 不同的东西的不同状态
flower = Hibiscus()
flower.desc() # 芙蓉如面柳如眉
flower2 = PeachBlossom()
flower2.desc() # 春风桃李花开夜
tree = ChineseParasol()
tree.desc() # 秋雨梧桐叶落时