200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > Python学习笔记:16 面向对象编程入门

Python学习笔记:16 面向对象编程入门

时间:2024-05-25 07:26:41

相关推荐

Python学习笔记:16 面向对象编程入门

文章目录

类和对象面向对象的过程定义类创建和给对象发消息打印对象面向对象编程的支柱经典案例例子1:定义一个类描述数字时钟,可以显示时/分/秒,可以运转(走字)例子2:扑克游戏:四个玩家参与,先洗牌,再把牌发到四个玩家手上

在面向对象编程的世界里,程序中的数据和操作数据的函数是一个逻辑上的整体,我们称之为对象对象可以接收消息,解决问题的方法就是创建对象并向对象发出各种各样的消息;通过消息传递,程序中的多个对象可以协同工作,这样就能构造出复杂的系统并解决现实中的问题。

类和对象

面向对象编程:把一组数据和处理数据的方法组成对象,把行为相同的对象归纳为,通过封装隐藏对象的内部细节,通过继承实现类的特化与泛化,通过多态实现基于对象类型的动态分派。

类是一个抽象的概念,对象是一个具体的概念类是对象的蓝图和模板,对象是类的实例

在面向对象编程的世界中,一切皆为对象对象都有属性和行为每个对象都是独一无二的,而且对象一定属于某个类。对象的属性是对象的静态特征,对象的行为是对象的动态特征。按照上面的说法,如果我们把拥有共同特征的对象的属性和行为都抽取出来,就可以定义出一个类。

面向对象的过程

面向对象编程:

​ 1、定义类—> 类的命名使用驼峰命名法(每个单词首字母大写)

​ — 数据抽象:找到对象相关的静态特征(属性) —> 找名词

​ — 行为抽象:找到和对象相关的动态特征(方法) —> 找动词

​ 2、造对象

​ 3、发消息

定义类

class Student:# 数据抽象def __init__(self, name, age):"""初始化方法"""self.name = nameself.age = age# 行为抽象def eat(self):"""吃饭"""print(f'{self.name}正在吃饭')def study(self, course_name):print(f'{self.name}正在学习{course_name}.')def play(self, game_name):print(f'{self.name}正在玩{game_name}.')

创建和给对象发消息

# 创建对象 ---> 构造器语法 ---> 类名()stu1 = Student('小红', 17)stu2 = Student('小白', 19)# 给对象发消息(调用对象的方法)Student.study(stu2, 'Python程序设计') # 小白正在学习Python程序设计stu1.eat() # 小红正在吃饭stu2.play('王者荣耀') # 小红正在玩王者荣耀# 修改年龄stu1.age = 20

打印对象

上面我们通过__init__方法在创建对象时为对象绑定了属性并赋予了初始值。在Python中,以两个下划线__(读作dunder)开头和结尾的方法通常都是有特殊用途和意义的方法,我们一般称之为魔术方法魔法方法。如果我们在打印对象的时候不希望看到对象的地址而是看到我们自定义的信息,可以通过在类中放置__repr__魔术方法来做到,该方法返回的字符串就是用print函数打印对象的时候会显示的内容,代码如下所示。

class Student:# 数据抽象def __init__(self, name, age):"""初始化方法"""self.name = nameself.age = age# 行为抽象def eat(self):"""吃饭"""print(f'{self.name}正在吃饭')def study(self, course_name):print(f'{self.name}正在学习{course_name}.')def play(self, game_name):print(f'{self.name}正在玩{game_name}.')def __repr__(self):return f'{self.name}: {self.age}' def main(): stu1 = Student('小青', 20)print(stu1) # 小青: 20students = [stu1, Student('小蓝', 16), Student('小白', 25)]print(students) # [小青: 40, 小蓝: 16, 小白: 25]if __name__ == '__main__':main()

面向对象编程的支柱

面向对象编程的四大支柱:

抽象:提取共性(定义类就是一个抽象过程,需要做数据抽象和行为抽象)。封装:把数据和操作数据的函数从逻辑上组成一个整体(对象)。隐藏实现细节,暴露简单的调用接口。继承:扩展已有的类创建新类,实现对已有类的代码复用。多态:给不同的对象发出同样的消息,不同的对象执行了不同的行为。

经典案例

例子1:定义一个类描述数字时钟,可以显示时/分/秒,可以运转(走字)

