Python 面向对象三大特征是关键_python面向对象和面向过程举例

liftword3个月前 (02-17)技术文章26

一、面向对象编程基础

在编程的世界里,编程范式多种多样,而面向对象编程(Object-Oriented Programming,OOP)是其中极为重要的一种,在 Python 语言中占据着核心地位。它与面向过程编程有着显著的区别。面向过程编程,如同其名,以过程为核心,将解决问题的步骤拆分成一个个函数,按照顺序依次执行这些函数来完成任务,就像一场精心编排的流程,每个步骤紧密相连,共同推动程序向前运行。

而面向对象编程则是以事物为中心,把现实世界中的事物抽象成程序中的对象。每个对象都有自己独特的属性(数据)和方法(行为) ,就像现实生活中的各种事物,它们都有自己的特征和能做的事情。例如,一只猫这个对象,它有名字、年龄、毛色等属性,也有跑、跳、叫、吃等方法。在面向对象编程中,我们通过创建对象,并让对象之间相互协作来实现程序的功能,就像现实世界中各种事物相互作用一样。这种编程方式更符合人们对现实世界的认知和思维方式,使得程序的设计和理解更加直观、自然。

二、Python 面向对象的三大特征

(一)封装:数据的隐形护盾

封装是面向对象编程的重要特性,它就像给数据穿上了一层隐形的护盾,将对象的属性和方法包装起来,隐藏内部实现的细节,只对外提供操作方法(接口) ,以此保护数据的安全,同时也提高了代码的维护性和可重用性。

在 Python 中,封装主要通过有着类似访问修饰限定符功能的下划线来实现权限控制。比如,给属性或方法添加单下划线、双下划线以及首尾双下划线,它们分别有着不同的访问权限。单下划线开头的属性或方法,表示受保护的成员,这类成员被视为仅供内部家族使用,允许类本身和子类进行访问,但实际上它也可以被外部代码访问 ,只是大家约定俗成尽量不在外部直接访问,以保持代码的规范性和可读性。比如,在一个表示人的类中,如果有一个受保护的属性_age,虽然在外部可以通过对象直接访问,但最好还是通过类提供的方法来操作它,这样可以更好地控制对这个属性的访问和修改。

双下划线开头的属性或方法,则表示私有的成员,这类成员如同被上了一把锁,只允许定义该属性或方法的类本身进行访问,外部代码无法直接触碰,从而有效地保护了类的内部数据不被随意篡改。例如,一个银行账户类中,账户密码属性__password就可以设置为私有,确保密码的安全性,只有类内部的方法,如验证密码、修改密码的方法,才能对其进行操作。

而首尾双下划线的属性或方法,一般表示特殊的方法,这些方法在 Python 中有特定的用途和意义,比如__init__方法是类的构造函数,在创建对象时会自动调用,用于初始化对象的属性;__str__方法用于返回对象的字符串表示,当我们使用print函数输出对象时,实际上调用的就是对象的__str__方法。

下面通过一个代码示例来更直观地感受封装的魅力:

Bash
class Dog():
def __init__(self, name, age):

 self.__name = name

 self._age = age

 def _fun1(self):

 print('这是被protected所修饰的方法')

 def __fun2(self):

 print('这是被private所修饰的方法')

dog = Dog('大白', 5)

print(dog._age)

# print(dog.__name) 直接访问会报错

dog._fun1()

# dog.__fun2() 直接访问会报错

在这个示例中,Dog类的__name属性是私有的,_age属性是受保护的,_fun1方法是受保护的,__fun2方法是私有的。从外部尝试直接访问__name和__fun2会报错,而可以访问_age和调用_fun1方法,这就体现了封装对属性和方法的访问控制。

(二)继承:代码的传承与进化

继承,是面向对象编程中类与类之间的一种重要关系,它允许一个类(子类、派生类)继承另一个类(父类、基类)的属性与方法,就像子女继承父母的基因一样,子类可以获得父类的特征和行为,并且还可以根据自身需求进行扩展和修改 ,是代码的传承与进化。

在 Python 中,一个子类可以继承多个父类,这是 Python 继承机制的一大特色,与 Java 的单继承不同。在 Java 中,一个子类只能有一个直接父类,而 Python 的多继承为开发者提供了更大的灵活性,使得代码可以更高效地复用和组织。不过,多继承也可能带来一些问题,比如当多个父类中有相同名称的属性或方法时,可能会导致命名冲突和复杂性增加 ,所以在使用多继承时需要谨慎考虑。每个类在 Python 中都默认继承自object类,object类是 Python 中所有类的基类,它提供了一些通用的方法和属性,为所有类的行为奠定了基础。

