目錄
六、繼承重用父類方法得兩種方式
繼承
封裝
多型
繼承是一種建立新類的方式,新建的類可以繼承乙個或多個父類(python支援多繼承),父類又可稱為基類或超類,新建的類稱為派生類或子類。父類的屬性和方法,子類中也有。
格式就是子類名加括號,括號內是父類名:
class a:
pass
class b(a): # b就繼承了a
pass
這裡提一下新式類和經典類的區別
新式類:只要繼承了object類,就是新式類,在python3中,預設都是新式類
在python2中,需要顯示指定繼承object才是新式類
經典類:在python2中,沒有繼承object的類,就是經典類
python3中沒有經典類
class a(object):
pass
class b(a):
pass
# b繼承了a這個類,單繼承
class c(a,b):
pass
# c繼承了a和b,多繼承
類的其他內建屬性:__名字__
print(b.__dict__) # 類的屬性和方法
print(b.__name__) # 類名
print(b.__bases__) # 類的父類
繼承中屬性的查詢順序:
先在物件中找---》子類中找---》父類中找(多繼承父類的話,從左到右,先從第乙個父類找)---》父類中找不到就報錯
# 這裡首先利用物件導向寫乙個老師和學生的類,他們的基類都是人
# 這裡不用繼承
class person:
school = 'oldboy'
class teacher(person):
def __init__(self,name,age,level):
self.name=name
self.age=age
self.level=level
class student(person):
def __init__(self,name,age,course):
self.name=name
self.age=age
self.course=course
# 以上**老師和學生的類都有共同屬性:name和age,那就可以把這兩個屬性放到人的類中,然後老師和學生的類來繼承人的類
class person(object):
school = 'oldboy'
def __init__(self, name, age):
self.name = name
self.age = age
class teacher(person):
pass
class student(person):
pass
# 這樣就減少了**的冗餘
注意:子類例項化會自動呼叫__init__
方法,如果子類中沒有,會去父類中找,父類中有幾個引數就要傳幾個引數
# 多層繼承:一層一層的繼承下去
class a:
a="aaaa"
class b(a):
a="bbb"
class c(b):
a="ccc"
pass
class d(c):
a = "ddd"
pass
# 多繼承
class a:
a="aaaa"
class b:
a="bbb"
class c:
a="ccc"
pass
class d(a,b,c): # 類 d 繼承了上面多個類
a = "ddd"
pass
# 多繼承的多層
class a:
a="aaaa"
class b(a):
a="bbb"
class c(b):
a="ccc"
pass
class d(a,b,c):
a = "ddd"
pass
繼承的菱形問題(顯示的都繼承乙個類,不是object類):新式類和經典類的查詢順序是不一樣的。
新式類(py3中全是新式類):廣度優先---從左側開始,一直往上找,找到菱形的頂點結束(不包括菱形頂點),繼續下乙個繼承的父類往上找,找到菱形的頂點結束(不包括菱形頂點),最後找到菱形頂點。
不出現菱形問題:正常查詢
#繼承的菱形問題:新式類和經典類的查詢順序是不一樣的
#新式類的查詢屬性:廣度優先
#經典類:深度優先
class g(object):
a = "ggg"
pass
class f(g):
# a = "fff"
pass
class e(g):
# a = "eee"
pass
class d(g):
# a = "ddd"
pass
class c(f):
# a="ccc"
pass
class b(e):
# a="bbb"
pass
class a(b,c,d):
# a="aaaa"
pass
a=a()
print(a.a)
以上**就出現新式類的菱形問題,查詢順序就是廣度優先:
經典類的菱形問題,查詢順序就是深度優先:
mro:列表,繼承順序查詢列表(只在新式類中有)
print(a.mro())
print(a.__mro__)
# 兩種方式都可以
# 父類中object寫與不寫,在py3中沒有區別,
# 有的人在py3中這麼寫,為了向下相容
# 呼叫父類方法的第一種方式 :指名道姓的方式,跟繼承關係無關
class person(object):
def __init__(self,name,age):
self.name=name
self.age=age
def init_1(self,name,age):
self.name=name
self.age=age
class student:
school = 'yyyy'
def __init__(self,name,age,course):
person.__init__(self,name,age) #指名道姓的使用person的__init__方法,preson中有三個引數就必須傳三個
init_1(self,name,age)
self.course=course
stu=student('nick',19,'python')
print(stu.name)
class person(object):
def __init__(self,name,age):
self.name=name
self.age=age
class student(person):
school = 'yyyy'
def __init__(self,name,age,course):
#super()相當於得到了乙個特殊物件,第乙個引數不需要傳,呼叫繫結方法,會把自己傳過去
########## self不需要傳,不需要傳
super().__init__(name,age)
#看到別人這麼寫:super(類名,物件) 在py3中為了相容py2
#在py3中這麼寫和省略寫法完全一樣
#在py2中必須super(student,self)寫
# super(student,self).__init__(name,age)
self.course=course
stu=student('nick',19,'python')
print(stu.name)
print(stu.age)
print(stu.course)
有繼承關係的時候,通常用super關鍵字方法;
指名道姓的方法在以下情況下用:
物件導向特性 繼承
1 子類繼承父類的方法和字段 class computer 子類,膝上型電腦類 class notecomputer extends computer 2 不需要父類的字段和方法,那麼可以採用重寫的方法覆蓋掉父類的方法。class computer 子類,膝上型電腦類 class notecompu...
c 物件導向特性之繼承(2)
繼承共分為三種 public 公有繼承 protected 保護繼承 private 私有繼承 於此同時,每個類中的成員也具有public,protected,private這三種特性,每種特性下的成員在每種繼承方式下都有不同的結果,總結如下 繼承方式 本來的屬性 轉換後的屬性 public pub...
物件導向三大特性之繼承
1 author kelvin2 date 2019 1 16 18 5734 class father 5 money 100067 def init self,name 8print 父類的init方法.9 self.name name 1011 defteach self 12print s ...