物件導向特性之 繼承

2022-07-23 11:21:15 字數 4654 閱讀 9943

目錄

六、繼承重用父類方法得兩種方式

繼承

封裝

多型

繼承是一種建立新類的方式,新建的類可以繼承乙個或多個父類(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 ...