面向对象
面向对象的特点
- 面相对想的三大特性:封装、继承、多态
封装
- 通俗理解:把属性和方法放到类里面的操作可以认为是封装,封装还可以控制属性和方法的访问权限,比如:把方法改成私有的。
- 将数据及相关操作打包在一起;
- 支持代码复用。
继承
- 定义:子类(subclass)借用父类(superclass)的行为。子类继承父类,可以直接使用父类的属性或者方法。
- 只能继承公有属性和公有方法,一个子类可以继承多个父类,但是父类的方法、属性重复时,只能继承第一个父类中的方法、属性(具体看多继承、多层继承)。
- 子类继承父类的原因:
- 需要使用父类里面的属性或者方法。
- 避免重复操作,提升代码复用程度。
- 子类也称为派生类,父类也称为是基类。
当父类的功能方法满足不了子类的需要,子类还可以重写父类方法。
# 语法
class ClassName(SuperClassName): # ClassName相对于父类来说是子类或者派生类
# 属性
# 方法
例
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def show(self):
print(self.name, self.age)
def show_info(self):
print("我是人类类")
# 相对于Person类来说,Student类就是子类,Person类就是父类
class Student(Person): # 小括号里面放的都是父类,只写一个父类的是单继承
def show_info(self):
print("我是学生类")
# 创建学生(字类)对象
student = Student("李四", 20)
student.show() # 调用继承自父类的方法
student.show_info() # 调用自己的方法,父类和字类都有的方法,优先使用自己的(即:重写了父类方法)
单继承
- 定义:子类只继承一个父类的继承叫单继承。
- 总结:子类继承父类,子类里面没有的方法可以使用父类的方法,如果子类也提供了和父类相同的方法,那么使用就是子类的方法(即优先使用子类自己的方法)。
- 案例:看继承的案例(上面那个)即可。
多继承
- 定义:子类可以继承多个父类,可以使用多个父类里面的属性或者方法。
- 提示:子类继承多个父类,多个父类放到小括号里面,父类直接使用逗号“
,
”进行分割。 - 扩展:获取类继承顺序,
类名.mro()
,返回列表。- 类的继承顺序决定了到底使用哪个方法。
- 注意:
- 先在当前类里面查找对应要使用的方法,如果当前类没有,然后会在类继承顺序中的下一个类进行查找。
- 如果找到了就会使用该方法,如果在类继承顺序中都没有找到要调用的方法,那么会崩溃。
# 定义动物类
class Animal(object):
def eat(self):
print("动物正在吃食物")
def sleep(self):
print("动物正在睡觉")
# 定义鱼类
class Fish(object):
def swim(self):
print("鱼儿正在愉快的游泳")
def sleep(self):
print("鱼儿正在睡觉")
# 定义鲨鱼类
class Shark(Fish, Animal):
def attack(self):
print("鲨鱼正在攻击其他鱼类")
# 创建鲨鱼对象
shark = Shark()
shark.attack() # 调用自己的方法
shark.swim() # 调用父类Fish的方法
shark.eat() # 调用父类Animal的方法
# 获取Shark类的类继承顺序
result = Shark.mro()
print(result)
# [<class '__main__.Shark'>, <class '__main__.Fish'>, <class '__main__.Animal'>, <class 'object'>]
# 在Flash和Animal中都有sleep,但是继承顺序Fish在前,所以使用Fish中的slee方法
shark.sleep()
# 找了一圈都没有kill方法,报错
# shark.kill()
多层继承
- 多个层级的继承关系,子类可以使用多个层级关系类的方法和者属性。
# 爷爷类
class GrandFather(object):
def open_flower_shop(self):
print("开花店")
# 爸爸类
class Father(GrandFather):
def open_hotel(self):
print("开酒店")
# 儿子类
class Son(Father):
def open_factory(self):
print("开厂子")
def open_big_hotel(self):
# 需要调用父类的开酒店方法
Father.open_hotel(self) # 记得类调用方法需要手动写self
print("开大酒店")
son = Son()
son.open_hotel()
son.open_flower_shop()
son.open_factory()
son.open_big_hotel()
print(Son.mro())
# [<class '__main__.Son'>, <class '__main__.Father'>, <class '__main__.GrandFather'>, <type 'object'>]