继承的语法也很简洁明了,使用class 类名([父类列表]):的形式来定义子类,当一个类的父类只有object类时,默认可以不写父类,但为了代码的清晰和规范性,建议还是写上。当有除object类之外的其他类时,就需要将这些类全部写到括号中。

看下面这个代码示例:

Bash
class Animal(object):
def __init__(self, name, age, gender, sort):

self.name = name

self.age = age

self.gender = gender

self.__sort = sort

class Dog(Animal):

pass

dog = Dog('大白', 5, '男', '中华田园犬')

print(dog.name)

print(dog.age)

print(dog.gender)

# 同样需要特殊手段才能访问到

print(dog._Animal__sort)

在这个例子中,Dog类继承自Animal类,它继承了Animal类的__init__方法以及name、age、gender属性,通过创建Dog类的对象dog,可以直接访问这些继承来的属性。而__sort属性是私有的,虽然在子类中不能直接访问,但可以通过特殊手段(如_Animal__sort)来访问,不过这种方式不推荐,因为它破坏了封装的原则,类似 Java 中的反射机制,有点反常规。

再来看一个多继承的代码示例:

Bash
class Person():
def __init__(self, name, age, gender):

self.name = name

self.age = age

self.gender = gender

def show(self):

print(f'我叫{self.name},今年{self.age},性别是{self.gender}')

class Father(Person):

def __init__(self, name, age, gender):

super().__init__(name, age, gender)

class Mother(Person):

def __init__(self, name, age, gender):

super().__init__(name, age, gender)

class Son(Father, Mother):

def __init__(self, name, age, gender):

super().__init__(name, age, gender)

father = Father('A', 40, '男')

mother = Mother('B', 35, '女')

son = Son('C', 10, '男')

father.show()

mother.show()

son.show()

在这个代码中,Son类继承了Father类和Mother类,而Father类和Mother类又都继承自Person类。通过创建Father、Mother和Son类的对象,并调用它们的show方法,可以看到它们都能正确地输出各自的信息,这展示了多继承的功能和效果。

当子类继承父类时,如果对父类中的某些方法不满意,子类可以进行方法重写 。方法重写就像是偷梁换柱,表面上方法名不变,但方法内部的实现结构已经发生了变化。重写的要求是方法名必须一样,而方法的返回值类型、参数列表、访问权限等可以不一样。在 Python 中,重写就是在子类中定义一个与父类重名的方法,调用时,如果子类有这个方法,就直接调用子类的方法,即使父类也有同名方法,也不会去调用,这就是所谓的 “地头蛇原则”。

例如:

Bash
class Animal():
def __init__(self, name, age):

self.name = name

self.age = age

def eat(self):

print(f'{self.name}正在吃食物,补充体力')

class Dog(Animal):

def __init__(self, name, age):

super().__init__(name, age)

def eat(self):

print(f'{self.name}正在吃狗粮~')

class Cat(Animal):

def __init__(self, name, age):

super().__init__(name, age)

dog = Dog('大白', 5)

dog.eat()

cat = Cat('小白', 3)

cat.eat()

在这个例子中,Dog类重写了Animal类的eat方法,当调用dog.eat()时,会执行Dog类中重写后的eat方法,输出 “大白正在吃狗粮~”;而Cat类没有重写eat方法,所以调用cat.eat()时,会执行Animal类的eat方法,输出 “小白正在吃食物,补充体力”。

(三)多态:同一行为的多样表现

多态,是面向对象编程中一个非常重要的概念,它描述了同一个行为在不同对象上可以有不同的表现形式,就像现实生活中,同样是 “吃” 这个行为,不同的动物有不同的吃法,人用筷子吃饭,狗用嘴巴啃骨头,猫用舌头舔食猫粮 ,这就是多态的体现。

在 Python 中,实现多态非常灵活。当不同的对象都有一个相同名称的方法时,我们可以通过一个统一的接口来调用这个方法,而具体执行的是哪个对象的方法,则取决于对象的实际类型。例如,定义一个函数,传入不同类型的对象,并调用它们的同一个方法,就可以看到不同的行为表现。

看下面的代码示例:

