php 子类重新定义父类的变量_Python 中类与类之间的关系

da774de79c68fa3edf9c57d8c5d9095a.png
封面图片来源:沙沙野

内容概览

  1. 继承
  2. 类与类之间的关系

继承

  1. 基础是一种创建新类的方式,新建的类可以继承一个或多个父类
  2. 父类又称基类或超类,新建的类称为子类或派生类
class Animal:
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age

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

class Cat:
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age

class Dog:
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age

3. 观察上面的四个类,发现给对象封装的属性是一样的,此时可以先定义一个类,封装一些属性和方法,其他的类要调用这些属性和方法的话,就继承这个类。从另一个角度来说,继承的作用之一就是降低重复性代码的使用率

class Animal:

    type_name = "动物类"

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

    def eat(self):
        print("吃东西")


# 这里 Person(Animal) 表示类 Person 继承类 Animal
# 类 Animal 就是父类,类 Person 就是子类
class Person(Animal):

    type_name = "人类"

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

# 先创建一个类 Person 的实例化对象
p1 = Person("小明", "男", 18)
# 假设这个对象想要调用 eat() 方法,但是在类 Person 中没有这个方法
# 此时,因类 Person 继承了 类 Animal
# p1 就会又去类 Animal 中查找是否有 eat() 这个方法
# 有就调用,没有的话就报错,因为再也没有其他地方可找了
p1.eat()               # 吃东西

# 同理,如果子类 Person 中有某个属性,即使父类 Animal 中也有
# 实例化对象 p1 也只会调用自己所属类 Person 中的属性
print(p1.type_name)      # 人类

4. 初始化一个实例化对象时,如果该实例化对象所属的子类中没有 __init__ 方法,只要父类中有,就能调用

class Animal:

    type_name = "动物类"

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

    def eat(self):
        print("吃东西")


class Person(Animal):

    type_name = "人类"

p1 = Person("小明", "男", 18)
print(p1.__dict__)
# 运行结果:
{'name': '小明', 'sex': '男', 'age': 18}

# 虽然类 Person 中没有给对象封装这些属性,但是父类 Animal 中有

5. 继承又分为单基础和多继承

# 定义父类1
class Parent_Class1:
    pass

# 定义父类2
class Parent_Class2:
    pass

# 单继承,基类是 Parent_Class1,派生类是 Sub_Class1
class Sub_Class1(Parent_Class1):
    pass

# 多继承
class Sub_Class2(Parent_Class1, Parent_Class2):
    pass


# 一个类继承了多少个类,可以使用 __bases__ 方法来查看
print(Sub_Class1.__bases__)         # (<class '__main__.Parent_Class1'>,)
print(Sub_Class2.__bases__)         # (<class '__main__.Parent_Class1'>, <class '__main__.Parent_Class2'>)


# 如果没有指定基类,比如这里的 Parent_Class1 和 Parent_Class2
# 那么会默认基础 Object 类,它是所有类的基类
# Object 类提供了一些常用的方法,比如 __str__
print(Parent_Class1.__bases__)      # (<class 'object'>,)
print(Parent_Class2.__bases__)      # (<class 'object'>,)

6. 如果一个实例化对象既要执行子类 (所属类) 的方法,又要执行父类方法,有两种方法可以实现

# 方法一:父类名.__init__(参数)
class Animal:

    type_name = "动物类"

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

    def eat(self):
        print("吃东西")


class Person(Animal):
    def __init__(self, name, sex, age, mind):
        # 继承父类中给对象封装的 name,sex,age 等属性
        Animal.__init__(self, name, sex, age)
        # 给子类中给对象封装一个 mind 属性
        self.mind = mind


class Cat(Animal):
    def __init__(self, name, sex, age, clmib):
        Animal.__init__(self, name, sex, age)
        self.clmib = clmib


class Dog(Animal):
    def __init__(self, name, sex, age, look):
        Animal.__init__(self, name, sex, age)
        self.look = look


