1、面向對象的優點:
面向對象是一種結構化的編程方式,好處如下:
(1)通過封裝明確了內、外
(2)通過繼承+多態在語言層面支持了歸一化設計
歸一化設計原理:使用接口函數、一切皆文件
2、類的定義
類是一種數據結構,就好比一個模型,該模型用來表述一類事物(事物即數據和動作的結合體),用它來產生真實的物體(實例)
3、對象的定義
你看到的一切事物都是一個個的對象,可以把對象理解成爲一個具體的事物(擁有數據和動作的結合體)
4、類和對象的關係
對象都是由類產生的,上帝造人,首先有一個造人的模板,這個模板即人的類,然後上帝根據類的定義來生產一個個的人
5、實例化定義
由類生產對象的過程叫實例化,類實例化的結果就是一個對象,或者叫做一個實例(實例=對象)
6、面向對象設計:將一類具體事物的數據和動作整合到一起
7、面向對象編程:用了定義類+實例對象的方式去實現面向對象的設計
8、靜態方法
staticmethod靜態方法只是名義上的歸屬類,不能使用類變量和實例變量,是類的工具包
class Room:
def __init__(self,name,owner,width,length):
self.name=name
self.owner=owner
self.width=width
self.length=length
@property
def cal_area(self):
area=self.width * self.length
return area
@staticmethod
def wash_room():
print("這裏是洗浴室")
R1=Room("別墅","lalala",100,100)
print(R1)
#輸出結果:
<__main__.Room object at 0x1038f51c0>
9、組合
(1)定義:定義一個類,通過數據屬性形成一個實例化的對象,這就是組合
(2)用途:
- 各個做關聯
- 小的組成大的
10、面向對象三大特性:繼承、封裝、多態
(1)繼承
- 繼承分爲單繼承和多繼承
- 子類繼承了父類的所有屬性,如果重名,子類先執行自己內部定義
class ParentClass1:
pass
class ParentClass2:
pass
#單繼承
class SonClass1(ParentClass1):
pass
#多繼承
class SonClass2(ParentClass1,ParentClass2):
pass
(2)繼承和集合的選擇?
- 當類之間有顯著不同,較小的類是較大的類的組件的時候,用集合比較好
- 當類之間有很多相同的功能,提取這些共同的功能做成基類的時候,用繼承比較好,如下實例
class animal:
def eat(self):
pass
def drink(self):
pass
def la(self):
pass
def sa(self):
pass
class dog(animal):
def wang(self):
print("汪汪汪")
class cat(animal):
def miao(self):
print("喵喵喵")
(3)繼承的含義
- 繼承父類的方法,並且做出自己的改變或者擴展(代碼重用)
但是這種方法不太好,一般寫代碼規範耦合度越小越好,這樣是強耦合 - 聲明於某個子類兼容於某父類,定義一個接口類,子類繼承接口類,並且實現接口中定義的方法
class animal:
def eat(self):
pass
def drink(self):
pass
class dog(animal):
def eat(self):
print("c喫")
def drink(self):
print("喝")
def wang(self):
pass
說明:
- 接口繼承實質上是要求作出一個良好的抽象,這個抽象規定了一個兼容接口,使得外部調用者無需關心具體細節,可一視同仁的處理實現特定接口的所有對象——這在程序設計上,叫做”歸一化“
- 接口類的存在是爲了規範子類
- 接口繼承不同於普通繼承,接口繼承中子類必須繼承父類的方法,父類方法僅定義即可,具體行爲可以在子類中實現,如上。
- 接口繼承需要導入一個abc模塊,父類加上對子類的限制,並且在父類方法加裝飾器,如下
import abc
class animal(metaclass=ABCMeta):
@abc.abstractmethod
def eat(self):
pass
class dog(animal):
@abc.abstractmethod
def eat(self):
print("c喫")
def wang(self):
pass
(4)繼承順序
- Python的類可以繼承多個類,Java和C#中只能繼承一個類
- Python的類如果繼承了多個類,繼承的順序有兩種:深度優先和廣度優先,在python3中都是按照廣度優先的方式
- 深度優先:按照一側找到底,再從另一側開始找
- 廣度預先:按照一側開始找,找到不包含父類的前一類,再從另一側開始找
當類是經典類的時候,多繼承的情況下,會按照深度優先的方式查找
當類是新式類的時候,多繼承的情況下,會按照廣度優先的方式查找
區分經典類和新式類:
新式類包含很多功能,從寫法上父類繼承了object類測試新式類,否則是經典類
經典類:
class A:
pass
class B(A):
pass
新式類:
class A(object):
pass
class B(A):
pass
(5)子類調用父類方法,可以直接引用父類的__ init__()函數
class Vehicle:
Country="China"
def __init__(self,name,speed,load,power):
self.name=name
self.speed=speed
self.load=load
self.power=power
def run(self):
print("開動啦")
class Subway(Vehicle):
def __init__(self,name,speed,load,power,line):
Vehicle.__init__(self,name,speed,load,power)
self.line=line
def show_info(self):
print(self.name,self.speed,self.load,self.power,self.line)
S1=Subway("地鐵","543m/s","10000000","電","13號線")
S1.show_info()
輸出結果:
地鐵 543m/s 10000000 電 13號線
也可以直接用supper()調用,就把Vehicle.__init__變成supper.init