# OOP 實(shí)戰(zhàn)通過(guò)簡(jiǎn)單的case 更好的理解OOP思想, 如果使用代碼,可以下載附件修改為.py即可
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2017年3月24日
@author: fWX457893
'''
# 類的封裝
class Student(object):
# __ 雙下劃線可使變量私有變成private,只有在函數(shù)每部可以訪問(wèn),外部不能訪問(wèn),
def __init__(self, name, score, **kw):
self.__name = name
self.__score = score
self.kw = kw
# 如果還想要讓外部訪問(wèn),可是添加方法 get_name, get_score, get_kw
def get_name(self):
return self.__name
def get_score(self):
return self.__score
# 又要允許外部代碼修改score怎么辦?可以再給Student類增加set_score方法:
def set_name(self, name):
self.__name = name
def set_score(self, score):
if 0 <= score <= 100:
self.__score = score
else :
raise ValueError('bad score')
def print_score(self):
print('%s: %s \t %s' % (self.__name, self.__score, self.kw))
def get_grade(self):
if self.__score >= 90:
return 'A'
elif self.__score >= 60:
return 'B'
else :
return"C"
bart = Student('fyh', 100, address='bj')
bart.print_score()
bart.set_score(10)
bart.print_score()
grade = bart.get_grade()
print grade
# 表面上看,外部代碼“成功”地設(shè)置了__name變量,但實(shí)際上這個(gè)__name變量和class內(nèi)部的__name變量不是一個(gè)變量!
# 內(nèi)部的__name變量已經(jīng)被Python解釋器自動(dòng)改成了_Student__name,而外部代碼給bart新增了一個(gè)__name變量。不信試試:
bart.__name = 'new name'
print bart.__name
bart.print_score()
# -------------------------------------------------------------------------------
# OOP 的 繼承和多態(tài)
class Animal(object):
def run(self):
print 'Animal is running...'
def eat(self):
print('Eating food...')
class Dog(Animal):
def run(self):
print('Dog is running...')
def eat(self):
print('Dog eating meat...')
class Cat(Animal):
def run(self):
print('Cat is running...')
def eat(self):
print('Cat eating fish...')
ani = Animal()
ani.run()
cat = Cat()
cat.run()
def run_eat(animal):
animal.run()
animal.eat()
run_eat(Animal())
run_eat(Dog())
run_eat(Cat())
'''
對(duì)于一個(gè)變量,我們只需要知道它是Animal類型,無(wú)需確切地知道它的子類型,就可以放心地調(diào)用run()方法,
而具體調(diào)用的run()方法是作用在Animal、Dog、Cat還是Tortoise對(duì)象上,由運(yùn)行時(shí)該對(duì)象的確切類型決定,
這就是多態(tài)真正的威力:調(diào)用方只管調(diào)用,不管細(xì)節(jié),而當(dāng)我們新增一種Animal的子類時(shí),
只要確保run()方法編寫正確,不用管原來(lái)的代碼是如何調(diào)用的。這就是著名的“開(kāi)閉”原則:
對(duì)擴(kuò)展開(kāi)放:允許新增Animal子類;
對(duì)修改封閉:不需要修改依賴Animal類型的run_twice()等函數(shù)。
繼承還可以一級(jí)一級(jí)地繼承下來(lái),就好比從爺爺?shù)桨职?、再到兒子這樣的關(guān)系。而任何類,最終都可以追溯到根類object,這些繼承關(guān)系看上去就像一顆倒著的樹(shù)。
'''
#
'''
靜態(tài)語(yǔ)言 vs 動(dòng)態(tài)語(yǔ)言
對(duì)于靜態(tài)語(yǔ)言(例如Java)來(lái)說(shuō),如果需要傳入Animal類型,則傳入的對(duì)象必須是Animal類型或者它的子類,否則,將無(wú)法調(diào)用run()方法。
對(duì)于Python這樣的動(dòng)態(tài)語(yǔ)言來(lái)說(shuō),則不一定需要傳入Animal類型。我們只需要保證傳入的對(duì)象有一個(gè)run()方法就可以了:
class Timer(object):
def run(self):
print('Start...')
這就是動(dòng)態(tài)語(yǔ)言的“鴨子類型”,它并不要求嚴(yán)格的繼承體系,一個(gè)對(duì)象只要“看起來(lái)像鴨子,走起路來(lái)像鴨子”,那它就可以被看做是鴨子。
Python的“file-like object“就是一種鴨子類型。對(duì)真正的文件對(duì)象,它有一個(gè)read()方法,返回其內(nèi)容。但是,許多對(duì)象,只要有read()方法,都被視為“file-like object“。
許多函數(shù)接收的參數(shù)就是“file-like object“,你不一定要傳入真正的文件對(duì)象,完全可以傳入任何實(shí)現(xiàn)了read()方法的對(duì)象。
'''
class Husky(Dog):
def run(self):
print('Husky is running...')
def eat(self):
print('Husky eating meat...')
# 使用isinstance()
# 對(duì)于class的繼承關(guān)系來(lái)說(shuō),使用type()就很不方便。我們要判斷class的類型,可以使用isinstance()函數(shù)。
# object -> Animal -> Dog -> Husky
animal = Animal()
dog = Dog()
husky = Husky()
print isinstance(husky, Husky), isinstance(husky, Dog), isinstance(husky, Animal)
# True True True husky 是husky dog object 但是 dog 不是husky 是dog object
#定義一個(gè)父類一個(gè)子類
class Province(object):
def __init__(self,proname):
self.proname=proname
def ps(self):
print('I am in %s'%self.proname)
class City(Province):
def __init__(self,proname,cityname):
self.cityname=cityname
Province.__init__(self,proname)
def ps1(self):
print('I\'m in %s-%s' %(self.proname,self.cityname))
#定義一個(gè)獨(dú)立的類
class Timer(object):
def ps(self):
print('我不屬于Province類或其子類,但我有ps方法我同樣可以被調(diào)用')
def ps1(self):
print('我不屬于Province類或其子類,但我有ps1方法我同樣可以被調(diào)用')
#定義一個(gè)函數(shù)
def func(x):
x.ps()
x.ps1()
#調(diào)用部分
func(City('北京','海淀'))
func(Timer())
# 部分參考廖神的python教程。
Python的OOP面向?qū)ο?
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
相關(guān)閱讀更多精彩內(nèi)容
- 類的構(gòu)造方法,init是種初始化函數(shù),也稱構(gòu)造函數(shù)。 super綁定函數(shù)的多重測(cè)試,綁定有多種。 python中一...
- 面向?qū)ο蟮母呒?jí)編程-使用slots【下面的筆記簡(jiǎn)直我就是不要face了】 在這一章里,因?yàn)闆](méi)有復(fù)習(xí), 有點(diǎn)看不懂了...
- python面向?qū)ο蟪绦蛟O(shè)計(jì)(OOP) 類定義語(yǔ)法class className: 在python中可以...
- 學(xué)習(xí)了面向?qū)ο蠛缶幊趟悸返母淖? 老師說(shuō)學(xué)習(xí)面向?qū)ο缶幊讨拔覀冺敹嗨闶强催^(guò)代碼,真正學(xué)過(guò)之后才算是寫過(guò)代碼...
- 1.什么是繼承?繼承有什么用處? 在OOP程序設(shè)計(jì)中,當(dāng)我們定義一個(gè)class的時(shí)候,可以從某個(gè)現(xiàn)有的cla...