p1 = Person("小春", "男", 28, "有思想")
print(p1.__dict__)      # {'name': '小春', 'sex': '男', 'age': 28, 'mind': '有思想'}

c1 = Cat("土豆", "女", 2, "爬树")
print(c1.__dict__)      # {'name': '土豆', 'sex': '女', 'age': 2, 'clmib': '爬树'}

d1 = Dog("大嘴", "雌性", 3, "看门")
print(d1.__dict__)      # {'name': '大嘴', 'sex': '雌性', 'age': 3, 'look': '看门'}
# 方法二:super().__init__(参数)
class Animal:

    type_name = "动物类"

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

    def eat(self):
        print("吃东西")

class Person(Animal):

    # type_name = "人类"

    def __init__(self, name, sex, age, mind):
        super().__init__(name, sex, age)
        self.mind = mind

    # 如果父类子类中都有 eat(),则要先执行父类的话,应该这样写
    def eat(self):
        super().eat()
        print("%s 吃饭" % self.name)


class Cat(Animal):
    def __init__(self, name, sex, age, clmib):
        super().__init__(name, sex, age)
        self.clmib = clmib


class Dog(Animal):
    def __init__(self, name, sex, age, look):
        super().__init__(name, sex, age)
        self.look = look


p1 = Person("小春", "男", 28, "有思想")
p1.eat()
# 运行结果:
吃东西
小春 吃饭

类与类之间的关系

  1. 依赖关系:给一个类的方法传了一个参数,此参数是另一个类的对象 (类名)。这种依赖关系是所有关系中紧密度最小的,耦合性最低的,俗称 "你中有我,我中有你"
class Elephant:

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

    # 给一个类的方法传了另一个类的对象
    def open(self, obj):
        print("%s心里默念:1,2,3,开!" % self.name)
        obj.open_door()

    def close(self, obj1):
        print("%s心里默念:3,2,1,关!" % self.name)
        obj1.close_door()


class Refrigerator:

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

    def open_door(self):
        print("%s冰箱门被大象打开了" % self.name)

    def close_door(self):
        print("%s冰箱门被大象关闭了" % self.name)

e1 = Elephant("神奇的大象")
haier = Refrigerator("海尔")
e1.open(haier)
e1.close(haier)
# 运行结果:
神奇的大象心里默念:1,2,3,开!
海尔冰箱门被大象打开了
神奇的大象心里默念:3,2,1,关!
海尔冰箱门被大象关闭了

2. 关联关系

class Boy:

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

    def eat(self):
        # 如果实例化一个对象时
        # 有 girlfrend 这个参数就执行下面的 if 条件的代码
        if self.girlfriend:
            print("%s和%s一起吃饭" % (self.name, self.girlfriend.name))
        else:
            print("一个人不吃了")

    def append_girl(self, girl):
        self.girlfriend = girl

    def remove_girl(self, girl):
        self.girlfriend = None

class Girl:

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

# 只传一个参数表示 girlfriend 默认是 None
b1 = Boy("小明")
b1.eat()        # 一个人不吃了

g1 = Girl("如花")
# 把类 Girl 的实例化对象 g1 当作参数传进 append_girl 函数
b1.append_girl(g1)
b1.eat()        # 小明和如花一起吃饭


g2 = Girl("小花")
# 把类 Girl 的实例化对象 g2 传进去
b2 = Boy("小黑", g2)
b2.eat()        # 小黑和小花一起吃饭


g3 = Girl("小兰")
b3 = Boy("小白", g3)
b3.eat()        # 小白和小兰一起吃饭
b3.remove_girl(g3)
b3.eat()        # 一个人不吃了

PS: 为了方便大家相互交流、解决学习过程中遇到的问题,我新建了一个 QQ 群,感兴趣的小伙伴加进来一起学习吧!~ (群号码:697678250,加群请备注:笔记)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值