Loading

面向对象的继承

一、面向对象的继承

面向对象的三大特性:继承,封装,多态

继承:

  • 字面意思:子承父业,合法继承家产,就是如果你是独生子,不出意外,你会继承你父母所有家产,他们所有财产都会由你使用。
  • 官方说法:如果一个类别A“继承自”另一个类别B,就把这个A称为“B的子类别”,而把B称为“A的父类别”也可以称“B是A的超类”。继承可以使得子类别具有父类别的各种属性和方法,而不需要再次编写相同的代码。
object类 新式类,类祖宗
  • 所有在 python3 当中的类都是继承object类的

  • object中有init

  • 所有的类都默认的继承object

继承的优点:
  1. 增加了类的耦合性(耦合性不宜多,宜精)
  2. 减少了重复代码。
  3. 使得代码更加规范,合理化。
继承的语法:
class A:
    pass

class B(A):
    pass

# B继承A,A是父类,B是子类
# A是父类 基类 超类
# B是子类 派生类

二、单继承

单继承的语法:

class A:
    pass
class B(A):
    pass
class C(B):
    pass
class D(C):
    pass
1.类名,对象执行父类方法,和执行顺序
class Animal:
    creature = '动物'

    def __init__(self, name):
        self.name = name

    def eat(self):
        print(f'{self.name},可以吃')

    def drink(self):
        print(f'{self.name},可以喝')

    def sleep(self):
        print(f'{self.name},会睡觉')


class Cat(Animal):
    def climb_tree(self):
        print(f'{self.name},会爬树')


class Dog(Animal):
    def house_keep(self):
        print(f'{self.name},会看家')


print(Cat.creature)         # 子类可以使用父类中的 : 方法 静态变量

# 实例化对象必须执行__init__方法。类中没有,从父类找,父类没有,从object类中找
Xiao_Bai = Cat('小白')	   
# 先开辟空间,空间里有一个类指针-->指向Cat
# 调用init,对象在自己的空间中找init没找到,到Cat类中找init也没找到,
# 找父类Animal中的init


# 对象可以调用父类属性和方法
Xiao_Bai.eat()              # --->小白,可以吃
# 要执行自己类中的eat方法,自己类没有才能执行父类中的方法
# 当子类和父类的方法重名的时候,我们只使用子类的方法,而不会去调用父类的方法了
2.同时执行类以及父类方法
  • 例如:
    • 猫吃猫粮,hp 加100。
    • 狗吃狗粮,vigour 加100。

方法一:

子类想要调用父类的方法的同时还想执行自己的同名方法

猫和狗在调用eat的时候既调用自己的也调用父类的,

在子类的方法中调用父类的方法 :父类名.方法名(self)

class Animal:

    def __init__(self, name, food):
        self.name = name
        self.food = food
        self.hp = 100
        self.vigour = 100

    def eat(self):
        print(f'{self.name},吃{self.food}')

    def drink(self):
        print(f'{self.name},可以喝')

    def sleep(self):
        print(f'{self.name},会睡觉')


class Cat(Animal):
    def eat(self):
        self.hp += 100
        Animal.eat(self)		# 子类eat方法中调用父类eat方法

    def climb_tree(self):
        print(f'{self.name},会爬树')


class Dog(Animal):
    def eat(self):
        self.vigour += 100
        Animal.eat(self)		# 子类eat方法中调用父类eat方法

    def house_keep(self):
        print(f'{self.name},会看家')


Xiao_Bai = Cat('小白', '猫粮')
Xiao_Hei = Dog('小黑', '狗粮')

Xiao_Bai.eat()
Xiao_Hei.eat()

print(Xiao_Bai.__dict__)
print(Xiao_Hei.__dict__)
# 输出
小白,吃猫粮
小黑,吃狗粮
{'name': '小白', 'food': '猫粮', 'hp': 200, 'vigour': 100}
{'name': '小黑', 'food': '狗粮', 'hp': 100, 'vigour': 200}

方法二:

  • 利用super,super( ). func ( 参数 )

给狗和猫定制个性的属性

  • 猫:eye_color眼睛的颜色
  • 狗:size 狗的体型
class Animal:

    def __init__(self, name):
        self.name = name
        self.hp = 100
        self.vigour = 100

    def eat(self):
        print(f'{self.name},吃{self.food}')

    def drink(self):
        print(f'{self.name},可以喝')

    def sleep(self):
        print(f'{self.name},会睡觉')


class Cat(Animal):
    def __init__(self, name, eye_color):
        super().__init__(name)
        self.eye_color = eye_color

    def climb_tree(self):
        print(f'{self.name},会爬树')


class Dog(Animal):
    def __init__(self, name, size):
        super().__init__(name)
        self.size = size

    def house_keep(self):
        print(f'{self.name},会看家')


Xiao_Bai = Cat('小白', '蓝色')
Xiao_Hei = Dog('小黑', '大型')

print(Xiao_Bai.__dict__)
print(Xiao_Hei.__dict__)

# 输出
{'name': '小白', 'hp': 100, 'vigour': 100, 'eye_color': '蓝色'}
{'name': '小黑', 'hp': 100, 'vigour': 100, 'size': '大型'}

三、多继承

  • 单继承:

    • 只有一个爹
  • 多继承:

    • 有好几个爹
    • 有些语言不支持多继承 java
    • python语言的特点:可以在面向对象中支持多继承
  • 多继承语法:

class A:
    pass
class B:
    pass
class C(A,B):	# 如果调用父类的变量和方法,会优先去找A类的,其次在去找B类的
    pass

单继承:

  • 调子类的:子类自己有的时候
  • 调父类的:子类自己没有的时候
  • 调子类和父类的:子类父类都有,子类中调用父类的

多继承:

  • 一个类有多少父类,在调用父类方法的时候,按照继承顺序,先继承的就先寻找。

四、其他

绑定方法和普通的函数
from types import FunctionType, MethodType
# FunctionType : 函数
# MethodType : 方法
  • 类调用自身的函数就是——>函数
  • 对象调用类的函数是——>方法
class A:
    def func(self):
        print('in func')


print(A.func)  # 类调用自身的函数就是-->函数
print(isinstance(A.func, FunctionType))     # 函数
print(isinstance(A.func, MethodType))       # 方法

print('------------------------------------------------------')
a = A()
print(a.func)  # 对象调用类的函数是-->方法
print(isinstance(a.func, FunctionType))     # 函数
print(isinstance(a.func, MethodType))       # 方法

# 输出
<function A.func at 0x014F3388>
True
False
------------------------------------------------------
<bound method A.func of <__main__.A object at 0x015CF868>>
False
True
面向对象中:pickle
  • 把对象序列化存储在文件中,需要用的时候在反序列化回来也可以调用类的方法和变量
import pickle


class Person:
    def __init__(self, name, age, sex, hobby, job):
        self.name = name
        self.age = age
        self.sex = sex
        self.hobby = hobby
        self.job = job

    def func(self):
        return f'{self.name}的方法'


Bob = Person('鲍勃', '18', '男', '熬夜', '攻城狮')
Ali = Person('艾伦', '20', '女', '看电视', '演员')

with open('pickle_', mode='wb') as f1:
    pickle.dump(Bob, f1)
    pickle.dump(Ali, f1)

with open('pickle_', mode='rb') as f2:
    B = pickle.load(f2)
    A = pickle.load(f2)

print(B.name)
print(A.func())
# 输出
鲍勃
艾伦的方法
posted @ 2021-05-02 16:44  Mr-Yang`  阅读(165)  评论(0编辑  收藏  举报