# ===== CodeLab: Python 面向对象编程 =====
# 来源: https://aoerliang.dpdns.org/articles/python-oop
# 以下代码片段按文章出现顺序拼接, 共 6 段

# ----- 片段 1 (python) -----
class Dog:
    """狗类:定义了狗应有的数据和行为"""
    species = "犬科"

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def bark(self):
        return f"{self.name} 汪汪叫!"

d1 = Dog("旺财", 3)
d2 = Dog("来福", 5)
print(d1.bark())
print(d1.species)
print(d1.age, d2.age)

# ----- 片段 2 (python) -----
class Student:
    def __init__(self, name, scores):
        self.name = name
        self.scores = scores      # 列表

    def average(self):
        return sum(self.scores) / len(self.scores)

s = Student("Ada", [92, 88, 95])
print(f"{s.name} 平均分 {s.average():.1f}")

# ----- 片段 3 (python) -----
class Circle:
    pi = 3.14159

    def __init__(self, radius):
        self.radius = radius

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

    @classmethod
    def from_diameter(cls, d):
        return cls(d / 2)

    @staticmethod
    def is_valid(r):
        return r > 0

c = Circle.from_diameter(10)
print(c.area())
print(Circle.is_valid(3))

# ----- 片段 4 (python) -----
class Animal:
    def speak(self):
        return "..."

class Cat(Animal):
    def speak(self):
        return "喵喵喵"

class Dog(Animal):
    def speak(self):
        return "汪汪汪"

for a in [Cat(), Dog(), Animal()]:
    print(a.speak())

# ----- 片段 5 (python) -----
class BankAccount:
    def __init__(self, owner):
        self.owner = owner
        self._balance = 0

    @property
    def balance(self):           # 只读访问器
        return self._balance

    def deposit(self, amount):
        if amount > 0:
            self._balance += amount
        else:
            raise ValueError("金额必须为正")

acc = BankAccount("Ada")
acc.deposit(100)
print(acc.balance)

# ----- 片段 6 (python) -----
class Point:
    def __init__(self, x, y):
        self.x, self.y = x, y

    def __str__(self):
        return f"({self.x}, {self.y})"          # 给人看

    def __repr__(self):
        return f"Point(x={self.x}, y={self.y})"  # 给开发者看

p = Point(3, 4)
print(p)          # (3, 4)   调用 __str__
print(repr(p))    # Point(x=3, y=4)  调用 __repr__
