继承
- 子类可以使用弗雷定义的内容或者行为等
- 继承的实现
- 父类,基类,超类:被继承的类,Base Class,Super Class
- 子类:有继承行为的类
- 所有类都必须有一个父类
- 如果没有,则默认为object的子类
- 继承的特征
- 所有的类都继承自object类,即所有的类都是object类的子类
- 子类一旦继承父类,则可以使用父类中除私有成员外的所有内容
- 子类继承父类后并没有将父类成员完全赋值到子类中,而是通过引用关系访问调用
- 子类中可以定义独有的成员属性和方法
- 子类中定义的成员合成父类成员如果相同,则优先使用子类成员
- 子类如果想扩充父类的方法,可以在定义新方法的同时访问父类成员来进行代码重用,可以使用 父类名.父类成员 的格式来调用父类成员,也可以使用super().父类成员的格式来调用
- 继承变量函数的查找顺序问题
- 优先查找自己的变量
- 没有则查找父类
- 构造函数如果本类中没有定义,则自动查找调用父类构造函数
- 如果本类有定义,则不再继续向上查找
# 所有类必须有父类
# 默认是object
class Person1():
pass
class Person2():
pass
class Person():
name = "NoName"
age = 0
# 父类卸载类定义的时候的括号里
class Teacher(Person):
pass
t = Teacher()
print(t.name)
NoName
class Bird():
fly = "Yes,we can"
def flying(self):
print("飞飞飞")
return None
class BirdMan(Person,Bird):
pass
bm = BirdMan()
bm.flying()
print(bm.name)
飞飞飞
NoName
# 继承的语法
# 在python中,任何类都有一个共同的父类叫object
class Person():
name = "NoName"
age = 0
__score = 0 # 考试成绩是秘密,只能自己知道
_petname = "sec" # 小名,是保护的,子类可以用,但不能公用
def sleep(self):
print("Sleeping........")
# 父类写在括号内
class Teacher(Person):
teacher_id = "1234"
def make_test(self):
print("attention")
t = Teacher()
print(t.name)
print(t._petname)
# 受保护不能外部访问,为啥这里可以
print(Teacher.name)
# 私有访问问题
# 公开访问私有变量,报错
#print(t.score)
t.sleep()
print(t.teacher_id)
t.make_test()
NoName
sec
NoName
Sleeping........
1234
attention
# 子类和父类定义同一个名称变量,则优先使用子类本身
class Person():
name = "NoName"
age = 0
__score = 0 # 考试成绩是秘密,只能自己知道
_petname = "sec" # 小名,是保护的,子类可以用,但不能公用
def sleep(self):
print("Sleeping........")
# 父类写在括号内
class Teacher(Person):
teacher_id = "1234"
name = "caipo"
def make_test(self):
print("attention")
t = Teacher()
print(t.name)
caipo
# 子类扩充父类功能的案例
# 人有工作的函数,老师也有工作函数,但老师的工作需要讲课
class Person():
name = "NoName"
age = 0
__score = 0 # 考试成绩是秘密,只能自己知道
_petname = "sec" # 小名,是保护的,子类可以用,但不能公用
def sleep(self):
print("Sleeping........")
def work(self):
print("make a money")
# 父类写在括号内
class Teacher(Person):
teacher_id = "1234"
name = "caipo"
def make_test(self):
print("attention")
def work(self):
# 扩充父类的功能只需要调用父类相应的函数
#Person.work(self)
# 扩充父类的另一种方法
# super代表得到父类
super().work()
self.make_test()
t = Teacher()
t.work()
make a money
attention
issubclass检测是否是子类
- 可以用来检测两个类的父子关系
# 利用刚才定义的Bird,BirMan,Person,Teacher,检测父子关系
print(issubclass(BirdMan,Bird))
print(issubclass(BirdMan,Person))
print(issubclass(BirdMan,Teacher))
True
True
False
help(issubclass)
Help on built-in function issubclass in module builtins:
issubclass(cls, class_or_tuple, /)
Return whether 'cls' is a derived from another class or is the same class.
A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to
check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B)
or ...`` etc.
构造函数
-
在函数实例化的时候调用的一个函数
-
自动调用
-
要求,第一个参数必须有,一般推荐self
-
构造函数的调用时间:一般认为在实例化的时候第一个被调用
-
一般不手动调用,实例化的时候自动调用,参数需写入类名称后面的括号中
-
是一类特殊的函数,在类进行实例化之前进行调用
-
如果子类定义了构造函数,则实例化时使用构造函数,不查找父类构造函数
-
如果子类没有定义构造函数,则自动查找父类构造函数
-
如果子类没定义构造函数,父类的构造函数带参数,则构造对象时参数应该安父类参数构造
class Bird():
def __init__(self):
print("我被调用了")
return None
# 此时被调用构造函数
b = Bird()
我被调用了
# 构造函数2
class Person():
def __init__(self,name,age):
print(name,age)
p = Person("wcp",16)
wcp 16
构造函数的继承
- 构造函数默认继承
- 一旦子类定义了构造函数,则不再调用父类构造函数
# 构造函数默认继承
class Person():
def __init__(self,name,age):
print("Person=({},{})".format(name,age))
class Teacher(Person):
pass
t = Teacher("wcp",16)
t = Teacher()
Person=(wcp,16)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-6-3e1b46e8ead1> in <module>
9
10 t = Teacher("wcp",16)
---> 11 t = Teacher()
TypeError: __init__() missing 2 required positional arguments: 'name' and 'age'
# 继承中的构造函数
class Animal():
pass
class Reptile(Animal):
def __init__(self):
print("I am Reptile")
class Dog(Reptile):
# __init__就是构造函数
# 每次实例化的时候,第一个被调用
# 因为主要工作是进行初始化,所以得名
def __init__(self):
print("I am init in dog")
# 实例化的时候,自动调用了Dog的构造函数
# 因为找到了构造函数,则不再查找父类的构造函数
summer = Dog()
# 猫没有写构造函数
class Cat(Reptile):
pass
# 此时应该自动调用构造函数,因为Cat没有构造函数,所以查找父类构造函数
# 在Reptile中查找到了构造函数,则停止向上查找
c = Cat()
I am init in dog
I am Reptile
# 继承中的构造函数 - 3
class Animal():
pass
class Reptile(Animal):
def __init__(self,name):
print("I am Reptile {0}".format(name))
class Dog(Reptile):
# __init__就是构造函数
# 每次实例化的时候,第一个被调用
# 因为主要工作是进行初始化,所以得名
def __init__(self):
print("I am init in dog")
# 实例化Dog时,查找到Dog的构造函数,参数匹配,不报错
summer = Dog()
# 猫没有写构造函数
class Cat(Reptile):
pass
# 此时,由于Cat没有构造函数,则向上查找
# 因为Reptile的构造函数需要两个参数,实例化的时候给了一个,报错
c = Cat()
I am init in dog
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-13-abcaecb3fe31> in <module>
24 # 此时,由于Cat没有构造函数,则向上查找
25 # 因为Reptile的构造函数需要两个参数,实例化的时候给了一个,报错
---> 26 c = Cat()
TypeError: __init__() missing 1 required positional argument: 'name'
# 继承中的构造函数 - 4
class Animal():
def __init__(self):
print("Animal")
class Reptile(Animal):
pass
class Dog(Reptile):
pass
# 实例化Dog时,查找到Dog的构造函数,参数匹配,不报错
summer = Dog()
# 猫没有写构造函数
class Cat(Reptile):
pass
# 此时,由于Cat没有构造函数,则向上查找
# 因为Reptile的构造函数需要两个参数,实例化的时候给了一个,报错
c = Cat()
Animal
Animal
- super
- super不是关键字,而是一个类
- super的作用是获取MRO(MethodResolustionOrder,方法解析顺序)列表中的第一个类
- super于父类直接没有任何实质性关系,但通过super可以调用到父类
- super使用两个方法,参见在构造函数中调用父类的构造函数
print(type(super))
help(super)
<class 'type'>
Help on class super in module builtins:
class super(object)
| super() -> same as super(__class__, <first argument>)
| super(type) -> unbound super object
| super(type, obj) -> bound super object; requires isinstance(obj, type)
| super(type, type2) -> bound super object; requires issubclass(type2, type)
| Typical use to call a cooperative superclass method:
| class C(B):
| def meth(self, arg):
| super().meth(arg)
| This works for class methods too:
| class C(B):
| @classmethod
| def cmeth(cls, arg):
| super().cmeth(arg)
|
| Methods defined here:
|
| __get__(self, instance, owner, /)
| Return an attribute of instance, which is of type owner.
|
| __getattribute__(self, name, /)
| Return getattr(self, name).
|
| __init__(self, /, *args, **kwargs)
| Initialize self. See help(type(self)) for accurate signature.
|
| __repr__(self, /)
| Return repr(self).
|
| ----------------------------------------------------------------------
| Static methods defined here:
|
| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate signature.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __self__
| the instance invoking super(); may be None
|
| __self_class__
| the type of the instance invoking super(); may be None
|
| __thisclass__
| the class invoking super()