Python 面向对象编程详解

1. 类和对象基础

基本语法

class ClassName:
    """类的文档字符串"""

    # 类属性
    class_attribute = "类属性值"

    def __init__(self, parameter1, parameter2):
        """构造方法"""
        # 实例属性
        self.instance_attr1 = parameter1
        self.instance_attr2 = parameter2
        self._protected_attr = "受保护的"  # 约定上的保护
        self.__private_attr = "私有的"     # 名称修饰

    def instance_method(self):
        """实例方法"""
        return f"实例方法: {self.instance_attr1}"

    @classmethod
    def class_method(cls):
        """类方法"""
        return f"类方法: {cls.class_attribute}"

    @staticmethod
    def static_method():
        """静态方法"""
        return "静态方法"

创建和使用对象

# 创建对象
obj = ClassName("参数1", "参数2")

# 访问属性和方法
print(obj.instance_attr1)
print(obj.instance_method())
print(ClassName.class_method())
print(ClassName.static_method())

2. 封装 (Encapsulation)

访问控制

class BankAccount:
    def __init__(self, account_holder, initial_balance=0):
        self.account_holder = account_holder        # 公开属性
        self._account_number = self._generate_account_number()  # 保护属性
        self.__balance = initial_balance           # 私有属性

    def _generate_account_number(self):
        """保护方法(内部使用)"""
        import random
        return f"ACC{random.randint(100000, 999999)}"

    def __validate_amount(self, amount):
        """私有方法"""
        return amount > 0

    # 公开接口
    def deposit(self, amount):
        if self.__validate_amount(amount):
            self.__balance += amount
            return True
        return False

    def withdraw(self, amount):
        if self.__validate_amount(amount) and amount <= self.__balance:
            self.__balance -= amount
            return True
        return False

    def get_balance(self):
        """通过方法访问私有属性"""
        return self.__balance

    def get_account_info(self):
        """提供受保护信息的受控访问"""
        return f"Holder: {self.account_holder}, Account: {self._account_number[-4:]}"

# 使用
account = BankAccount("Alice", 1000)
account.deposit(500)
print(account.get_balance())  # 1500
print(account.get_account_info())

# 强制访问(不推荐)
print(account._BankAccount__balance)  # 名称修饰后的私有属性

属性装饰器

class Person:
    def __init__(self, name, age):
        self._name = name
        self._age = age

    @property
    def name(self):
        """获取器"""
        return self._name

    @name.setter
    def name(self, value):
        """设置器"""
        if isinstance(value, str) and len(value) > 0:
            self._name = value
        else:
            raise ValueError("姓名必须是非空字符串")

    @property
    def age(self):
        return self._age

    @age.setter
    def age(self, value):
        if 0 <= value <= 150:
            self._age = value
        else:
            raise ValueError("年龄必须在0-150之间")

    @property
    def description(self):
        """只读属性"""
        return f"{self._name}, {self._age}岁"

# 使用
person = Person("张三", 25)
person.name = "李四"  # 调用setter
person.age = 30      # 调用setter
print(person.description)  # 调用getter

3. 继承 (Inheritance)

基本继承

class Animal:
    def __init__(self, name, species):
        self.name = name
        self.species = species
        self._is_alive = True

    def speak(self):
        raise NotImplementedError("子类必须实现此方法")

    def eat(self, food):
        return f"{self.name} 正在吃 {food}"

    def sleep(self):
        return f"{self.name} 正在睡觉"

    def __str__(self):
        return f"{self.species}: {self.name}"

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name, "犬科")  # 调用父类构造方法
        self.breed = breed

    def speak(self):
        return "汪汪!"

    def fetch(self, item):
        return f"{self.name} 正在捡回 {item}"

class Cat(Animal):
    def __init__(self, name, color):
        super().__init__(name, "猫科")
        self.color = color

    def speak(self):
        return "喵喵!"

    def climb(self, height):
        return f"{self.name} 爬到了 {height}米高"

# 使用继承
dog = Dog("旺财", "金毛")
cat = Cat("咪咪", "白色")

print(dog.speak())      # 汪汪!
print(cat.speak())      # 喵喵!
print(dog.eat("狗粮"))  # 继承的方法
print(cat.climb(2))     # 特有的方法

多重继承

class Flyable:
    def __init__(self, max_altitude=1000):
        self.max_altitude = max_altitude
        self._is_flying = False

    def take_off(self):
        self._is_flying = True
        return "起飞"

    def land(self):
        self._is_flying = False
        return "降落"

    def fly(self):
        if self._is_flying:
            return "正在飞行"
        return "尚未起飞"

class Swimmable:
    def __init__(self, max_depth=10):
        self.max_depth = max_depth
        self._is_swimming = False

    def dive(self):
        self._is_swimming = True
        return "下潜"

    def surface(self):
        self._is_swimming = False
        return "浮出水面"

    def swim(self):
        if self._is_swimming:
            return "正在游泳"
        return "不在水中"

class Duck(Animal, Flyable, Swimmable):
    def __init__(self, name):
        Animal.__init__(self, name, "鸭科")
        Flyable.__init__(self, 500)    # 鸭子飞不高
        Swimmable.__init__(self, 3)    # 鸭子潜不深

    def speak(self):
        return "嘎嘎!"

    def act(self):
        actions = [
            self.speak(),
            self.eat("虫子"),
            self.take_off(),
            self.fly(),
            self.land(),
            self.dive(),
            self.swim(),
            self.surface()
        ]
        return " | ".join(actions)

