第四周Day4 —— Python继承

第四周 Day4 —— Python继承

一、继承

1. 什么是继承

​ 让子类直接拥有父类属性和方法的过程就是继承。

​ 子类:继承者

​ 父类:被继承者,父类又叫超类

2. 怎么继承

​ Python中子类可以继承父类所有的属性和方法。

class 子类(父类):
	pass

若要创建子类,必须有父类。

class Person:
    def __init__(self, name='小花', age=18, gender='女'):
        self.name = name
        self.age = age
        self.gender = gender


class Student(Person):
    pass


stu1 = Student()
print(stu1.name, stu1.age, stu1.gender)   # 小花 18 女

注意:

  1. 如果定义类的时候没有添加父类,默认继承python的基类object
  2. 同一个子类可以同时继承多个父类:class 子类(父类1, 父类2, 父类3,...)

二、重写

1. 在子类中添加属性和方法
  1. 添加类属性:直接在子类中定义新的类属性。

  2. 添加方法:直接在子类中添家新的方法。

    1. 在子类中添家方法的时候可以对父类的方法重写。

    2. 在子类中可以通过super().方法的形式来调用父类中的方法。(注意:不能在静态方法中使用super()调用父类的方法)

class A:
    x = 100


    @staticmethod
    def func1():
        print('A')

    @classmethod
    def funca(cls):
        print('A1')


class B(A):
    y = 20

    @staticmethod
    def func2():
        print('B')


    @staticmethod
    def func1():
        """重写func1"""
        print('BB')

    @classmethod
    def funca(cls):
        super().funca()
        print('B2')

    @staticmethod
    def func3():
        super(B, B()).func1()
        print('B的静态')


print(A.x)    # 100
print(B.x)    # 100
print(B.y)    # 20
# print(A.y)    # 报错
B.func1()     # BB
B.func2()     # B
A.func1()     # A

B.funca()     # A1 B2
B.func3()     # A B的静态

总结:super的用法

可以通过super在子类中调用父类中的方法。

  1. suoer().方法() - 直接调用当前类的父类的指定方法
  2. super(类, 对象).方法() - 调用指定类的父类的指定方法(要求对象必须是前面的类的对象)
  1. 添加对象属性

    在子类的__init__方法中通过super()去调用父类的__init__

class Animal:
    def __init__(self):
        self.age = 0
        self.gender = '雌'


class Cat(Animal):
    def __init__(self):
        super().__init__()
        self.color = '白色'
        self.price = 2000
        self.breed = '野猫'


cat = Cat()
print(cat.age, cat.gender)    # 0 雌
print(cat.color, cat.price, cat.breed)     # 白色 2000 野猫

三、对象属性的添加问题

class A:
    def __init__(self, a, b=10):
        self.a = a
        self.b = b
        self.c = 0


class B(A):
    def __init__(self, d, a):
        super().__init__(a)
        self.d = d


bb = B(100, 200)
print(bb.a, bb.b, bb.c, bb.d)         # 200 10 0 100

练习:创建一个人类有属性:姓名、年龄、性别,要求创建人的对象的时候姓名和年龄必须赋值,性别可以赋值也可以不赋值(默认是男)

创建学生类有属性:姓名、年龄、性别、学号、学分和电话,要求创建学生对象的时候,姓名和电话必须赋值,年龄和性别可以赋值也可以不赋值(默认是18和男),学分和学号创建的时候不能赋值,默认值分别是‘000’和0

class Person:
    def __init__(self, name, age, gender='男'):
        self.name = name
        self.age = age
        self.gender = gender


class Student(Person):
    def __init__(self, name, tel, age=18, gender='男'):
        super().__init__(name, age, gender)
        self.tel = tel
        self.stu_id = '000'
        self.credits = 0


stu1 = Student('小明', '123456789', age=20, gender='女')
print(stu1.name, stu1.age, stu1.gender, stu1.tel, stu1.stu_id, stu1.credits) 
# 小明 20 女 123456789 000 0

四、多继承

​ 多继承的是子类可以继承所有父类的类属性和方法,但是只能继承第一个父类的对象属性。

