python继承详解

导语:今天学习下继承!

在面向对象编程中,继承是一种非常重要的概念。它允许我们创建一个新的类(子类),继承另一个类(父类)的特性。这样,子类就可以复用父类的属性和方法,同时还可以添加新的属性和方法。

类的定义

首先,我们定义一个Person类,它代表人类。这个类包含了类变量、实例属性和实例方法。

class Person:
    attribute = '女人'

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

    def eat(self):
        return (self.name, self.age, '喜欢吃饭')

    def sleep(self):
        return (self.name, self.age, '喜欢睡觉')

    @classmethod
    def learn(cls):
        print('人类都喜欢学习')

    @staticmethod
    def computer(a, b):
        return a + b

完全继承

当我们创建一个子类Children时,如果没有任何修改,它将完全继承Person类的所有属性和方法。

class Children(Person):
    pass

son = Children('小小崔', '6岁')
print(son.eat())
print(son.sleep())

在这个例子中,Children类完全继承了Person类的方法,可以直接调用eatsleep方法。

部分继承1

有时候,我们可能只需要继承部分属性和方法。下面是一个例子,我们只修改了__init__方法。

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

son = Children('小小的')
print(son.eat())
print(son.sleep())

在这个例子中,我们只传了一个参数little,但它仍然可以调用父类的eatsleep方法。

部分继承2

如果我们想同时使用父类的__init__方法,可以使用super()函数。

class Children(Person):
    def __init__(self, little):
        super().__init__(little, little)

son = Children('小小的')
print(son.eat())
print(son.sleep())

这里,我们通过super()调用了父类的__init__方法,使得子类可以正常使用父类的属性和方法。

部分继承3

如果子类和父类有同名的方法,子类会优先使用自己的方法。

class Children(Person):
    @classmethod
    def learn(cls):
        print('小孩子也都喜欢学习')

son = Children('小小崔', '6')
son.learn()

在这个例子中,Children类的learn方法覆盖了父类的learn方法。

部分继承4:追加

如果我们想在子类中使用父类的方法,并在此基础上添加新的功能,可以这样做:

class Children(Person):
    @classmethod
    def learn(cls):
        super().learn()
        print('小孩子也都喜欢学习')

son = Children('小小崔', '6')
son.learn()

这里,我们首先调用了父类的learn方法,然后又添加了子类自己的打印语句。

多重继承

在Python中,一个类可以继承多个父类,这被称为多重继承。多重继承允许子类继承多个父类的属性和方法。下面是一个多重继承的例子:

class Father:
    # 类变量/类属性(供所有实例所共享)
    attribute = '男人'

    # 初始化方法 self是实力的本身
    # 里面可传参数,代表一出生就有的内容
    # 这里代表实例的属性
    def __init__(self, name, age):
        self.age = age
        self.name = name

    # 这个人类可以吃饭,睡觉
    # 实例的行为,实例方法
    # 实例方法(只能实例调用,类不能调用)
    def eat(self):
        return (self.name, self.age, '喜欢吃饭')

    # 实例方法(类不能调用)
    def sleep(self):
        return (self.name, self.age, '喜欢睡觉')

    # 类方法(类可以调用,实例也可以调用)
    @classmethod
    def learn(cls):
        print('人类都喜欢学习')

    # 静态方法 (跟类没有任何关系的)(类可以调用,实例也可以调用)
    # 这相当于工具,比如人类使用计算机,不用去导入,直接在这写静态方法
    # 其实这个是函数 ,打印出来类型是<class 'function'>
    @staticmethod
    def computer(a, b):
        return a + b

# 儿子
class Son(Father):
    # 父亲有这个方法,儿子也有这个方法,儿子先用自己的 就近原则
    @classmethod
    def learn(cls):
        super().learn()
        print('小孩子也都喜欢学习')

# 孙子(多重继承,注意要先继承上一层,再继承上上一层)
class Grandson(Son,Father):
    '''孙子的内容'''

# 显示类的属性
print(Grandson.__dict__)
# 显示类的注释内容
print(Grandson.__doc__)
# 显示类的名字
print(Grandson.__name__)
# 显示类的层级关系
print(Grandson.__mro__)

在这个例子中,Grandson类同时继承了Son类和Father类。多重继承时,需要注意继承的顺序,因为它会影响到属性的查找顺序。

类的属性

在Python中,类有一些内置的属性,可以用来获取类的相关信息。

  • __dict__:类的属性字典,包含了类的所有属性和方法。
  • __doc__:类的文档字符串,即类的注释内容。
  • __name__:类的名字。
  • __mro__:类的层级关系,即方法解析顺序。

下面是如何使用这些属性的例子:

# 显示类的属性
print(Grandson.__dict__)
# 显示类的注释内容
print(Grandson.__doc__)
# 显示类的名字
print(Grandson.__name__)
# 显示类的层级关系
print(Grandson.__mro__)

对象的属性

在Python中,对象的属性是在实例化时通过__init__方法设置的。下面是如何定义和访问对象属性的例子:

# 实例化一个Grandson对象
grandson = Grandson('小明', 5)

# 访问对象的属性
print(grandson.name)  # 输出名字
print(grandson.age)   # 输出年龄

在这个例子中,grandson是一个Grandson类的实例。我们通过.__init__方法设置了nameage属性,并可以在对象实例上直接访问这些属性。

继承的不同写法

在Python中,继承有多种写法,下面是三种常见的继承方式:

写法1:使用object基类

class Class1(object):
    pass

这种写法在Python 2中是常见的,它显式地指出了Class1是从object类继承的,因为object是所有类的基类。

写法2:不写object基类和括号

class Class2():
    pass

这种写法在Python 3中是等价的,它也隐式地从object继承。括号是可选的,除非你想指定其他基类。

写法3:不写object基类和括号

class Class3:
    def __init__(self):
        self.name = "cuicui"

这种写法在Python 3中也是有效的,它同样隐式地从object继承。

将方法转换为属性

在Python中,我们可以使用@property装饰器将一个方法转换为属性。这样,我们可以像访问属性一样访问方法,而无需调用它。

class Class3:
    def __init__(self):
        self.name = "cuicui"

    @property
    def fun1(self):
        return self.name

    def fun2(self):
        return self.name

cl3 = Class3()

# 属性调用时,使用 对象.属性名
print(cl3.fun1)
# 方法调用时,使用 对象.方法名()
print(cl3.fun2())

Class3类中,我们定义了fun1fun2两个方法。fun1@property装饰器装饰,因此它现在可以像属性一样被调用,而fun2仍然是普通的方法。

  • 当我们使用print(cl3.fun1)时,由于fun1被转换为属性,我们直接访问它,不需要括号。
  • 而对于print(cl3.fun2()),由于fun2是普通方法,我们需要使用括号来调用它。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值