Bash
class Animal():
def eat(self):

print('正在吃东西')

class Person():

def eat(self):

print('正在干饭')

class Dog():

def eat(self):

print('正在吃狗粮')

class Cat():

def eat(self):

print('正在吃猫粮')

def eat(obj):

obj.eat()

eat(Animal())

eat(Person())

eat(Dog())

eat(Cat())

在这个示例中,Animal、Person、Dog和Cat类都有一个eat方法,但它们的实现各不相同。通过定义eat函数,传入不同类的对象,调用obj.eat()时,就会根据对象的实际类型执行相应类的eat方法,从而实现了多态。当传入Animal对象时,输出 “正在吃东西”;传入Person对象时,输出 “正在干饭”;传入Dog对象时,输出 “正在吃狗粮”;传入Cat对象时,输出 “正在吃猫粮” 。

与 Java 等语言的多态相比,Python 的多态实现方式更加简洁和灵活。在 Java 中,多态需要满足三个条件:向上转型(父类引用指向子类对象)、子类重写父类的方法、向上转型的父类调用该方法(被重写的方法) ,这时才会执行子类的方法。而在 Python 中,只要不同的类有相同的方法,就可以轻松实现多态,不需要显式的向上转型等操作,这使得代码的编写更加简洁和高效,也更符合 Python 简洁、优雅的设计理念。

三、综合案例分析

(一)电商系统类设计

为了更深入地理解面向对象三大特征在实际项目中的应用,我们以电商系统为例,展示如何运用封装、继承和多态进行类设计。

在电商系统中,商品类是一个基础类,它包含了商品的基本属性,如商品名称、价格、库存等,以及一些基本方法,如获取商品信息、更新库存等。通过封装,将这些属性和方法包装在一起,隐藏内部实现细节,只对外提供必要的接口,确保商品数据的安全性和一致性。

Bash
class Product:
def __init__(self, name, price, stock):

self.__name = name

self.__price = price

self.__stock = stock

def get_product_info(self):

return f"商品名称: {self.__name}, 价格: {self.__price}, 库存: {self.__stock}"

def update_stock(self, quantity):

if self.__stock >= quantity:

self.__stock -= quantity

return True

else:

return False

用户类也是电商系统中的重要类,它包含用户的基本信息,如用户名、密码、地址等,以及用户的行为方法,如登录、注册、下单等。同样,通过封装保护用户信息的安全,对外提供操作接口。

Bash
class User:
def __init__(self, username, password, address):

self.__username = username

self.__password = password

self.__address = address

def login(self, username, password):

if self.__username == username and self.__password == password:

return True

else:

return False

def register(self, new_username, new_password, new_address):

self.__username = new_username

self.__password = new_password

self.__address = new_address

def place_order(self, order):

# 下单逻辑,这里简单示意

print(f"{self.__username} 下单: {order.get_order_info()}")

订单类则关联了用户和商品,它记录了订单的相关信息,如订单编号、订单状态、购买的商品列表等,以及订单的操作方法,如添加商品、删除商品、结算订单等。订单类通过继承可以扩展出不同类型的订单,如普通订单、促销订单等,体现了继承的特性。

Bash
class Order:
def __init__(self, order_id, user, status="未支付"):

self.__order_id = order_id

self.__user = user

self.__status = status

self.__products = []

def add_product(self, product, quantity):

self.__products.append((product, quantity))

def remove_product(self, product):

self.__products = [p for p in self.__products if p[0]!= product]

def calculate_total_price(self):

total = 0

for product, quantity in self.__products:

total += product._Product__price * quantity

return total

def get_order_info(self):

product_info = ", ".join([f"{p[0]._Product__name} x {p[1]}" for p in self.__products])

return f"订单编号: {self.__order_id}, 订单状态: {self.__status}, 商品: {product_info}, 总价: {self.calculate_total_price()}"

在这个电商系统中,继承的应用体现在订单类的扩展上。比如,促销订单类可以继承自订单类,并且添加一些促销相关的属性和方法,如促销折扣、满减活动等。

Bash
class PromotionOrder(Order):
def __init__(self, order_id, user, promotion_discount, status="未支付"):

super().__init__(order_id, user, status)

self.__promotion_discount = promotion_discount

def calculate_total_price(self):

total = super().calculate_total_price()

return total * (1 - self.__promotion_discount)

