Python 中的类与面向对象编程(二)

目录

一、面向对象编程(OOP)

二、类与实例

[1. 类](#1. 类)

[2. 实例](#2. 实例)

[三、' self ' 关键字](#三、' self ' 关键字)

四、魔法函数

[1. 初始化与字符串表示](#1. 初始化与字符串表示)

[2. 长度与比较](#2. 长度与比较)

[3. 算术运算](#3. 算术运算)

五、构造函数与析构函数

[1. 初始化函数](#1. 初始化函数)

[2. 构造函数](#2. 构造函数)

[3. 析构函数](#3. 析构函数)

六、面向对象编程的三大特性

[1. 封装](#1. 封装)

[2. 继承](#2. 继承)

多重继承

[3. 多态](#3. 多态)

[1. 方法重载(函数同名不同参数)](#1. 方法重载(函数同名不同参数))

[2. 父子类多态](#2. 父子类多态)

七、抽象类

八、动态添加内容

[1. 添加实例属性](#1. 添加实例属性)

[2. 添加实例方法](#2. 添加实例方法)

[3. 添加类属性和方法](#3. 添加类属性和方法)

九、总结


大家好!今天我们将继续探讨 Python 中的类及其在面向对象编程(OOP)中的应用。面向对象编程是一种编程范式,它使用"对象"来模拟现实世界的事务,使代码更加结构化和易于维护。在上一篇文章中,我们详细了解类和实例的概念、' self ' 关键字的作用、魔法函数的定义、构造函数和析构函数的用途,今天我们会在上一篇文章的基础上补充面向对象编程的三大特性:封装、继承和多态。让我们开始吧!

一、面向对象编程(OOP)

面向对象编程是一种将现实世界事务使用类与实例来模拟的方法。在 OOP 中,所有事物都被视为对象。这些对象可以是具体的,如:

灯:可以开关的设备。

汽车:具有属性(如颜色、品牌)和行为(如行驶、停车)的交通工具。

导弹:具备特定属性和发射行为的武器。

杯子:用于盛放液体的容器。

通过将这些现实世界的事务抽象为对象,我们可以创建更易于理解和操作的代码结构。

二、类与实例

1. 类

类是对现实世界描述的一种类型。它是一个抽象的概念,约定了未来实例应该有的内容。定义类的基本语法如下:

python 复制代码
class 类名:
    pass

在 Python 中,类名通常采用大驼峰(Pascal Case)命名法。例如,我们可以定义一个名为' Car ' 的类:

python 复制代码
class Car:
    pass

类是实例的模板,它定义了实例的属性和行为,但并不包含具体的数据。

2. 实例

实例是通过调用类生成的具体对象。生成实例的语法为:

python 复制代码
实例名 = 类名()

例如:

python 复制代码
my_car = Car()

这里,' my_car ' 是 ' Car ' 类的一个实例,它包含了 ' Car ' 类定义的所有属性和方法,但具体的数据是属于这个实例的。

三、' self ' 关键字

' self ' 关键字在类的方法内部,' self ' 代表实例本身。它用于访问实例的属性和方法。' self ' 必须作为第一个参数出现在类的方法中。让我们看一个简单的例子,展示如何使用 ' self ' :

python 复制代码
class Dog:
    def __init__(self, name):
        self.name = name  # 将实例属性name初始化为传入的name参数

    def bark(self):
        return f"{self.name} says Woof!"

在上面的代码中,' init ' 是一个初始化函数,用于创建实例时初始化属性。通过 ' self ' ,我们可以在 ' bark ' 方法中引用实例的 ' name ' 属性。

四、魔法函数

魔法函数是以双下划线开头和结尾的特殊方法,它们能够实现某些特定的功能。常用的魔法函数包括:

1. 初始化与字符串表示

' init(self) ' :构造函数,用于初始化实例。

' str(self) ' :定义对象的字符串表示,通常用于 ' print() ' 函数。

python 复制代码
class Cat:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return f"This is {self.name} the cat."
2. 长度与比较

' len(self) ' :返回对象的长度。

比较运算符魔法函数:' eq(self, other) ':等于比较。

' ne(self, other) ':不等于比较。

' gt(self, other) ':大于比较。

' ge(self, other) ':大于或等于比较。

' lt(self, other) ':小于比较。

' le(self, other) ':小于或等于比较。

python 复制代码
class Box:
    def __init__(self, size):
        self.size = size

    def __len__(self):
        return self.size

    def __eq__(self, other):
        return self.size == other.size
3. 算术运算

魔法函数还可以重载算术运算符,使得我们能够使用常见的运算符(如 `+`、`-` 等)对自定义对象进行操作。这些魔法函数包括:

' add(self, other) ' :实现加法运算。

' sub(self, other) ':实现减法运算。

' mul(self, other) ':实现乘法运算。

' truediv(self, other) ':实现除法运算。

' mod(self, other) ':实现取模运算。以下是一个示例,展示如何使用 ' add ' 魔法函数:

python 复制代码
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)

    def __repr__(self):
        return f"Point({self.x}, {self.y})"

# 创建两个 Point 实例
p1 = Point(1, 2)
p2 = Point(3, 4)
p3 = p1 + p2  # 这里会调用 p1.__add__(p2)
print(p3)  # 输出: Point(4, 6)

在这个例子中,' add ' 方法允许我们直接使用 ' + ' 运算符来相加两个 ' Point ' 实例。

五、构造函数与析构函数

1. 初始化函数

初始化函数是一个特殊的方法,用于初始化实例的属性。' init ' 方法在创建对象时自动调用。

python 复制代码
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def display(self):
        return f"姓名: {self.name}, 年龄: {self.age}"

# 创建实例
person = Person("Alice", 30)
print(person.display())  # 输出: 姓名: Alice, 年龄: 30

2. 构造函数

构造函数是一个特殊的方法,用于创建实例。' new ' 方法在实例被创建时被调用。通常情况下,我们不需要直接使用 ' new ' ,但在需要控制实例创建过程时可以使用。

python 复制代码
class Singleton:
    _instance = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance

# 测试 Singleton 类
s1 = Singleton()
s2 = Singleton()

print(s1 is s2)  # 输出: True,确保只有一个实例

3. 析构函数

析构函数是另一个特殊的方法,在实例不再使用时被调用,通常用于释放资源。Python 中的析构函数是 ' del ' 方法。虽然 Python 有垃圾回收机制,但在某些情况下,手动释放资源是很有用的。

析构函数的基本结构如下:

python 复制代码
def __del__(self):
    # 清理代码

下面是一个简单的示例,展示如何使用析构函数:

python 复制代码
class Resource:
    def __init__(self):
        print("Resource acquired!")

    def __del__(self):
        print("Resource released!")

# 创建一个资源对象
res = Resource()
# 资源会在对象销毁时被释放

当 ' res ' 对象超出作用域时,Python 的垃圾回收会调用 ' del ' 方法,输出"Resource released!"。

六、面向对象编程的三大特性

在 OOP 中,有三大基本特性:封装、继承和多态。

1. 封装

封装是指将数据和方法结合在一起,并限制对某些数据的直接访问。通过封装,我们可以保护对象的内部状态,只通过公共方法(接口)来访问和修改这些状态。

python 复制代码
class Person:
    def __init__(self, name, age):
        self.__name = name  # 私有属性
        self.__age = age    # 私有属性

    def get_name(self):
        return self.__name

    def set_name(self, name):
        self.__name = name

    def get_age(self):
        return self.__age

    def set_age(self, age):
        if age > 0:
            self.__age = age
        else:
            print("年龄必须为正数!")

# 创建实例
person = Person("Alice", 30)
print(person.get_name())  # 输出: Alice
person.set_age(-5)        # 输出: 年龄必须为正数!

在上面的代码中,我们使用了双下划线 ' __ ' 将实例属性 ' __name ' 和 ' __age ' 定义为私有属性,这样它们就不能被直接访问。我们提供了公共方法 ' get_name ' 和 ' set_name ' 来访问和修改这些私有属性。这种封装机制不仅保护了对象的内部状态,还提供了更好的数据验证和控制。

2. 继承

继承是指一个类(子类)可以继承另一个类(父类)的属性和方法,从而实现代码的重用。子类可以扩展或修改父类的行为。

python 复制代码
class Animal:
    def speak(self):
        return "Animal speaks"

class Dog(Animal):  # Dog 继承自 Animal
    def speak(self):
        return "Woof!"

class Cat(Animal):  # Cat 也继承自 Animal
    def speak(self):
        return "Meow!"

# 实例化对象
dog = Dog()
cat = Cat()
print(dog.speak())  # 输出: Woof!
print(cat.speak())  # 输出: Meow!

在这个例子中,' Dog ' 和 ' Cat ' 类都继承了 ' Animal ' 类的 ' speak ' 方法,但它们各自实现了自己的版本。这种特性使得我们可以创建一个通用的父类,并根据需要扩展子类。

多重继承

Python 支持多重继承,即一个类可以同时继承多个类。这在某些情况下非常有用,但也可能导致复杂性(如菱形继承问题)。

python 复制代码
class Flyer:
    def fly(self):
        return "Flying"

class Swimmer:
    def swim(self):
        return "Swimming"

class Duck(Flyer, Swimmer):
    def quack(self):
        return "Quack!"

# 实例化 Duck
duck = Duck()
print(duck.fly())  # 输出: Flying
print(duck.swim())  # 输出: Swimming
print(duck.quack())  # 输出: Quack!

3. 多态

多态是指不同类的对象可以通过相同的接口进行操作。多态的实现通常依赖于继承和方法重载。Python 中的多态通常有两种形式:

1. 方法重载(函数同名不同参数)

Python 不支持传统意义上的方法重载,但我们可以使用可变参数( ' *args ' 和 ' **kwargs ' )来实现类似效果。

python 复制代码
class MathOperation:
    def add(self, *args):
        return sum(args)

math_op = MathOperation()
print(math_op.add(1, 2))          # 输出: 3
print(math_op.add(1, 2, 3, 4, 5))  # 输出: 15
2. 父子类多态

父类和子类的方法名相同,但实现不同。我们可以通过多态来处理不同类型的对象。

python 复制代码
def animal_sound(animal):
    print(animal.speak())

# 实例化对象
dog = Dog()
cat = Cat()
animal_sound(dog)  # 输出: Woof!
animal_sound(cat)  # 输出: Meow!

在这个例子中,' animal_sound ' 函数接收 ' Animal ' 类型的对象,不论是 ' Dog ' 还是 ' Cat ',都可以调用 ' speak ' 方法。

七、抽象类

抽象类是一种特殊的类,用于定义接口和强制子类实现特定的方法。抽象类不能被实例化,通常用于提供一个模板,要求其子类实现抽象方法。使用 ' abc ' 模块来定义抽象类和抽象方法。

python 复制代码
from abc import ABC, abstractmethod

class Animal(ABC):  # 继承自 ABC,表示这是一个抽象类
    @abstractmethod
    def speak(self):  # 抽象方法
        pass

class Dog(Animal):
    def speak(self):
        return "Woof!"

class Cat(Animal):
    def speak(self):
        return "Meow!"

# 实例化对象
dog = Dog()
cat = Cat()
print(dog.speak())  # 输出: Woof!
print(cat.speak())  # 输出: Meow!

# animal = Animal()  # 这将引发错误,因为不能实例化抽象类

在这个示例中,' Animal ' 是一个抽象类,定义了一个抽象方法 ' speak ' 。子类 ' Dog ' 和 ' Cat ' 必须实现这个方法,否则会引发错误。抽象类的使用使得接口的实现变得一致,并确保所有子类都具备特定的方法。

八、动态添加内容

Python 是一门动态语言,允许我们在运行时向类和实例添加属性和方法。这种灵活性使得 Python 在许多场景下非常强大。

1. 添加实例属性

我们可以在实例创建后直接为实例添加新的属性。

python 复制代码
class Cup:
    def __init__(self, capacity):
        self.capacity = capacity

# 创建实例
my_cup = Cup(300)
my_cup.color = "Blue"  # 动态添加实例属性
print(my_cup.color)  # 输出: Blue

2. 添加实例方法

可以使用 ' types.MethodType ' 动态添加实例方法。注意,动态添加的方法的第一个参数必须是 'self ' 。

python 复制代码
import types

def new_method(self):
    return f"This cup has a capacity of {self.capacity} ml."

my_cup.new_method = types.MethodType(new_method, my_cup)  # 动态添加实例方法
print(my_cup.new_method())  # 输出: This cup has a capacity of 300 ml.

3. 添加类属性和方法

同样地,我们可以向类本身动态添加属性和方法。

python 复制代码
Cup.color = "Red"  # 动态添加类属性
print(Cup.color)  # 输出: Red

def class_method(cls):
    return f"This class has the capacity: {cls.color}"

Cup.class_method = classmethod(class_method)  # 动态添加类方法
print(Cup.class_method())  # 输出: This class has the capacity: Red

九、总结

通过本篇文章,我们深入了解了 Python 中的类和面向对象编程的基本概念,包括:

类与实例:类是对象的模板,实例是具体的对象。类定义了属性和行为,实例则包含具体的数据。

'self' 关键字:用于引用实例本身,允许在方法中访问实例属性和方法。

魔法函数:特殊的方法,允许我们定义对象的行为(如初始化、比较和运算),包括 ' init '、 ' str ' 、' len ' 等。

构造函数与析构函数:用于创建和销毁实例,管理资源。构造函数 ' new ' 和析构函数 ' del ' 使得我们可以控制实例的创建和销毁过程。

面向对象编程的三大特性:

封装:将数据和方法结合在一起,保护对象的内部状态。

继承:允许子类继承父类的属性和方法,促进代码重用。

多态:允许不同类的对象通过相同的接口进行操作,提高代码的灵活性和可扩展性。

抽象类:用于定义接口,强制子类实现特定的方法,提供一致性。

动态添加内容:Python 允许在运行时向类和实例添加属性和方法,增加了编程的灵活性。

面向对象编程的优势在于它将数据和功能封装在一起,使代码更加模块化可读且易于维护。能帮助我们更好地组织代码,提高开发效率。

相关推荐
ac-er88882 分钟前
PHP弱类型安全问题
开发语言·安全·php
ac-er88882 分钟前
PHP网络爬虫常见的反爬策略
开发语言·爬虫·php
爱吃喵的鲤鱼12 分钟前
linux进程的状态之环境变量
linux·运维·服务器·开发语言·c++
DARLING Zero two♡38 分钟前
关于我、重生到500年前凭借C语言改变世界科技vlog.16——万字详解指针概念及技巧
c语言·开发语言·科技
Gu Gu Study41 分钟前
【用Java学习数据结构系列】泛型上界与通配符上界
java·开发语言
yyfhq42 分钟前
sdnet
python
测试19981 小时前
2024软件测试面试热点问题
自动化测试·软件测试·python·测试工具·面试·职场和发展·压力测试
love_and_hope1 小时前
Pytorch学习--神经网络--搭建小实战(手撕CIFAR 10 model structure)和 Sequential 的使用
人工智能·pytorch·python·深度学习·学习
芊寻(嵌入式)1 小时前
C转C++学习笔记--基础知识摘录总结
开发语言·c++·笔记·学习
一颗松鼠1 小时前
JavaScript 闭包是什么?简单到看完就理解!
开发语言·前端·javascript·ecmascript