changed 5 years ago
Linked with GitHub
tags: python

物件導向程式設計

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

專有名詞介紹

類別(class)

  • 某種事物的概念(例如:手機、電腦),說明該事物內部有什麼屬性及方法
  • 定義了一件事物的抽象特點
  • 藍圖、設計稿、模子

物件(object)

  • 某種事物的成品(例如:sony手機、hp手機,asus筆電、acer筆電
  • 實體

屬性(properties)

  • 類別中的變數,我們也稱作屬性

方法(functions)

  • 類別中的函數,我們也稱作方法

定義(definition)

  • 說明該類別有什麼屬性及方法

宣告(declaration)

  • 根據某種類別實做出一個物件

公開(public)

  • 預設所有方法、屬性都是公開
  • 可讓在類別或函數之外透過類別或列使用,例如:dog.name, dog.run()

私有(private)

  • 方法或屬性之前加2個底線,例如:__name
  • 實踐 封裝(Encapsulation) 概念
    * 避免不小心修改到內部屬性
    * 簡化使用者操作
    * 隱藏內部執行步驟

層次

  • 套件 > 模組 > 類別 > 方法(函數) > 屬性(變數)
  • 以上層次沒有絕對必然性
    • 可以在模組或類別中直接設定屬性
    • 可以在模組中直接設定方法

注意事項

  • 一定要先定義類別才能宣告該類別的物件
  • 習慣上類別第一個字大寫,例如:Vehicle
  • 類別裡面的方法定義,第一個參數一定是self關鍵字
  • 類別中可以設定子類別
  • 函數中可以設定子函數

範例一

定義一個類別叫做「車」,實作「汽車、卡車」物件

class Vehicle: doors = 4 max_speed = 160 fuel = '95' car = Vehicle() print('car.doors: ', car.doors) print('car.max_speed: ', car.max_speed) print('car.fuel: ', car.fuel) truck = Vehicle() print('truck.doors: ', truck.doors) print('truck.max_speed: ', truck.max_speed) print('truck.fuel: ', truck.fuel)

範例二:根據參數初始化物件屬性

__init__()

  • 當透過類別實作物件時,第一時間會執行的動作
  • 可設定物件屬性的初始值或預設執行哪些程序
class Vehicle: def __init__(self, doors, max_speed, fuel): self.doors = doors self.max_speed = max_speed self.fuel = fuel car = Vehicle(4, 200, '95') print('car.doors: ', car.doors) print('car.max_speed: ', car.max_speed) print('car.fuel: ', car.fuel) print() truck = Vehicle(2, 160, '柴油') print('truck.doors: ', truck.doors) print('truck.max_speed: ', truck.max_speed) print('truck.fuel: ', truck.fuel)

觀念

類別中的函數若要指定是該類別的屬性,記得要加self
沒加self會被認為是函數內的變數

class Car: doors = 4 def set(self, abc): doors = abc car = Car() print(car.doors) # 4 car.set(5) print(car.doors) # 4
class Car: doors = 4 def set(self, abc): self.doors = abc car = Car() print(car.doors) # 4 car.set(5) print(car.doors) # 5

範例三 為何需要私有屬性或方法

class Mobile: def __init__(self): self.__password = '12345' self.__alarm = None def set_alarm(self, time): if time > 9 and time < 23: self.__alarm = time return 'alarm is setting' else: return 'time is not accept' def show_password(self): name = input('input your name: ') if name == 'amos': return self.__password else: return 'your are not owner' myphone = Mobile() time = int(input('alarm time: ')) print(myphone.set_alarm(time))

繼承(inheritance)

  • 從既有類別(父類別)產生新類別(子類別),並擴充子類別自身的屬性與方法
  • 修改父類別,底下的子類別也會被調整
  • 減少重複輸入既有類別的屬性與方法
  • 若子類別同名的屬性與方法會覆蓋父類別原有的屬性與方法
  • 當不同子類別都會使用的屬性或方法就可以放到父類別來定義
class Animal: def __init__(self, head, hand, foot): self.head = head self.hand = hand self.foot = foot def run(self): return '使用身體快速移動' class Human(Animal): def run(self): return '使用腳奔跑' class Bird(Animal): def __init__(self, head, wing, foot): self.head = head self.wing = wing self.foot = foot def run(self): return '使用雙腳奔跑' def fly(self): return '使用翅膀飛翔' animal = Animal(1, 0, 4) animal.run() human = Human(1, 2, 2) human.run() bird = Bird(1, 2, 2) bird.run() bird.fly()

引用上一輩的初始化方法

class Animal: def __init__(self, head, hand, foot): self.head = head self.hand = hand self.foot = foot def run(self): return '使用身體快速移動' class Monkey(Animal): def __init__(self, head, hand, foot, food='banana'): super().__init__(head, hand, foot) # 呼叫上一輩的初始化方法 self.food = food animal = Animal(1, 0, 4) print(animal.run()) monkey = Monkey(1, 2, 2, 'fruit') print(monkey.food) print(monkey.head) print(monkey.run())

鍊狀繼承(chained inheritance)

  • 父類別的屬性、方法可以傳給子類別,子類別再傳給孫類別
  • 修改父類別,底下的子類別、孫類別也會同時調整
class Animal: def __init__(self, head, hand, foot): self.head = head self.hand = hand self.foot = foot def run(self): return '使用身體快速移動' class Human(Animal): def run(self): return '使用腳奔跑' class Bird(Animal): def __init__(self, head, wing, foot): self.head = head self.wing = wing self.foot = foot def run(self): return '使用雙腳奔跑' def fly(self): return '使用翅膀飛翔' class Penguin(Bird): def fly(self): return '無法使用翅膀飛翔' def swim(self): return '使用翅膀游泳' animal = Animal(1, 0, 4) print(animal.head, animal.hand, animal.foot) print(animal.run()) human = Human(1, 2, 2) print(human.head, human.hand, human.foot) print(human.run()) bird = Bird(1, 2, 2) print(bird.head, bird.wing, bird.foot) print(bird.run()) print(bird.fly()) penguin = Penguin(1, 2, 2) print(penguin.head, penguin.wing, penguin.foot) print(penguin.run()) print(penguin.fly()) print(penguin.swim())

多重繼承(multiple inheritance)

  • 子類別可以繼承多個父類別的屬性與方法
class mobile: def __init__(self, phone_number): self.phone_number = phone_number def call(self, number): return '撥打' + number def receive(self, number): return '接通' + number + '來電' class PDA: def __init__(self, note): self.note = '備忘錄' def install(self, app_name): return '安裝' + app_name + '軟體' def uninstall(self, app_name): return '移除' + app_name + '軟體' class SmartPhone(mobile, PDA): pass smartPhone = SmartPhone('12345') print(smartPhone.phone_number) print(smartPhone.call('77788899944455')) print(smartPhone.receive('444551122')) print(smartPhone.install('台北等公車')) print(smartPhone.uninstall('台北等公車'))

範例四:(註一)

class Account: def __init__(self, number, name): self.number = number self.name = name self.balance = 0 def deposit(self, amount): #存款動作: amount代表存入金額 if amount <= 0: raise ValueError('must be positive') self.balance += amount def withdraw(self, amount): #取款動作: amount代表取款金額 if amount <= self.balance: self.balance -= amount else: raise RuntimeError('balance not enough') acct1 = Account('123–456–789', 'Justin') #開一個帳戶 acct1.deposit(100) acct1.withdraw(30) print(acct1.balance) #餘額是 70

範例: 日記軟體

軟體:

  • 屬性:
    • name:帳號
    • password:密碼
    • article:文章內容
    • logined:是否登入
  • 方法:
    • login:帳號登入
    • logout:帳號登出
    • change_pw:變更密碼
    • post:更新文章內容
    • read:讀取文章內容
class Software: def __init__(self): self.__name = 'admin' self.__password = 'admin' self.__article = None self.__logined = False self.__content = '' def login(self): name = input('請輸入帳號: ') password = input('請輸入密碼: ') if self.__name == name and self.__password == password: self.__logined = True print('you are login!', self.__logined) else: print('帳號或密碼錯誤,請重新輸入') def logout(self): self.__logined = False print('you are logout', self.__logined) def change_pw(self): if self.__logined: new_password = input('請輸入新密碼: ') new_password2 = input('請再輸入新密碼: ') if new_password == new_password2: self.__password = new_password print(self.__password) else: print('上下密碼不一致,請重新輸入') else: self.login() def post(self): if self.__logined: self.__content = input('請輸入文章內容: ') else: self.login() def read(self): if self.__logined: print(self.__content) else: self.login() mydictionary = Software() mydictionary.login() # mydictionary.logout() # mydictionary.change_pw() mydictionary.post() mydictionary.read()

備註

  1. 關於Python的類別(Class)基本篇

S20200609 來自amos老師的網站。物件導向程式設計

Select a repo