Python 继承
一、继承
概念
面向对象中的继承和现实生活中的继承是一个意思。如:子承父业
被继承的类称为:"基类"、"父类"或者"超类"
继承方式
1.实现继承
实现继承是指使用基类的属性和方法而无需额外编码的能力
2.接口继承
接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力(子类重构爹类方法)
在继承中子类可以继承多个基类,但一般都是一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现
开发范式大致为:划分对象 -> 抽象类 ->将类组织成为层次化结构(继承和合成) ->用类与实例进行设计和实现几个阶段
如: 中国人可以:吃、喝、拉、撒
美国人可以:吃、喝、拉、撒
上面说了中国人和美国人都可以有吃、喝、拉、撒,那么我们可以使用"继承"的方法来实现。如下:
# 定义父类. 将相同的写在父类里面. 父类中的相关方法
class Person(object):
def Eat(self):
print("吃".center(20,"♠"))
def Drink(self):
print("喝".center(20,"✌"))
def La(self):
print("拉".center(20,"❀"))
def Scatter(self):
print("撒".center(20,"✺"))
# 在类后面括号中写入另外一个类名,表示当前类继承另外一个类
class C_Person(Person):
# 本身类方法
def Ch_Person(self):
print("生是中国人. 死是中国鬼")
# 在类后面括号中写入另外一个类名,表示当前类继承另外一个类
class U_Person(Person):
# 本身类方法
def US_Person(self):
print("生是美国人. 死是中国鬼")
C = C_Person()
C.Eat()
C.Ch_Person()
U = U_Person()
U.La()
U.US_Person()
对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法
注:除了子类和父类的称谓,你可能看到过 派生类 和 基类 ,他们与子类和父类只是叫法不同而已
Python继承实例. 并重写父类方法. 如果不重新父类方法则用父类方法.重写的话就直接用自己本身的
# 定义父类. 将相同的写在父类里面. 父类中的相关方法
class Person(object):
def Eat(self):
print("吃".center(20,"♠"))
def Drink(self):
print("喝".center(20,"✌"))
def La(self):
print("拉".center(20,"❀"))
def Scatter(self):
print("撒".center(20,"✺"))
# 在类后面括号中写入另外一个类名,表示当前类继承另外一个类
class C_Person(Person):
# 本身类方法
def Ch_Person(self):
print("生是中国人. 死是中国鬼")
# 重写分类方法
def Drink(self):
print("我是中国人. 我喝国产水. 不喝吃国外产品")
# 在类后面括号中写入另外一个类名,表示当前类继承另外一个类
class U_Person(Person):
# 本身类方法
def US_Person(self):
print("生是美国人. 死是中国鬼")
C = C_Person()
C.Eat()
C.Ch_Person()
C.Drink()
U = U_Person()
U.La()
U.US_Person()
U.Drink()
Python继承实例.并重写父类方法和继承父类构造方法并重构
# 定义父类. 将相同的写在父类里面. 父类中的相关方法
class Person(object):
def __init__(self,name,age):
self.name = name
self.age= age
self.sex = "noraml" # 默认的
def Eat(self):
print("吃".center(20,"♠"))
def Drink(self):
print("喝".center(20,"✌"))
def La(self):
print("拉".center(20,"❀"))
def Scatter(self):
print("撒".center(20,"✺"))
# 在类后面括号中写入另外一个类名,表示当前类继承另外一个类
class C_Person(Person):
"""
先继承父类的构造方法.在重构
1.程序在调用时先执行本身的构造方法(def __init__(self,name,age,white)).
然后在将传递的参数传递给父类的构造方法进行构造(封装) (Person.__init__(self,name,age))
ps:构造方法接收参数值和传递的参数必须是一一对应的. 否则会报错.
"""
def __init__(self,name,age,white):
Person.__init__(self,name,age)
self.white = white
print(self.name,self.age,self.sex,self.white)
# 本身类方法
def Ch_Person(self):
print("生是中国人. 死是中国鬼")
# 重写分类方法
def Drink(self):
print("我是中国人. 我喝国产水. 不喝吃国外产品")
# 在类后面括号中写入另外一个类名,表示当前类继承另外一个类
class U_Person(Person):
# 本身类方法
def US_Person(self):
print("生是美国人. 死是中国鬼. I am %s. This year at the age of %s"%(self.name,self.age))
C = C_Person("中国人01",28,"我很白")
C.Eat()
C.Ch_Person()
C.Drink()
U = U_Person("美国人01",99)
U.La()
U.US_Person()
U.Drink()
"""
PS:当类中有构造方法(封装)时. 在调用时就必须穿对应的参数.否则会报错
"""
继承-实战
class SchoolMember(object):
"""学校成员基类"""
member = 0 # 公有属性. 存放新注册的人员信息.
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
self.Enroll() # 自动执行.计数
def Enroll(self):
"""注册"""
print("just enrolled a new schol menber [%s]"%self.name)
SchoolMember.member += 1
def Tell(self):
"""打印自己的个人信息详细信息. """
print("✌-✌-✌-✌-✌ info %s ✌-✌-✌-✌-✌" % self.name)
for k,v in self.__dict__.items():
print("\t",k,v)
print("✌-✌-✌-✌-✌ ✌ ✌ end ✌ ✌-✌-✌-✌-✌")
def __del__(self):
print("[%s] 被开除了."%self.name)
class Teacher(SchoolMember):
"""讲师类"""
def __init__(self,name,age,sex,salary,course):
"""两种继承父类(基类)方法"""
# SchoolMember.__init__(self,name,age,sex) # 1.经典类写法
super(Teacher,self).__init__(name,age,sex) # 2.新式类写法
self.salary = salary
self.course = course
def teaching(self):
print("Teacher [%s] is teaching [%s]"%(self.name,self.course))
class Student(SchoolMember):
def __init__(self,name,age,sex,course,tuition):
SchoolMember.__init__(self,name,age,sex)
self.course =course
self.tuition = tuition
def pay_tuition(self,amount):
print("student [%s] has just paied [%s]" %(self.name,self.course))
self.amount = amount
T_one = Teacher("Yuhonglin",27,"Man",15000,"Python")
S_one = Student("Gouer",26,"F","Python",9000)
S_two = Student("Yulan",29,"F","Linux",19800)
# print(T_one.__dict__) # 显示所有成员变量
print(SchoolMember.member)
T_one.Tell()
S_one.Tell()
S_two.Tell()
del S_two
print(S_one.member)
刚刚继承实战演练中有提到新式类和经典类. 那么他们的区别在于那. 写法在于那呢等 ?
经典类 vs 新式类
定义新式类: 定义经典类:
class Person(object): #new style class Person: #classical style
super ParentClass.__init__
super(Teacher,self).__init__(name,age,sex) SchoolMember.__init__(self,name,sex)
ps:现都用经典类
介绍了继承及新式类and经典类.那么问题又来了.多继承呢?
是否可以继承多个类
如果继承的多个类每个类中都定了相同的函数,那么那一个会被使用呢
1、Python的类可以继承多个类,Java和C#中则只能继承一个类
2、Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先
当类是经典类时.多继承情况下.会按照深度优先方式查找
当类是新式类时.多继承情况下.会按照广度优先方式查找
经典类和新式类.从字面上可以看出一个老一个新.新的必然包含了跟多的功能.也是之后推荐的写法.从写法上区分的话.如果 当前类或者父类继承了object类.那么该类便是新式类.否则便是经典类.
经典类多继承
class D:
def bar(self):
print 'D.bar'
class C(D):
def bar(self):
print 'C.bar'
class B(D):
def bar(self):
print 'B.bar'
class A(B, C):
def bar(self):
print 'A.bar'
a = A()
# 执行bar方法时
# 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错
# 所以,查找顺序:A --> B --> D --> C
# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
a.bar()
新式类多继承
class D(object):
def bar(self):
print 'D.bar'
class C(D):
def bar(self):
print 'C.bar'
class B(D):
def bar(self):
print 'B.bar'
class A(B, C):
def bar(self):
print 'A.bar'
a = A()
# 执行bar方法时
# 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错
# 所以,查找顺序:A --> B --> C --> D
# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
a.bar()
经典类:
先去A类中查找.如A类中没有.则去B类中找.如果B类中么有.继续去D类中找.如果D类中么有.继续去C类中找.如果还是未找到.报错
新式类:
先去A类中查找.如A类中没有.则去B类中找.如果B类中么有.继续去C类中找.如果C类中么有.继续去D类中找.如果还是未找到.报错
注意:在上述查找过程中.一旦找到.则寻找过程立即中断.便不会再继续找了
PS:python3以后版本都是广度查询