多态的应用则体现在不同类型的订单在结算时的不同表现。比如,普通订单按照原价结算,而促销订单则按照促销后的价格结算。

Bash
# 使用示例
product1 = Product("Python入门教程", 50, 100)

product2 = Product("数据结构与算法", 80, 80)

user = User("张三", "123456", "北京市朝阳区")

order1 = Order("001", user)

order1.add_product(product1, 2)

order1.add_product(product2, 1)

promotion_order = PromotionOrder("002", user, 0.1)

promotion_order.add_product(product1, 3)

user.place_order(order1)

user.place_order(promotion_order)

(二)案例总结

通过这个电商系统的案例,我们可以看到封装、继承和多态这三大特征在面向对象编程中的紧密协作和重要作用。封装确保了数据的安全性和代码的模块化,使得每个类的内部实现细节得到保护,外部只能通过特定的接口进行操作,提高了代码的可维护性和可重用性。继承实现了代码的复用和扩展,通过创建子类继承父类的属性和方法,减少了重复代码的编写,同时可以根据具体需求对父类进行个性化的扩展,使代码结构更加清晰和层次分明。多态则为代码带来了灵活性和可扩展性,同一个操作在不同的对象上可以有不同的表现形式,使得我们可以编写更加通用和灵活的代码,适应不同的业务场景和需求变化。

在实际的软件开发中,合理运用这三大特征能够显著提高代码的质量、可维护性和扩展性,使我们能够更高效地开发出健壮、灵活的软件系统 ,满足不断变化的业务需求,在激烈的市场竞争中占据优势。

Python 面向对象的三大特征 —— 封装、继承和多态,是 Python 编程的核心思想,它们相互配合,共同构建了强大而灵活的面向对象编程体系 。封装保护了数据的安全,提高了代码的可维护性和可重用性;继承实现了代码的复用和扩展,使代码结构更加清晰和层次分明;多态则为代码带来了灵活性和可扩展性,让同一个操作在不同的对象上展现出多样的行为。

对于读者来说,深入学习面向对象编程是提升 Python 编程能力的关键。通过不断地学习和实践,熟练掌握这三大特征的使用技巧,能够让你编写出更加优雅、高效、可维护的代码。在实际的项目开发中,要善于运用面向对象的思维方式,将问题分解为一个个对象,利用封装、继承和多态的特性来设计和实现系统,提高开发效率和软件质量 。

同时,不要局限于理论知识的学习,要积极参与实际项目的开发,在实践中不断积累经验,加深对面向对象编程的理解和应用能力。也可以参考优秀的开源项目代码,学习他人的设计思路和编程技巧,不断拓宽自己的视野和思维方式,提升自己的编程水平,在 Python 编程的道路上越走越远,创造出更多优秀的软件作品 。

相关文章

python极简教程:对象的方法_python对象的含义

这一场,主讲python的面向对象的第二部分—— 对象的方法 。目的:掌握Python对象的五个核心方法。init和new讲解之前,先上一段代码class Demo: def __init__...

Python 对象有哪几种,我们可以从哪些角度进行分类呢?

楔子在程序开发中,我们每时每刻都在创建对象,那到底什么是对象呢?其实一个对象就是一片被分配的内存空间,空间可以是连续的,也可以是不连续的。然后空间里面存储了指定的数据,并提供了操作数据的一些功能方法。...

Python 如何创建一个 JSON 对象_python创建一个person类

我们可以使用下面的代码来在 Python 中创建一个 JSON 对象。import json data = {} data['key'] = 'value' json_data = json.dum...

详细介绍一下Python中的类与对象_python对象和类的关系

类和对象是面向对象编程的两个核心概念,而Python作为一门支持面向对象的编程语言,也是需要通过类和对象来实现代码的组织和封装的,下面我们就来详细介绍一下Python中的类与对象,来帮助大家一起了解它...

Python基础之对象、面向对象编程_python面向对象程序

本系列内容所用Python版本为anaconda,直接浏览器搜索下载安装即可!前面内容我有多次提到过对象这个概念,今天我想专门出一期内容,浅谈一下Python的对象这一基础概念,并谈谈我对面向对象编程...

Python 类和对象的概念_python中类和对象的区别

前言在面向对象的编程范式中,类和对象是两个核心概念。它们是构成程序逻辑的基础单元,也是实现代码复用和模块化的关键。Python作为一种高级编程语言,对面向对象编程提供了良好的支持。本文将深入探讨Pyt...