面向对象的三大特性之继承
Posted lizeqian1994
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象的三大特性之继承相关的知识,希望对你有一定的参考价值。
在子类中 类名后面加上括号,写上父类的名称即可,
在python中一个子类可以有多个父类,多个父类在括号中用逗号隔开,,这一点在其他语言中是不支持的
class Parents():
year=2018
def coding(self):
print(‘正在编辑...‘)
class Son(Parents):
pass
s=Son()
print(s.year) #结果:2018 子类可以使用父类中的属性
s.coding() #结果:正在编辑.. 子类也可以使用父类中的函数
有时继承虽然减少了重复代码,但是继承到一些不应该有的内容
这时我们就需要抽取公共的父类这一过程就叫做抽象
抽象就是抽取多个类中相同的部分形成另一个类
如下:Person就是抽象得到的类
class Person:
def __init__(self ,name ,age ,sex):
self.name = name
self.age = age
self.sex = sex
def eat(self):
print("正在吃饭....")
def study(self):
print("正在学习....")
class Teacher(Person):
def teaching(self):
print("老师正在上课......")
t1 = Teacher("henry" ,29 ,"man")
t1.eat()
t1.study()
class Student(Person):
pass
stu1 = Student("wendy" ,20 ,"woman")
stu1.eat()
stu1.study()
通过继承 避免了重复代码的编写
通过抽象 避免了继承到一些不应该有的内容
应该先抽象再继承
再抽取过程中 可能会一些跟业务需求无关的类,这是正常的 这些称之为公共父类
公共父类的作用是存储多个子类相同属性和技能
派生
什么是派生?
派生指的是 子类继承某个父类 并且拥有自己独特的属性或技能 该子类称之为派生类
只要子类中出现了任何新内容,它就是一个派生类
class Person:
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def sayHI(self):
print("hello 我是%s 今年%s岁 性别:%s" % (self.name,self.age,self.sex))
# Test不能称为派生类 , 因为没与任何独特的内容与父类完全一致
class Test(Person):
pass
# Student类就成为 Person类的派生类
class Student(Person):
def __init__(self,name,age,sex,number):
self.name = name
self.age = age
self.sex = sex
self.number = number
def up_class(self):
print("%s 正在上课.....")
覆盖
什么是覆盖?
在子类中如果出现与父类中相同的属性名称时,根据查找顺序,优先使用子类中的属性,这种行为称之为覆盖.
class A():
age=18
def f1(self):
print(‘A f1‘)
pass
class B(A):
age=24
def f1(self):
print(‘B f1‘)
pass
b1=B()
print(b1.age) #结果:24
b1.f1() #结果:B f1
1.指名道姓的调用
class Person():
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def say_hi(self):
print(‘my name is %s,my age is %s,my sex is%s‘%(self.name,self.age,self.sex))
class Student(Person):
def __init__(self,name,age,sex,number):
Person.__init__(self,name,age,sex) #指名道姓地调用
self.number=number
def up_class(self):
print(‘正在上课....‘)
def say_hi(self):
Person.say_hi(self)
print(‘我的学号:%s‘%(self.number))
stu1=Student(‘wendy‘,18,‘woman‘,‘007‘)
print(stu1.name)
stu1.say_hi()
2.使用super()创建一个特殊的函数用来调用父类 查找顺序按照mro列表
class Person():
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def say_hi(self):
print(‘my name is %s,my age is %s,my sex is%s‘%(self.name,self.age,self.sex))
class Student(Person):
def __init__(self,name,age,sex,number):
#在python3中
super().__init__(name,age,sex)
#在python2中
# super(Student,self).__init__(name, age, sex)
self.number=number
def up_class(self):
print(‘正在上课....‘)
def say_hi(self):
#在python3zhong
super().say_hi()
#在python2中
#super(Student,self).say_hi()
print(‘我的学号:%s‘%(self.number))
stu1=Student(‘wendy‘,18,‘woman‘,‘007‘)
print(stu1.name)
stu1.say_hi()
对象 -> 子类 ->父类 ->父类的父类.....
优先找对象 如果对象没有 则找子类,如果子类没有,会沿着继承关系一直找到最顶层的父类
无论是属性还是方法(函数) 查找顺序是一样的
mro列表
mro列表存储的是各个父类,顺序是通过c3算法得来
菱形
有菱形时,先广度再深度. 没有菱形时,深度优先
新式类:
所有直接继承或间接继承object(对象)的类 都是新式类
object 称之为根类 意思是 所有的类都源自于object类
为什么这么设计?
例如:创建对象时,需要申请内存空间,创建新的名称空间,将对象的属性放入名称空间,这一些了复杂的基础操作,都有object来完成
简单地说object提供了一些常用的基础操作
在python3中默认所有类都是新式类
而python2中默认是经典类(不会自动继承Object)
class S:
pass
class Student(S):
pass
# __bases__用于查看父类
print(Student.__bases__)
# 显示属性的查找顺序列表,属性查找属性就是按照该列表来查找的
print(Student.mro())
以上是关于面向对象的三大特性之继承的主要内容,如果未能解决你的问题,请参考以下文章