[TOC] 組合 什麼是組合 組合指的是一個對象中的屬性,是另一個對象 為什麼要使用組合 減少代碼冗餘 如何使用組合 繼承實現: 組合實現: 總結: 繼承是類與類的關係,一種什麼是什麼的關係,子類與父類是一種從屬關係 組合是對象與對象的關係,一種什麼有什麼的關係,一個對象擁有另一個對象 組合練習 封 ...
[TOC]
組合
什麼是組合
組合指的是一個對象中的屬性,是另一個對象
為什麼要使用組合
減少代碼冗餘
如何使用組合
繼承實現:
# 選課系統:老師類,學生類,老師與學生都有名字、年齡、性別
class People:
def __init__(self, name, age, sex, year, month, day):
self.name = name
self.age = age
self.sex = sex
self.year = year
self.month = month
self.day = day
def tell_birth(self):
print(f'''
=== 出生年月日 ===
年: {self.year}
月: {self.month}
日: {self.day}
''')
class Teacher(People):
def __init__(self, name, age, sex, year, month, day):
super().__init__(name, age, sex, year, month, day)
class Student(People):
def __init__(self, name, age, sex, year, month, day):
super().__init__(name, age, sex, year, month, day)
tea1 = Teacher('tank', 18, 'male', 2001, 1, 1)
tea1.tell_birth()
組合實現:
class People:
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
class Teacher(People):
def __init__(self, name, age, sex):
super().__init__(name, age, sex)
class Student(People):
def __init__(self, name, age, sex):
super().__init__(name, age, sex)
class Date:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
def tell_birth(self):
print(f'''
=== 出生年月日 ===
年: {self.year}
月: {self.month}
日: {self.day}
''')
tea1 = Teacher('tank', 18, 'male')
date_obj = Date(2001, 1, 1)
# 將date對象賦值給tea1對象的屬性date中
tea1.date = date_obj
tea1.date.tell_birth()
總結:
- 繼承是類與類的關係,一種什麼是什麼的關係,子類與父類是一種從屬關係
- 組合是對象與對象的關係,一種什麼有什麼的關係,一個對象擁有另一個對象
組合練習
'''
選課系統需求:
1.學生類,老師類, 學生和老師都有課程屬性, 每一門課程都是一個對象.
課程: 課程名字,課程周期,課程價錢
2.學生和老師都有選擇課程的功能, 還有列印所有課程的功能.
'''
class People:
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
def add_course(self, course_obj):
self.course_list.append(course_obj)
def tell_all_course(self):
# 拿到當前對象的課程列表,列表中存放的是一個個對象
for course_obj in self.course_list:
# 每一個課程對象查看課程信息的方法
course_obj.tell_course_info()
class Teacher(People):
def __init__(self, name, age, sex):
super().__init__(name, age, sex)
self.course_list = []
class Student(People):
def __init__(self, name, age, sex):
super().__init__(name, age, sex)
self.course_list = []
class Course:
def __init__(self, course_name, course_period, course_price):
self.course_name = course_name
self.course_period = course_period
self.course_price = course_price
def tell_course_info(self):
print(f'''
課程名稱:{self.course_name}
課程周期:{self.course_period}
課程價格:{self.course_price}
''')
tea1 = Teacher('tank', 18, 'male')
stu1 = Student('小明', 18, 'male')
python_obj = Course('python', 6, 2)
linux_obj = Course('linux', 6, 1)
tea1.add_course(python_obj)
tea1.add_course(linux_obj)
tea1.tell_all_course()
封裝
什麼是封裝
封裝指的是把一堆屬性封裝到一個對象中
存數據的目的是為了取,對象可以"."的方式,獲取屬性
為什麼要封裝
封裝的目的是為了方便存取,可以通過對象.屬性的方式獲取屬性
如何封裝
特征:變數 ---> 數據屬性
技能:函數 ---> 方法屬性
在類內部,定義一堆屬性(特征與技能)
訪問限制機制
什麼是訪問限制機制
在類內部定義,凡是以__
開頭的數據屬性與方法屬性,都會被python內部隱藏起來,讓外部不能直接訪問內部的__
開頭的屬性,如:__name = '小in'
訪問限制機制的目的
一堆隱私的屬性與不能被外部輕易訪問的屬性,可以隱藏起來,不能被外部直接調用
好處:對重要數據獲取的邏輯更加嚴謹,進而保護了數據的安全
隱私屬性可以通過封裝一個介面,在介面內做業務邏輯的處理,再把數據返回給調用者
class Foo:
# 數據屬性
__name = 'tank'
# 方法屬性
def __run(self):
print('running...')
def get_name(self):
return self.__name
def set_name(self):
self.__name = 'cwz'
foo = Foo()
# print(foo.__name)
foo.set_name()
print(foo.get_name())
print(foo._Foo__name) # _類名__屬性名
註意:在python中,不會強制限制屬性的訪問,類內部__開頭的屬性,只是做了一種變形。若想直接訪問,調用變形後的名字即可
class Teacher:
def __init__(self, name, age, sex):
self.__name = name
self.__age = age
self.__sex = sex
# 介面:列印用戶信息介面
def get_info(self):
user = input('user:').strip()
pwd = input('pwd:').strip()
if user == 'tank' and pwd == '123':
print(f'''
姓名:{self.__name}
年齡:{self.__age}
性別:{self.__sex}
''')
# 介面:修改用戶信息介面
def set_info(self, name, age, sex):
if not isinstance(name, str):
raise TypeError('名字必須要使用字元串')
if not isinstance(age, int):
raise TypeError('年齡必須要使用數字')
if not isinstance(sex, str):
raise TypeError('性別必須要使用字元串')
self.__name = name
self.__age = age
self.__sex = sex
t1 = Teacher('tank', 18, 'male')
t1.get_info()
class ATM:
# 插卡
def __insert_card(self):
print('開始插卡')
# 輸入密碼
def __input_pwd(self):
print('開始輸入密碼')
# 輸入取款金額
def __input_money(self):
print('輸入取款金額')
# 開始吐錢
def __get_money(self):
print('開始吐錢')
# 列印賬單
def __print_flow(self):
print('列印賬單')
# 取錢介面
def withdraw(self):
self.__insert_card()
self.__input_pwd()
self.__input_money()
self.__get_money()
self.__print_flow()
print('程式執行完畢')
atm = ATM()
atm.withdraw()
property
什麼是property
python內置的裝飾器,主要是給類內部的方法使用
為什麼要用property
使用它的目的,是將類內部的方法(def 方法名() 變成了(def 方法))
在對象使用某個方法時,將對象.方法()變成了對象.方法
如何使用property
'''
計算人的bmi:bmi值 = 體重 / (身高 * 身高)
'''
class People:
def __init__(self, name, weight, height):
self.name = name
self.weight = weight
self.height = height
@property
def bmi(self):
return self.weight / (self.height ** 2)
p = People('cwz', 180, 1.8)
print(p.bmi)
註意:不能對被裝飾過的方法屬性修改
但是也可以修改(瞭解)
class People:
def __init__(self, name, weight, height):
self.name = name
self.weight = weight
self.height = height
@property
def bmi(self):
return self.weight / (self.height ** 2)
@property
def get_name(self):
return self.name
# 修改
@get_name.setter
def set_name(self, val):
self.name = val
# 刪除
@get_name.deleter
def del_name(self):
del self.name
p = People('cwz', 180, 1.8)
# print(p.bmi)
p.set_name = 'nick'
# print(p.get_name)
del p.del_name
# print(p.get_name)
多態
什麼是多態
多態指的是同一種事物的多種形態
多態的目的
多態也稱之為多態性,在程式中繼承就是多態的表現形式
多態的目的是為了,讓多種不同類型的對象,在使用相同功能的情況下,調用同一個名字的方法名
父類:定義一套統一的標準
子類:遵循父類統一的標準
多態的最終目的:統一子類編寫的規範,為了讓使用者更方便調用相同方法的功能
如何實現:
繼承
抽象類
在python中,不會強制要求子類必須遵循父類的一套標準,所以出現了抽象類
abc模塊
會強制子類遵循父類的一套標準
import abc
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def eat(self):
pass
@abc.abstractmethod
def drink(self):
pass
@abc.abstractmethod
def speak(self):
pass
class Pig(Animal):
def eat(self):
pass
def drink(self):
pass
def jiao(self): # 強制使用與父類相同的標準,這樣會報錯
print('哼哼哼。。。')
pig = Pig()
pig.jiao()
鴨子類型
在不知道當前對象是什麼的情況下,但你長得像鴨子,那麼你就是鴨子類型
在python中,不推薦使用抽象類強制子類的定義,但是推薦子類都遵循鴨子類型
- 繼承:耦合性太高,程式的可擴展性差
- 鴨子類型:耦合度第,程式的可擴展性強
多態炫技操作
class Animal:
def eat(self):
pass
def drink(self):
pass
def speak(self):
pass
class Pig(Animal):
def eat(self):
pass
def drink(self):
pass
def speak(self):
print('哼哼哼。。。')
class Cat(Animal):
def eat(self):
pass
def drink(self):
pass
def speak(self):
print('喵喵喵。。。')
class Dog(Animal):
def eat(self):
pass
def drink(self):
pass
def speak(self):
print('汪汪汪。。。')
pig = Pig()
dog = Dog()
cat = Cat()
def BARK(animal):
animal.speak()
BARK(dog)
BARK(pig)
BARK(cat)