import osfrom time import sleepclass Clock:def __init__(self, hour=0, minute=0, second=0):self.hour = hourself.minute = minuteself.second = seconddef show(self):"""显示当前时间"""return f'{self.hour:0>2d}:{self.minute:0>2d}:{self.second:0>2d}'def run(self):"""走字"""self.second += 1if self.second == 60:self.second = 0self.minute += 1if self.minute == 60:self.minute = 0self.hour += 1if self.hour == 24:self.hour = 0if __name__ == '__main__':c1 = Clock(1, 58, 58)while True:os.system('cls')print(c1.show())sleep(1)c1.run()

注意:运行时使用终端运行python 文件名命令。

例子2:扑克游戏:四个玩家参与,先洗牌,再把牌发到四个玩家手上

分析:由题目可以抽取出三个类,分别是牌类、扑克类、玩家类,各自的属性和行为如下:

牌(Card)

属性:花色(suite)、点数(face)

行为:显示

扑克(Poker)

属性:保存牌的列表行为:洗牌(shuffle)、发牌(deal)

玩家(Player)

属性:名字(昵称)、保存玩家手牌的列表行为:摸牌(get)、整理(arrange)

魔术方法(魔法方法)—> 有特殊用途和意义的方法

~__init__—> 初始化方法,在调用构造器语法创建对象的时候会被自动调用

~__str__—> 获得对象的字符串表示,在调用print函数输出对象时会被自动调用

~__repr__—> 获得对象的字符串表示,把对象放到容器中调用print输出时会自动调用

—> representation

~__lt__—> 在使用 < 运算符比较两个对象大小时会自动调用

如果一个变量的取值只有有限个选项,可以考虑使用枚举类型。

Python中没有定义枚举类型的语法,但是可以通过继承Enum类来实现枚举类型。

结论1:枚举类型是定义符号常量的最佳选择!!!

结论2:符号常量(有意义的名字)总是优于字面常量!!!

牌类

"""example06 - 扑克游戏,四个玩家参与,先洗牌,再把牌发到四个玩家的手上。Author: yucuiDate: /8/5"""from enum import Enum# 枚举类型class Suite(Enum):SPADE, HEART, CLUB, DIAMOND = range(4)class Card:"""牌"""def __init__(self, suite, face):self.suite = suiteself.face = facedef __str__(self):return self.show()def __repr__(self):return self.show()def __lt__(self, other):if self.suite == other.suite:return self.face < other.facereturn self.suite.value < other.suite.valuedef show(self):"""显示"""suites = ['♠', '❤', '♣', '♦']faces = ['', 'A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']return f'{suites[self.suite.value]}{faces[self.face]}'def main():"""程序入口"""card1 = Card(Suite.HEART, 1)card2 = Card(Suite.SPADE, 13)print(card1, card2)print(card1 is card2)card3 = Card(Suite.DIAMOND, 9)card4 = Card(Suite.CLUB, 11)print(card3.show(), card4.show())card1 = card2print(card1, card2, card3)# 身份运算符print(card1 is card2)print(card1 is card3)cards = [card1, card2, card3, card4]print(cards)if __name__ == '__main__':main()

扑克类

"""example07 - 扑克Author: yucuiDate: /8/5"""import randomfrom example06 import Cardfrom example06 import Suiteclass Poker:"""扑克"""def __init__(self):self.cards = [Card(suite, face)for suite in Suitefor face in range(1, 14)]self.counter = 0def shuffle(self):"""洗牌"""self.counter = 0random.shuffle(self.cards)def deal(self) -> Card:"""发牌"""card = self.cards[self.counter]self.counter += 1return carddef has_more(self) -> bool:"""是否还有牌"""return self.counter < len(self.cards)def main():poker = Poker()poker.shuffle()while poker.has_more():print(poker.deal(), end=' ')if __name__ == '__main__':main()

玩家类

"""example08 - 玩家Author: yucuiDate: /8/5"""from example07 import Pokerclass Player:"""玩家"""def __init__(self, nickname):self.nickname = nicknameself.cards = []def get_one_card(self, card):"""摸一张牌"""self.cards.append(card)def arrange(self):"""整理手上的牌"""self.cards.sort()def show(self):"""显示玩家手上的牌"""print(self.nickname, end=': ')for card in self.cards:print(card, end=' ')print()def main():nicknames = ('东邪', '西毒', '南帝', '北丐')players = [Player(nickname) for nickname in nicknames]poker = Poker()poker.shuffle()# 将牌发到四个玩家的手上for _ in range(13):for player in players:card = poker.deal()player.get_one_card(card)# 显示四个玩家手上的牌for player in players:player.arrange()player.show()if __name__ == '__main__':main()

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。