# 使用多重继承
duck = Duck("唐老鸭")
print(duck.act())

# 方法解析顺序 (MRO)
print(Duck.__mro__)
# (<class '__main__.Duck'>, <class '__main__.Animal'>, 
#  <class '__main__.Flyable'>, <class '__main__.Swimmable'>, <class 'object'>)

4. 多态 (Polymorphism)

方法重写

class Shape:
    def __init__(self, name):
        self.name = name

    def area(self):
        """计算面积 - 抽象方法"""
        raise NotImplementedError("子类必须实现area方法")

    def perimeter(self):
        """计算周长 - 抽象方法"""
        raise NotImplementedError("子类必须实现perimeter方法")

    def __str__(self):
        return f"{self.name} - 面积: {self.area():.2f}, 周长: {self.perimeter():.2f}"

class Rectangle(Shape):
    def __init__(self, width, height):
        super().__init__("矩形")
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

    def perimeter(self):
        return 2 * (self.width + self.height)

class Circle(Shape):
    def __init__(self, radius):
        super().__init__("圆形")
        self.radius = radius

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

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

class Triangle(Shape):
    def __init__(self, a, b, c):
        super().__init__("三角形")
        self.a = a
        self.b = b
        self.c = c

    def area(self):
        # 使用海伦公式
        s = self.perimeter() / 2
        return (s * (s - self.a) * (s - self.b) * (s - self.c)) ** 0.5

    def perimeter(self):
        return self.a + self.b + self.c

# 多态演示
def process_shapes(shapes):
    """处理各种形状 - 多态的体现"""
    total_area = 0
    total_perimeter = 0

    for shape in shapes:
        print(shape)  # 调用各自的 __str__ 方法
        total_area += shape.area()        # 动态调用各自的area方法
        total_perimeter += shape.perimeter()  # 动态调用各自的perimeter方法

    print(f"总面积: {total_area:.2f}")
    print(f"总周长: {total_perimeter:.2f}")

# 创建不同形状的对象
shapes = [
    Rectangle(5, 3),
    Circle(4),
    Triangle(3, 4, 5)
]

process_shapes(shapes)

鸭子类型 (Duck Typing)

class FileReader:
    def read(self):
        return "从文件读取数据"

class DatabaseReader:
    def read(self):
        return "从数据库读取数据"

class APIReader:
    def read(self):
        return "从API读取数据"

def read_data(reader):
    """不关心reader的具体类型,只要它有read方法"""
    return reader.read()

# 使用不同的reader
readers = [FileReader(), DatabaseReader(), APIReader()]

for reader in readers:
    print(read_data(reader))  # 多态的体现

5. 高级特性

抽象基类

from abc import ABC, abstractmethod

class Vehicle(ABC):
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model
        self._is_running = False

    @abstractmethod
    def start_engine(self):
        pass

    @abstractmethod
    def stop_engine(self):
        pass

    def get_info(self):
        return f"{self.brand} {self.model}"

class Car(Vehicle):
    def start_engine(self):
        self._is_running = True
        return "汽车引擎启动"

    def stop_engine(self):
        self._is_running = False
        return "汽车引擎停止"

class Motorcycle(Vehicle):
    def start_engine(self):
        self._is_running = True
        return "摩托车引擎启动"

    def stop_engine(self):
        self._is_running = False
        return "摩托车引擎停止"

# 不能实例化抽象类
# vehicle = Vehicle("通用", "型号")  # 报错

car = Car("丰田", "卡罗拉")
motorcycle = Motorcycle("本田", "CBR")

魔术方法

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other):
        """+ 运算符重载"""
        return Vector(self.x + other.x, self.y + other.y)

    def __sub__(self, other):
        """- 运算符重载"""
        return Vector(self.x - other.x, self.y - other.y)

    def __mul__(self, scalar):
        """* 运算符重载"""
        return Vector(self.x * scalar, self.y * scalar)

    def __str__(self):
        """字符串表示"""
        return f"Vector({self.x}, {self.y})"

    def __repr__(self):
        """解释器表示"""
        return f"Vector({self.x}, {self.y})"

    def __len__(self):
        """长度(模)"""
        return int((self.x**2 + self.y**2)**0.5)

    def __eq__(self, other):
        """== 运算符重载"""
        return self.x == other.x and self.y == other.y

    def __getitem__(self, index):
        """索引访问"""
        if index == 0:
            return self.x
        elif index == 1:
            return self.y
        else:
            raise IndexError("Vector索引超出范围")

# 使用魔术方法
v1 = Vector(2, 3)
v2 = Vector(1, 4)

print(v1 + v2)  # Vector(3, 7)
print(v1 * 2)   # Vector(4, 6)
print(len(v1))  # 3
print(v1 == v2) # False
print(v1[0])    # 2

6. 设计原则

组合优于继承

class Engine:
    def start(self):
        return "引擎启动"

    def stop(self):
        return "引擎停止"

class Wheels:
    def __init__(self, count):
        self.count = count

    def rotate(self):
        return f"{self.count}个轮子在旋转"

class Car:
    def __init__(self, brand, wheel_count=4):
        self.brand = brand
        self.engine = Engine()          # 组合
        self.wheels = Wheels(wheel_count)  # 组合

    def drive(self):
        return f"{self.brand}: {self.engine.start()} -> {self.wheels.rotate()}"

# 使用组合
car = Car("宝马")
print(car.drive())
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