敲黑板,面向物件的三大特征:
封裝、繼承和多型,
封裝
封裝性
封裝就是隱藏底層的實作細節,只提供公有的介面供外界訪問, 這樣當底層實作細節改變的時候,就不會對外界造成影響,
私有屬性
在類的設計角度,我們可以將屬性或方法(類的成員)定義為私有,來實作封裝,
私有成員只能在定義類的內部進行訪問,在類外是無法進行訪問的,
私有成員的定義方式:以_進行開頭,但是不能以兩個或多個進行結尾,
class Computer:
def __init__(self,cpu):
self.cpu = cpu
# 私有屬性(私有的實體屬性)
self.__memory = 1024
# 在定義私有屬性“類的內部”,可以訪問私有成員
#print(self.__memory)
c = Computer("某cpu")
c.__memory # 可以發現私有屬性不能夠在外部直接訪問
結果如下:

class Computer:
def __init__(self,cpu):
self.cpu = cpu
# 私有屬性(私有的實體屬性)
self.__memory = 1024
# 在定義私有屬性“類的內部”,可以訪問私有成員
print(self.__memory)
def x(self):
pass
# 如果想要采用公有的方法(在類的外部),訪問私有屬性,需要額外定義兩個方法
def set_memory(self,memory):
self.__memory = memory
def get_memory(self):
return self.__memory
c = Computer("某cpu")
c.get_memory()
結果如下:

為什么非要定義為:私有屬性呢?定義為一般的實體屬性不是也可以嗎?
原因在于:定義為私有屬性后,當我們以后需要對類中某屬性做出修改時,只需要在內部修改,而不會對外部的使用者,產生影響,
假如不將memory定義為私有屬性
class Computer:
def __init__(self, cpu):
self.cpu = cpu
self.memory = 1024
c = Computer("某cpu")
print(c.memory)
# 1024
c.memory = 6666
print(c.memory)
# 6666

假如說,由于某種業務要求,需要將memory改為memory2,那么,我們不僅需要在內部進行修改,同時外部呼叫者也需要進行修改,假如你有很多粉絲使用這個,估計都會罵你(假如代碼中有很多行都需要將memory改為memory2)
其實,私有屬性也并非真正的私有,只是將名稱進行了一下偽裝而已,
偽裝成了:類名_私有屬性的名稱
這就意味著,在類的外部,我們可以通過真實名稱對私有屬性進行訪問,
但是,不建議這么做,偽裝就是為了保證封裝性,而你非要去捅破,
class Computer:
def __init__(self,cpu):
self.cpu = cpu
self.__memory = 1024
c = Computer("某cpu")
c.__memory
c._Computer__memory # 切記不要這么做,這樣做破壞了封裝性
結果如下:

繼承
繼承之前
class PythonTeacher:
def __init__(self,name,group):
self.name = name
self.group = group
def introcude(self):
print(f"我的名字是{self.name},所在小組是{self.group}")
def teach(self):
print("打開pycharm")
print("輸入代碼")
print("知識點講解")
class JaVaTeacher:
def __init__(self,name,group):
self.name = name
self.group = group
def introcude(self):
print(f"我的名字是{self.name},所在小組是{self.group}")
def teach(self):
print("打開eslipse")
print("輸入代碼")
print("知識點講解")
實作繼承
繼承體現的是一般與特殊的關系,如果兩個類A與B,A(蘋果)是一種特殊的B(水果),則我們就稱A繼承了B,A就是子類,B就是父類,
子類一旦繼承了父類,子類就會成為一種特殊的父類,子類就會具備父類的一切特征,因此,父類能夠做的事情,子類也可以做到,
子類繼承了父類,子類就會繼承父類中定義的成員,就好象子類中自己定義了一樣,
class Fruit:
def show(self):
print("水果")
# 繼承,在定義類時,給出繼承的父類
class Apple(Fruit):
pass
f = Fruit()
f.show()
a = Apple()
a.show()
結果如下:

定義類時,若沒有顯示的繼承任何類,則表明繼承object類,object是python中最根層次的類,
我們可以將公共的功能提取出來,放入父類中,然后使用每一個子類去繼承父類,這樣,就無需將這些公共的功能分別放在子類中實作,從而避免了代碼的重復性,
子類繼承父類,子類可以吸收“父類的功能”,此外,子類還可以增加自己特有的功能,如果父類的功能對于子類來說不適用,子類就可以改造(重寫)父類中的功能,
class Bird:
def fly(self):
print("鳥飛")
def describe(self):
print("有羽毛,無牙齒,蛋生")
class Ostrich(Bird):
# 父類中的fly功能,不適合鴕鳥,因此,子類需要對父類的功能進行修改
def fly(self):
print("不會飛")
# 子類增加自己特有的功能
def run(self):
print("高速奔跑")
c = Ostrich()
c.fly(),c.describe(),c.run()
結果如下:

成員繼承
子類可以繼承父類中定義的:類屬性、實體屬性;類方法、實體方法;靜態方法,
class Father:
class_attr = 1
def __init__(self):
self.instance_attr = 2
def instance_method(self):
pass
@classmethod
def class_method(cls):
pass
@staticmethod
def static_method():
pass
class Son(Father):
pass
s = Son()
然后子類就可以呼叫父類的類屬性、實體屬性;類方法、實體方法;靜態方法,

