面向对象编程是一种常见的编程范式,它将现实世界中的实体抽象为对象,通过对象之间的交互来设计和构建软件系统,核心概念包括类、对象、继承、封装和多态。
一、核心概念
1.类与对象
- 类:类是对象的蓝图或模板,它定义了一组属性(变量)和方法(函数),这些属性和方法是该类的所有对象共有的。
- 对象:对象是类的实例,它是根据类定义创建的,并且每个对象都可以拥有不同的属性值。
2.继承
- 继承:继承是一种机制,允许一个类(子类)继承另一个类(父类或超类)的属性和方法。这有助于代码复用,并可以创建出一个层次结构。
3.封装
- 封装:封装是将数据(属性)和行为(方法)结合在一起的机制,同时限制对内部实现的直接访问。这有助于隐藏内部细节,只暴露必要的操作接口。
4.多态
- 多态:多态是指允许不同类的对象对同一消息做出响应的能力。这意味着同一个接口可以被不同的对象以不同的方式实现。
二、面向对象编程的优点
- 代码复用:通过继承和封装,OOP促进了代码的复用。
- 易于维护:对象的封装性质使得修改和维护代码更加容易。
- 灵活性:多态性允许系统更容易地扩展和适应变化。
三、 实战1:扑克点数花色问题
1.说明
在本示例中,我们将创建一个简单的扑克游戏,游戏中包含52张牌,没有大小王。游戏的目标是将这些牌发给4个玩家,每个玩家获得13张牌。牌的花色按照黑桃、红心、草花、方块的顺序排列,点数从小到大。
2.类设计
- Card: 代表一张扑克牌,具有花色和点数两个属性。
- Suite: 用枚举类型表示扑克牌的花色。
- Poker: 代表一副扑克牌,包含52张牌,可以进行洗牌和发牌操作。
- Player: 代表玩家,持有一定数量的牌,并能对牌进行排序。
3.代码实现
首先是枚举类型和牌的类定义:
from enum import Enum
class Suite(Enum):
""“花色(枚举)”""
SPADE = 0, HEART = 1, CLUB = 2, DIAMOND = 3
class Card:
""“牌”""
def __init__(self, suite, face):
self.suite = suite
self.face = face
def __repr__(self):
suits = '♠♥♣♦'
faces = ['2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A']
return f'{suits[self.suite.value]}{faces[self.face]}'
接下来是扑克类的定义:
import random
class Poker:
""“扑克”""
def __init__(self):
self.cards = [Card(suite, face) for suite in Suite for face in range(2, 15)]
self.current = 0
def shuffle(self):
""“洗牌”""
random.shuffle(self.cards)
self.current = 0
def deal(self):
""“发牌”""
if self.current < len(self.cards):
card = self.cards[self.current]
self.current += 1
return card
return None
@property
def has_next(self):
""“判断是否还有牌可以发”""
return self.current < len(self.cards)
然后是玩家类的定义:
class Player:
"""玩家"""
def __init__(self, name):
self.name = name
self.cards = []
def get_one(self, card):
""“摸牌”""
self.cards.append(card)
def arrange(self):
""“排列手中的牌”""
self.cards.sort(key=lambda x: (x.suite.value, x.face))
最后是游戏的测试代码:
def deal_game(poker, players):
poker.shuffle()
while poker.has_next:
for player in players:
player.get_one(poker.deal())
for player in players:
player.arrange()
print(f'{player.name}的手牌: {player.cards}')
players = [Player('东邪'), Player('西毒'), Player('南帝'), Player('北丐')]
game = Poker()
deal_game(game, players)
四、实战2:面向对象系统设计
1.要求
设计一个工资结算系统,包含三种类型的员工:部门经理、程序员和销售员。部门经理月薪固定,程序员按工作时间计薪,销售员月薪包括底薪和销售额提成。
2.类设计
- Employee: 作为基类,定义所有员工共有的属性和方法。
- Manager: 继承自Employee,代表部门经理。
- Programmer: 继承自Employee,代表程序员。
- Salesman: 继承自Employee,代表销售员。
3.代码实现
首先是抽象基类Employee的定义:
from abc import ABCMeta, abstractmethod
class Employee(metaclass=ABCMeta):
""“员工(抽象类)”""
def __init__(self, name):
self.name = name
@abstractmethod
def get_salary(self):
""“结算月薪”""
pass
接下来是具体员工类的定义:
class Manager(Employee):
""“部门经理”""
def get_salary(self):
return 15000.0
class Programmer(Employee):
""“程序员”""
def __init__(self, name, working_hour=0):
super().__init__(name)
self.working_hour = working_hour
def get_salary(self):
return 200 * self.working_hour
class Salesman(Employee):
""“销售员”""
def __init__(self, name, sales=0):
super().__init__(name)
self.sales = sales
def get_salary(self):
return 1800 + 0.05 * self.sales
最后是工资结算系统的测试代码:
employees = [
Manager('刘备'), Programmer('诸葛亮'), Manager('曹操'),
Programmer('荀彧'), Salesman('吕布'), Programmer('张辽')
]
for emp in employees:
if isinstance(emp, Programmer):
emp.working_hour = int(input(f'请输入{emp.name}本月工作时间: '))
elif isinstance(emp, Salesman):
emp.sales = float(input(f'请输入{emp.name}本月销售额: '))
print(f'{emp.name}本月工资为: ¥{emp.get_salary():.2f}元')
面向对象编程是一种强大的编程范式,它通过模拟现实世界中的对象和它们之间的交互来简化复杂的编程任务。OOP的应用非常广泛,从桌面应用程序到大型企业系统,再到游戏和模拟软件,都可以看到OOP的身影。通过本篇文章探讨了理论知识,并结合了扑克游戏和工资结算系统的实际应用案例,展示了如何将OOP的概念应用于实际编程中。希望大家能够从中获得启发,并在自己的编程实践中运用面向对象编程的原则。