导语:今天学习下继承!
在面向对象编程中,继承是一种非常重要的概念。它允许我们创建一个新的类(子类),继承另一个类(父类)的特性。这样,子类就可以复用父类的属性和方法,同时还可以添加新的属性和方法。
类的定义
首先,我们定义一个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
类的方法,可以直接调用eat
和sleep
方法。
部分继承1
有时候,我们可能只需要继承部分属性和方法。下面是一个例子,我们只修改了__init__
方法。
class Children(Person):
def __init__(self, little):
self.age = little
self.name = little
son = Children('小小的')
print(son.eat())
print(son.sleep())
在这个例子中,我们只传了一个参数little
,但它仍然可以调用父类的eat
和sleep
方法。
部分继承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__
方法设置了name
和age
属性,并可以在对象实例上直接访问这些属性。
继承的不同写法
在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
类中,我们定义了fun1
和fun2
两个方法。fun1
被@property
装饰器装饰,因此它现在可以像属性一样被调用,而fun2
仍然是普通的方法。
- 当我们使用
print(cl3.fun1)
时,由于fun1
被转换为属性,我们直接访问它,不需要括号。 - 而对于
print(cl3.fun2())
,由于fun2
是普通方法,我们需要使用括号来调用它。