面向对象编程的三大特性
封装
根据职责将属性和方法封装到一个抽象的类中
继承
实现代码的重用,相同的代码不需要重复的编写
多态
不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活度
单继承
子类拥有父类及父类的父类的的所有属性和方法
基础概念
子类/牌派生类、父类/基类、继承/派生
class Animal:
def eat(self):
print("吃")
def drink(self):
print("喝")
def run(self):
print("跑")
def sleep(self):
print("睡")
class Dog(Animal):
# 子类拥有父类的所有属性和方法
def bark(self):
print("汪汪叫")
# 创建一个对象 - 狗对象
wangcai = Dog()
wangcai.eat()
wangcai.drink()
wangcai.run()
wangcai.sleep()
wangcai.bark()
方法的重写
当父类的方法实现不能满足子类需求时,可以对方法进行重写
覆盖父类的方法
class Animal:
def eat(self):
print("吃")
def drink(self):
print("喝")
def run(self):
print("跑")
def sleep(self):
print("睡")
class Dog(Animal):
def bark(self):
print("汪汪叫")
class XiaoTianQuan(Dog):
def fly(self):
print("我会飞")
def bark(self):
print("叫地跟神一样")
# 创建一个哮天犬的对象
xtq = XiaoTianQuan()
# 如果子类中重写了父类的方法,会调用子类中重写的方法
xtq.bark()
扩展父类的方法
super().父类方法或父类名.方法(self)
class Animal:
def eat(self):
print("吃")
def drink(self):
print("喝")
def run(self):
print("跑")
def sleep(self):
print("睡")
class Dog(Animal):
def bark(self):
print("汪汪叫")
class XiaoTianQuan(Dog):
def fly(self):
print("我会飞")
def bark(self):
# 1、针对子类特有的需求,编写代码
print("神一样的叫唤")
# 2、使用 super(),调用原本在父类中的封装方法
super().bark()
# 父类名.方法(self)
# 注意:使用子类调用方法,会出现递归调用 - 会出现死循环
# XiaoTianQuan.bark()
Dog.bark(self)
# 3、增加其他子类的代码
print("arafafgreaf")
# 创建一个哮天犬的对象
xtq = XiaoTianQuan()
# 如果子类中重写了父类的方法,会调用子类中重写的方法
xtq.bark()
父类的私有属性和私有方法
class A:
def __init__(self):
self.num1 = 100
self.__num2 = 200
def __test(self):
print("私有方法 %d %d" % (self.num1, self.__num2))
class B(A):
def demo(self):
# 1、访问父类的私有属性
print("访问父类的私有属性 %d" % self.__num2)
# 2、调用父类的私有方法
self.__test()
# 创建一个子类对象
b = B()
print(b)
# 在外界不能直接访问父类的私有属性和私有方法
# print(b.__num2)
# b.__test()
# 在子类中不能直接访问父类的私有属性和私有方法
# b.demo()
多继承
子类可以拥有多个父类,并且具有所有父类的属性和方法
多继承的使用注意事项
如果父类之间存在同名的属性或方法时,应避免使用多继承
MRO-方法搜索顺序
主要用于多继承时判断方法、属性的调用路径
class A:
def test(self):
print("A---test 方法")
def demo(self):
print("A---demo 方法")
class B:
def test(self):
print("B---test 方法")
def demo(self):
print("B---demo 方法")
class C(B, A):
"""多继承可以让子类对象,同时具有多个父类的属性和方法"""
pass
# 创建子类对象
c = C()
c.test()
c.demo()
# 确定C类对象调用方法的顺序
print(C.__mro__)