對于父類中的實體屬性,我們需要留意,如果子類中定義了自己的init方法,則不會呼叫父類的init方法,因此,父類方法中系結的實體屬性,就不會系結到子類物件上,也就是說父類的實力屬性,子類不會得到繼承,
class Father:
class_attr = 1
def __init__(self):
self.instance_attr = 2
def instance_method(self):
pass
@classmethod
def class_method(cls):
pass
@staticmethod
def static_method():
pass
class Son(Father):
def __init__(self):
pass
so = Son()
so.instance_attr
結果如下:

有時候,父類的初始化,可能"并不完全適合于"子類,這是,子類需要定義自己的init方法,
"并不完全適合于"指的是:父類中,有的實體屬性適合雨子類,有的不適合于子類,子類中既要定義自己的init方法,又想使用父類中部分實體屬性,那么該怎么做呢?
class Person():
delf __init__(self,name,age):
self.name = name
self.age = age
class Student(Person):
delf __init__(self,name,age,id):
self.name = name
self.age = age
self.id = id
# 父類的初始化不完全適合于子類,但是,也沒有完全不適合于子類
整改:在子類的init方法中,去呼叫父類的init方法,這樣可以"避免代碼重復",
super()方法登場
class Person():
def __init__(self,name,age):
self.name = name
self.age = age
class Student(Person):
def __init__(self,name,age,id):
# 呼叫父類的__init__方法
super().__init__(name,age) # 呼叫父類的__init__方法
self.id = id
s = Student("梁某人",18,2017011)
s.name,s.age,s.id
結果如下:

私有屬性的繼承
實際上,私有屬性也是可以被子類繼承的,只不過,子類繼承的不是私有屬性本來的名字,而是私有屬性偽裝后的名字,
雖然子類可以繼承并訪問父類的私有屬性,但是不建議這么做,既然是私有的,肯定是不愿意我們去訪問的,
class Father:
def __m(self):
print("私有方法")
class Son(Father):
def p(self):
# 通過偽裝之后的名字,進行訪問
self._Father__m()
s = Son()
s.p()
結果如下:

兩個關于繼承的內建函式
① isinstance(引數一,引數二)
- 第一個引數:物件;
- 第二個引數:型別;
- 含義:判斷第一個指定的引數指定的"物件",是否是第二個引數的指定型別(包括其父類性);
class Father:
pass
class Son(Father):
pass
f = Father()
s = Son()
來檢測一下:

② issubclass()
- 第一個引數:型別;
- 第二個引數:型別;
- 含義:判斷第一個指定的引數型別,是否是第二個引數的指定型別(或者是其子型別);
class Father:
pass
class Son(Father):
pass
f = Father()
s = Son()
再來檢測一下:

重寫
當父類中的成員,對子類不完全適用時,子類就可以重新定義該成員,
class Bird:
def fly(self):
print("鳥飛")
class Ostrich(Bird):
# 父類中的fly功能,不適合鴕鳥,因此,子類需要對父類的功能進行修改
def fly(self):
print("不會飛")
# 子類增加自己特有的功能
def run(self):
print("高速奔跑")
o = Ostrich()
o.fly()
結果如下:

class Bird:
def fly(self):
print("鳥飛")
class Ostrich(Bird):
# 父類中的fly功能,不適合鴕鳥,因此,子類需要對父類的功能進行修改
def fly(self):
# 通過super()方法,可以實作對父類中同名方法的訪問
super().fly() # super()既可以呼叫父類中的私有屬性,也可以呼叫父類中的方法
print("不會飛")
o = Ostrich()
o.fly()
結果如下:

多重繼承
python中,一個子類可以繼承多個父類,多個父類的成員,都可以被子類所繼承,繼承多個父類使用 , 分割,
class Rectangle:
def area(self):
print("矩形求面積")
class Diamond:
def area(self):
print("菱形求面積")
class Square(Rectangle,Diamond): #總是按照這里的先后順序,一一繼承
def t(self):
self.area()
s = Square()
s.t()
結果如下:

class Rectangle:
def area(self):
print("矩形求面積")
class Diamond:
def area(self):
print("菱形求面積")
class Square(Diamond,Rectangle): #總是按照這里的先后順序,一一繼承
def t(self):
self.area()
s = Square()
s.t()
結果如下:

多繼承:按照繼承原則,每個父類看作一個分支,按照順序進行查找,深度優先,但是有一個原則:子類一定會在父類之前被搜索,
class Teacher:
def __init__(self,name,group):
self.name = name
self.group = group
def introcude(self):
print(f"我的名字是{self.name},所在小組是{self.group}")
def teach(self):
print("輸入代碼")
print("知識點講解")
class PythonTeacher(Teacher):
def __init__(self,name,group):
super().__init__(name,group)
def teach(self):
print("打開pycharm")
super().teach()
class JaVaTeacher(Teacher):
def __init__(self,name,group):
super().__init__(name,group)
def teach(self):
print("打開eslipse")
super().teach()
p = PythonTeacher("梁某人", 10)
print(p.introcude(), p.teach())
結果如下:

j = JaVaTeacher("梁三",666)
print(j.group,j.teach())
結果如下:

多型
這個在python中基本體現不出來,知道面向物件有多型這個特性就行了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/275672.html
標籤:Python
