Python面向对象(OOP)速成教程

Python 是一门支持面向对象编程(OOP)的语言,面向对象编程的核心概念包括类、对象、封装、继承和多态。下面通过具体的范例来详细介绍这些概念的使用

一、类和对象

类是对象的设计稿,定义了对象的属性和方法;对象是类的实例。

# 定义一个类
class Dog:
    # 类属性
    species = "Canis familiaris"

    def __init__(self, name, age):
        # 实例属性
        self.name = name
        self.age = age

    # 实例方法
    def bark(self):
        return f"{self.name} says woof!"

# 创建对象
dog1 = Dog("Buddy", 3)
dog2 = Dog("Lucy", 2)

# 访问属性
print(dog1.name)  # 输出: Buddy
print(dog2.age)   # 输出: 2

# 调用方法
print(dog1.bark())  # 输出: Buddy says woof!

二、封装

 封装是将数据(属性)和操作数据的方法(行为)绑定在一起,并隐藏对象的内部实现细节。通过使用访问修饰符(在 Python 中通常通过命名约定)来控制属性的访问。 

class BankAccount:
    def __init__(self, account_number, balance):
        # 私有属性,通过命名约定,以双下划线开头
        self.__account_number = account_number
        self.__balance = balance

    # 公有方法,用于存款
    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount
            return f"Deposited {amount}. New balance: {self.__balance}"
        else:
            return "Invalid deposit amount."

    # 公有方法,用于取款
    def withdraw(self, amount):
        if 0 < amount <= self.__balance:
            self.__balance -= amount
            return f"Withdrew {amount}. New balance: {self.__balance}"
        else:
            return "Insufficient funds or invalid withdrawal amount."

    # 公有方法,用于获取余额
    def get_balance(self):
        return self.__balance

account = BankAccount("123456", 1000)
print(account.deposit(500))  # 输出: Deposited 500. New balance: 1500
print(account.withdraw(200))  # 输出: Withdrew 200. New balance: 1300
print(account.get_balance())  # 输出: 1300

在面向对象编程中,访问修饰符用于控制类的属性和方法的访问权限,即决定哪些代码可以访问这些属性和方法。在 Python 里,虽然没有像 Java、C++ 那样明确的 publicprivateprotected 等访问修饰符关键字,但通过命名约定来实现类似的访问控制效果。下面详细介绍 Python 中基于命名约定的访问修饰符概念。

1、公有属性和方法(无特殊前缀)

在 Python 中,没有任何特殊前缀的属性和方法默认是公有的,这意味着它们可以在类的内部、类的实例以及类外部的任何地方被访问。

class Person:
    def __init__(self, name):
        # 公有属性
        self.name = name

    # 公有方法
    def say_hello(self):
        return f"Hello, my name is {self.name}."

# 创建对象
p = Person("Alice")
# 访问公有属性
print(p.name)  
# 调用公有方法
print(p.say_hello())  

在上述代码中,name 属性和 say_hello 方法都是公有的,我们可以直接在类外部通过对象实例进行访问和调用。

2、私有属性和方法(双下划线前缀)

当属性或方法名以双下划线 __ 开头时,Python 会将其视为私有成员。私有成员在类外部不能直接访问,这在一定程度上实现了对类内部数据和实现细节的封装。

class BankAccount:
    def __init__(self, balance):
        # 私有属性
        self.__balance = balance

    # 私有方法
    def __calculate_interest(self):
        return self.__balance * 0.05

    # 公有方法,用于间接访问私有属性和方法
    def get_balance_with_interest(self):
        interest = self.__calculate_interest()
        return self.__balance + interest

# 创建对象
account = BankAccount(1000)
# 尝试直接访问私有属性会报错
# print(account.__balance)  
# 调用公有方法间接访问私有属性和方法
print(account.get_balance_with_interest())  

 在这个例子中,__balance 是私有属性,__calculate_interest 是私有方法。如果在类外部直接访问 __balance 会引发 AttributeError 异常,我们只能通过类内部的公有方法(如 get_balance_with_interest)来间接访问和操作这些私有成员。

3、受保护的属性和方法(单下划线前缀)

 以单下划线 _ 开头的属性和方法被视为受保护的成员。这只是一种约定,实际上在 Python 中并没有真正限制对这些成员的访问,但按照编程规范,通常表示这些成员不应该在类外部直接访问,主要供类内部或子类使用。

class Vehicle:
    def __init__(self, speed):
        # 受保护的属性
        self._speed = speed

    # 受保护的方法
    def _increase_speed(self, amount):
        self._speed += amount

class Car(Vehicle):
    def accelerate(self):
        # 子类可以访问受保护的属性和方法
        self._increase_speed(10)
        return self._speed

