python——面向物件(中)
1.單繼承
在程式中,繼承描述的是事物之間的所屬關係,例如貓和狗都屬於動物,
程式中便可以描述為貓和狗繼承自動物。
同理,波斯貓和巴釐貓都繼承自貓,而沙皮狗和斑點狗都繼承自狗
# 定義一個父類,如下:
class Cat(object):
def __init__(self, name, color="白色"):
self.name = name
self.color = colordef run(self):
print("%s--在跑"%self.name)
# 定義一個子類,繼承Cat類如下:
class Bosi(Cat):
def setNewName(self, newName):
self.name = newName
def eat(self):
print("%s--在吃"%self.name)
bs = Bosi("印度貓")
print('bs的名字為:%s'%bs.name)
print('bs的顏色為:%s'%bs.color)
bs.eat()
bs.setNewName('波斯')
bs.run()
雖然子類沒有定義__init__方法,但是父類有,所以在子類繼承父類的時候這個方法就被繼承了,所以只要建立Bosi的物件,就預設執行了那個繼承過來的__init__方法
子類在繼承的時候,在定義類時,小括號()中為父類的名字 父類的屬性、方法,會被繼承給子類 私有的屬性,不能通過物件直接訪問,但是可以通過方法訪問
私有的方法,不能通過物件直接訪問 私有的屬性、方法,不會被子類繼承,也不能被訪問 一般情況下,私有的屬性、方法都是不對外公佈的,往往用來做內部的事情,起到 安全的作用
棧 主要執行的是函式 堆 主要存放的是物件
類:一些具有相同特徵行為屬性的物件的統稱
物件:該類中的具體例項
類是物件的一種描述
在描述類的時候,
class Person:
#在建立物件時 對物件進行初始化
def __init__(self):
self.name="張三"
self.age=18
def speak(self):
print("哈哈")
#建立一個Person的物件
p=Person()
#如果在類的描述中 不存在屬性的話
#屬於動態新增屬性
#將屬性新增到該物件的所屬空間中
#
#否則,更改屬性
p.name="李四"
p.age=20
print(p.name)
print(p.age)
p1=Person()
print(p1.name)
prin(p1.age)
print("="*20)
class Dog:
def __init__(self,typ,color):
self.typ=typ
self.color=color
self.age=20
def jiao(self):
print("旺旺"+self.typ+self.color)
def __str__(self):
return self.typ+self.color+str(self.age)
'''
1.開闢空間 分配地址
2.為物件進行初始化工作
'''
d=Dog("拉布拉多","黃色")
d.jiao()
d1=Dog("哈士奇","黑色")
d1.jiao()
print(d1)
#區別哪的函式呼叫,python中會自動指向呼叫的地址
面向物件與之前的面向過程比
優點:1.將資料和指令結合,方便操作
2.從程式設計思想上來說 更加符合我們的實際思考習慣
比如:客戶 商品 訂單 商家
如果沒有物件怎麼辦?
那就建立物件 建立好之後,就可以後面使用,一勞永逸面向物件:三大特徵
封裝
random.random() 只需要獲取隨機值就行,就像吃飯付錢,不管廚師的操作
繼承
多型
引入隱藏資料的原因:
如果屬性沒有私有化 外界直接訪問(取值,修改)
但是修改可能會改成錯誤資料 會影響後續程式的執行
所以,不允許外界直接訪問屬性 __必須私有化
間接 提供Setter Getter函式 __ 表示隱藏資料,外界只能讀取,不能進行操作(是兩個下劃線呦)
class Person:
def __init__(self):
self.__age=10 #隱藏資料 已經被隱藏,不能被呼叫
def getAge(self): #p.__age
#對外來說,訪問不了,但對於get可以,可以間接引用
return self.__age
def setAge(self,age):
if age<0 or age>150:
print("非法資料")
self.__age=0
else:
self.__age=age #p.__age=30
p=Person()
#這裡面 不管是age 還是__age 都找不到
# p.age=-20 編譯正確,直接對age的值進行操作,有些冒險
#p.__age=-20 編譯錯誤,顯示找不到
#print(p.__age)
p.__age=-20
p.setAge(30)
print(p.getAge())
為什麼要刪除物件?
如果物件不再被使用時,那麼該物件就會被清理
class Person:
def __init__(self):
print("a person has created!")
def __init__(self):
print("a person has deleted!")
def show(self):
p=Person() #建立好下個物件後,此物件不再被使用
p=Person()
p1=Person()
del p1
print("="*20)
a=Person()
# 執行完 del c 就會刪除一個物件不再引用,就會被刪除,預設垃圾回收機制
c=a
del a
#a.show()
del b
#b.show()
del c
#c.show()
關於繼承:
繼承 is a 從屬
抽取多個類之間相同的部分時
注意所抽取出來的父類 基類 超類
繼承 從屬關係 是一個系列面向物件程式設計 都有父類 如果沒有明顯寫出 表示object
class Person(object):
def __init__(self,name,age):
self.name=name
self.age=age
def eat(self):
print(self.name+"在吃飯.....")
class Student(Person):
def study(self):
print(self.name+"在學習....")
class Teacher(Person):
def teach(self):
print(self.name+"在上課.....")
p=Person("張三",18)
p.eat() #可以
#p.study() #不可以
#p.teach() #不可以 是其子類
p1=Student("李梅",20)
p1.eat()
p1.study()
p2=Teacher("張雪峰")
p1.eat()
p1.teach()
p2.study() #並沒有在teacher裡定義,錯誤
#注意:python 所有東西兼物件
下面,舉個簡單的栗子:
'''
class SortUtil:
def sort():
swipe(a,b)
def __swipe(a,b):
#屬於排序類的演算法,可能會被別的函式呼叫,不需要對外界呼叫,不是本質上的真正功能
su=SortUtil()
su.sort([])