class Animal:
    num = 61


    def __init__(self):
        self.age = 0
        self.gender = '雄'


    @classmethod
    def show(cls):
        print(f'数量:{cls.num}')


class Fly:
    name = '飞行器'


    def __init__(self):
        self.height = 100
        self.time = 3

    @staticmethod
    def message():
        print('飞行器')


class Bird(Animal, Fly):
    pass


print(Bird.num, Bird.name)     # 61 飞行器
Bird.show()                    # 数量:61
Bird.message()                 # 飞行器

bird1 = Bird()
print(bird1.age, bird1.gender)
# print(bird1.height, bird1.time)   # AttributeError: 'Bird' object has no attribute 'height'

五、私有化(补充)

  • 公开的:在类的内部可以使用、类的外部也可以使用还可以被继承。(Python中所有的属性和方法都可以公开)

  • 保护的:在类的内部可以使用、可以被继承。

  • 私有的:只能在类的内部可以使用。

1.私有化的方法:

​ 在属性名或者方法名前面加__就可以让属性或者方法变成私有的。

2.私有化的原理:

​ 假的私有化;在__开头的名字前面加_类名

class A:
    __x = 100


print(A.__x)    # 报错
print(A._A__x)  # 100

六、拷贝

from copy import copy, deepcopy


class Dog:
    def __init__(self):
        self.name = '馒头'
        self.gender = '公狗'


    def __repr__(self):
        return f'<{str(self.__dict__)[1:-1]}, id:{id(self)}>'


class Person:
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender
        self.dog = Dog()


    def __repr__(self):
        return f'<{str(self.__dict__)[1:-1]}>'


p1 = Person('小明', 20, '男')
p2 = p1          # 直接赋值,将p1中的地址赋给p2
p3 = copy(p1)    # 浅拷贝,复制p1产生一个新的对象,用新对象给p3赋值
p4 = deepcopy(p1)  # 深拷贝,复制p1产生一个新的对象,用新对象给p4赋值
p1.name = '小花'
print('原数据:', p1)
print('直接赋值:', p2)
print('浅拷贝:', p3)
print('深拷贝:', p4)

# 原数据: <'name': '小花', 'age': 20, 'gender': '男', 'dog': <'name': '馒头', 'gender': '公狗', id:2968125319600>, id:2968122732616>
# 直接赋值: <'name': '小花', 'age': 20, 'gender': '男', 'dog': <'name': '馒头', 'gender': '公狗', id:2968125319600>, id:2968122732616>
# 浅拷贝: <'name': '小明', 'age': 20, 'gender': '男', 'dog': <'name': '馒头', 'gender': '公狗', id:2968125319600>, id:2968125319768>
# 深拷贝: <'name': '小明', 'age': 20, 'gender': '男', 'dog': <'name': '馒头', 'gender': '公狗', id:2968125342496>, id:2968125320440>
1. 浅拷贝和深拷贝

​ 共同点:不管是浅拷贝还是深拷贝都是复制被拷贝的对象产生一个新的对象,然后用新的对象来复制。

​ 区别:如果背靠背的对象中有子对象,浅拷贝不复制子对象用原来的,深拷贝会复制子对象产生新的子对象。

A = [10, 20, 30, ['abc', '123']]
B = A
C = copy(A)
D = deepcopy(A)

A.append(100)       # A = [10, 20, 30, ['abc', '123'], 100]
A[3].pop()          # A = [10, 20, 30, ['abc'], 100]

print(B)            # B = [10, 20, 30, ['abc', '123'], 100]
print(C)            # C = [10, 20, 30, ['abc']]
print(D)            # D = [10, 20, 30, ['abc', '123']]

七、内存管理

​ 内存管理分为内存的开辟和释放:

1. 内存的开辟

python中所有的类型都是类,所有的数据都是对象,对象都保存在堆里面。

​ 在保存护具的时候相同的不可变数据内存中只保存一份,相同的可变数据在内存中一定会保存多份。

使用数据的时候就申请内存保存数据

2. 内存的释放——垃圾回收机制

python中内存的某个数据是否销毁(对应的内存是否释放),看这个数据在程序中的引用个数,当引用个数大于0的时候数据不会被销毁,当数据的引用个数为0的时候数据就会被自动销毁。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值