# 创建对象
car = Car(50)
# 虽然可以直接访问受保护的属性,但不建议这样做
# print(car._speed)  
print(car.accelerate())  

在这个示例中,_speed 是受保护的属性,_increase_speed 是受保护的方法。子类 Car 可以访问这些受保护的成员,而在类外部虽然可以直接访问,但按照约定不应该这样做。

Python 通过命名约定实现了类似访问修饰符的功能,帮助开发者控制类的属性和方法的访问权限,提高代码的安全性和可维护性。


三、继承

 继承允许一个类继承另一个类的属性和方法,从而实现代码的复用和扩展。被继承的类称为父类(基类),继承的类称为子类(派生类)。

# 父类
class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        return f"{self.name} makes a sound."

# 子类
class Cat(Animal):
    def speak(self):
        return f"{self.name} meows."

class Cow(Animal):
    def speak(self):
        return f"{self.name} moos."

cat = Cat("Whiskers")
cow = Cow("Bessie")

print(cat.speak())  # 输出: Whiskers meows.
print(cow.speak())  # 输出: Bessie moos.

四、多态

多态是指不同的对象可以对同一方法做出不同的响应。在 Python 中,多态通常通过继承和方法重写来实现。

class Shape:
    def area(self):
        pass

class Square(Shape):
    def __init__(self, side):
        self.side = side

    def area(self):
        return self.side * self.side

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        import math
        return math.pi * self.radius ** 2

# 定义一个函数,接受一个 Shape 对象并调用其 area 方法
def print_area(shape):
    print(f"The area of this shape is {shape.area()}.")

square = Square(5)
circle = Circle(3)

print_area(square)  # 输出: The area of this shape is 25.
print_area(circle)  # 输出: The area of this shape is approximately 28.274333882308138.

通过这些范例,你可以了解 Python 面向对象编程的基本概念和使用方法。在实际开发中,合理运用类、对象、封装、继承和多态可以提高代码的可维护性、复用性和可扩展性。

五、抽象

在 Python 中,可以定义抽象类和抽象方法,不过需要借助 abc (Abstract Base Classes,抽象基类)模块来实现。下面为你详细介绍相关概念、使用方法和示例代码。

抽象类和抽象方法的概念

  • 抽象类:是一种不能被实例化的类,它主要用于定义一组子类必须实现的接口(方法),起到一种规范和约束的作用,为子类提供一个统一的模板。
  • 抽象方法:是在抽象类中声明但没有具体实现的方法,子类必须实现这些抽象方法才能被实例化。

abc 模块提供了 ABC 类(Python 3.4 及以后版本)和 abstractmethod 装饰器,用于定义抽象类和抽象方法。

from abc import ABC, abstractmethod

# 定义抽象类,继承自 ABC
class Shape(ABC):
    # 定义抽象方法,使用 @abstractmethod 装饰器
    @abstractmethod
    def area(self):
        pass

    @abstractmethod
    def perimeter(self):
        pass

# 定义子类,继承自抽象类 Shape
class Square(Shape):
    def __init__(self, side):
        self.side = side

    # 实现抽象方法 area
    def area(self):
        return self.side * self.side

    # 实现抽象方法 perimeter
    def perimeter(self):
        return 4 * self.side

# 定义另一个子类,继承自抽象类 Shape
class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    # 实现抽象方法 area
    def area(self):
        import math
        return math.pi * self.radius ** 2

    # 实现抽象方法 perimeter
    def perimeter(self):
        import math
        return 2 * math.pi * self.radius

# 尝试实例化抽象类会报错
# shape = Shape()  

# 实例化子类
square = Square(5)
print(f"Square area: {square.area()}, perimeter: {square.perimeter()}")

circle = Circle(3)
print(f"Circle area: {circle.area()}, perimeter: {circle.perimeter()}")

代码解释

  1. 导入模块:从 abc 模块导入 ABC 类和 abstractmethod 装饰器。
  2. 定义抽象类:创建 Shape 类并继承自 ABC,使其成为抽象类。
  3. 定义抽象方法:在 Shape 类中使用 @abstractmethod 装饰器定义 area 和 perimeter 抽象方法,这些方法没有具体的实现代码,只有方法签名。
  4. 定义子类:创建 Square 和 Circle 类,继承自 Shape 抽象类,并实现了 area 和 perimeter 抽象方法。
  5. 实例化对象:尝试实例化抽象类 Shape 会引发 TypeError 异常,而实例化子类 Square 和 Circle 则是允许的,因为它们已经实现了所有的抽象方法。

通过这种方式,Python 可以实现抽象类和抽象方法的功能,确保子类遵循统一的接口规范。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值