Skip to content

面向对象编程

类和对象

Python 面向对象编程

基本类定义

python
# Python - 基本类定义
class Person:
    """人类类"""

    # 类变量
    species = "Homo sapiens"

    def __init__(self, name, age):
        """构造函数"""
        self.name = name  # 实例变量
        self.age = age
        self._private_var = "私有变量"  # 约定私有变量

    def introduce(self):
        """自我介绍方法"""
        return f"我叫 {self.name},今年 {self.age} 岁"

    def have_birthday(self):
        """过生日方法"""
        self.age += 1
        return f"{self.name} 过生日了,现在 {self.age} 岁"

    @property
    def is_adult(self):
        """属性方法"""
        return self.age >= 18

    @classmethod
    def create_anonymous(cls):
        """类方法"""
        return cls("匿名", 0)

    @staticmethod
    def is_valid_age(age):
        """静态方法"""
        return 0 <= age <= 150

# 创建对象
person1 = Person("Alice", 25)
person2 = Person("Bob", 30)

# 调用方法
print(person1.introduce())  # 我叫 Alice,今年 25 岁
print(person2.have_birthday())  # Bob 过生日了,现在 31 岁
print(person1.is_adult)  # True

# 使用类方法
anonymous = Person.create_anonymous()
print(anonymous.introduce())  # 我叫 匿名,今年 0 岁

# 使用静态方法
print(Person.is_valid_age(200))  # False

继承

python
# Python - 继承
class Student(Person):
    """学生类,继承自 Person"""

    def __init__(self, name, age, student_id, major):
        # 调用父类构造函数
        super().__init__(name, age)
        self.student_id = student_id
        self.major = major
        self.grades = []

    def add_grade(self, grade):
        """添加成绩"""
        self.grades.append(grade)

    def get_average(self):
        """计算平均分"""
        if not self.grades:
            return 0
        return sum(self.grades) / len(self.grades)

    def introduce(self):
        """重写父类方法"""
        base_intro = super().introduce()
        return f"{base_intro},学号 {self.student_id},专业 {self.major}"

# 创建学生对象
student = Student("Charlie", 20, "2023001", "计算机科学")
student.add_grade(85)
student.add_grade(92)
student.add_grade(78)

print(student.introduce())  # 我叫 Charlie,今年 20 岁,学号 2023001,专业 计算机科学
print(f"平均分: {student.get_average():.1f}")  # 平均分: 85.0

多态和抽象类

python
# Python - 多态和抽象类
from abc import ABC, abstractmethod

class Animal(ABC):
    """抽象动物类"""

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

    @abstractmethod
    def make_sound(self):
        """抽象方法"""
        pass

    def introduce(self):
        return f"我是 {self.name}"

class Dog(Animal):
    """狗类"""

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

    def fetch(self):
        return f"{self.name} 在捡球"

class Cat(Animal):
    """猫类"""

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

    def climb(self):
        return f"{self.name} 在爬树"

# 多态示例
animals = [Dog("旺财"), Cat("咪咪")]

for animal in animals:
    print(f"{animal.introduce()}: {animal.make_sound()}")
    # 我是 旺财: 汪汪!
    # 我是 咪咪: 喵喵!

特殊方法

python
# Python - 特殊方法
class Vector:
    """向量类"""

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

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

    def __repr__(self):
        """详细字符串表示"""
        return f"Vector(x={self.x}, y={self.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 __eq__(self, other):
        """相等比较"""
        return self.x == other.x and self.y == other.y

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

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

print(v1)  # Vector(3, 4)
print(v1 + v2)  # Vector(4, 6)
print(v1 - v2)  # Vector(2, 2)
print(v1 == v2)  # False
print(len(v1))  # 5

JavaScript 面向对象编程

基本类定义

javascript
// JavaScript - 基本类定义
class Person {
  // 类变量(静态属性)
  static species = "Homo sapiens";

  constructor(name, age) {
    this.name = name; // 实例变量
    this.age = age;
    this._privateVar = "私有变量"; // 约定私有变量
  }

  introduce() {
    return `我叫 ${this.name},今年 ${this.age} 岁`;
  }

  haveBirthday() {
    this.age += 1;
    return `${this.name} 过生日了,现在 ${this.age} 岁`;
  }

  // Getter 属性
  get isAdult() {
    return this.age >= 18;
  }

  // 静态方法
  static createAnonymous() {
    return new Person("匿名", 0);
  }

  static isValidAge(age) {
    return age >= 0 && age <= 150;
  }
}

// 创建对象
const person1 = new Person("Alice", 25);
const person2 = new Person("Bob", 30);

// 调用方法
console.log(person1.introduce()); // 我叫 Alice,今年 25 岁
console.log(person2.haveBirthday()); // Bob 过生日了,现在 31 岁
console.log(person1.isAdult); // true

// 使用静态方法
const anonymous = Person.createAnonymous();
console.log(anonymous.introduce()); // 我叫 匿名,今年 0 岁

// 使用静态方法
console.log(Person.isValidAge(200)); // false

继承

javascript
// JavaScript - 继承
class Student extends Person {
  constructor(name, age, studentId, major) {
    super(name, age); // 调用父类构造函数
    this.studentId = studentId;
    this.major = major;
    this.grades = [];
  }

  addGrade(grade) {
    this.grades.push(grade);
  }

  getAverage() {
    if (this.grades.length === 0) {
      return 0;
    }
    return (
      this.grades.reduce((sum, grade) => sum + grade, 0) / this.grades.length
    );
  }

  introduce() {
    const baseIntro = super.introduce();
    return `${baseIntro},学号 ${this.studentId},专业 ${this.major}`;
  }
}

// 创建学生对象
const student = new Student("Charlie", 20, "2023001", "计算机科学");
student.addGrade(85);
student.addGrade(92);
student.addGrade(78);

console.log(student.introduce()); // 我叫 Charlie,今年 20 岁,学号 2023001,专业 计算机科学
console.log(`平均分: ${student.getAverage().toFixed(1)}`); // 平均分: 85.0

多态和接口

javascript
// JavaScript - 多态(通过继承实现)
class Animal {
  constructor(name) {
    this.name = name;
  }

  makeSound() {
    throw new Error("子类必须实现 makeSound 方法");
  }

  introduce() {
    return `我是 ${this.name}`;
  }
}

class Dog extends Animal {
  makeSound() {
    return "汪汪!";
  }

  fetch() {
    return `${this.name} 在捡球`;
  }
}

class Cat extends Animal {
  makeSound() {
    return "喵喵!";
  }

  climb() {
    return `${this.name} 在爬树`;
  }
}

// 多态示例
const animals = [new Dog("旺财"), new Cat("咪咪")];

animals.forEach((animal) => {
  console.log(`${animal.introduce()}: ${animal.makeSound()}`);
  // 我是 旺财: 汪汪!
  // 我是 咪咪: 喵喵!
});

特殊方法和操作符重载

javascript
// JavaScript - 特殊方法(通过 Symbol 实现)
class Vector {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return `Vector(${this.x}, ${this.y})`;
  }

  valueOf() {
    return Math.sqrt(this.x ** 2 + this.y ** 2);
  }

  // 自定义方法
  add(other) {
    return new Vector(this.x + other.x, this.y + other.y);
  }

  subtract(other) {
    return new Vector(this.x - other.x, this.y - other.y);
  }

  equals(other) {
    return this.x === other.x && this.y === other.y;
  }

  get length() {
    return Math.sqrt(this.x ** 2 + this.y ** 2);
  }
}

// 使用特殊方法
const v1 = new Vector(3, 4);
const v2 = new Vector(1, 2);

console.log(v1.toString()); // Vector(3, 4)
console.log(v1.add(v2).toString()); // Vector(4, 6)
console.log(v1.subtract(v2).toString()); // Vector(2, 2)
console.log(v1.equals(v2)); // false
console.log(v1.length); // 5

面向对象特性对比

特性PythonJavaScript
类定义class ClassName:class ClassName {}
构造函数__init__(self)constructor()
继承class Child(Parent):class Child extends Parent
方法调用self.method()this.method()
私有变量_variable (约定)#variable (ES2022)
属性@propertyget property()
静态方法@classmethodstatic method()
抽象类ABC + @abstractmethod无内置支持

高级面向对象特性

Python 高级特性

python
# Python - 多重继承
class Flyable:
    def fly(self):
        return f"{self.name} 在飞行"

class Swimmable:
    def swim(self):
        return f"{self.name} 在游泳"

class Duck(Animal, Flyable, Swimmable):
    def make_sound(self):
        return "嘎嘎!"

# 使用多重继承
duck = Duck("唐老鸭")
print(duck.make_sound())  # 嘎嘎!
print(duck.fly())  # 唐老鸭 在飞行
print(duck.swim())  # 唐老鸭 在游泳

# Python - 混入类
class LoggerMixin:
    def log(self, message):
        print(f"[{self.__class__.__name__}] {message}")

class LoggedPerson(Person, LoggerMixin):
    def introduce(self):
        self.log("正在自我介绍")
        return super().introduce()

# 使用混入类
logged_person = LoggedPerson("Alice", 25)
print(logged_person.introduce())
# [LoggedPerson] 正在自我介绍
# 我叫 Alice,今年 25 岁

JavaScript 高级特性

javascript
// JavaScript - 混入模式
const LoggerMixin = {
  log(message) {
    console.log(`[${this.constructor.name}] ${message}`);
  },
};

class LoggedPerson extends Person {
  introduce() {
    this.log("正在自我介绍");
    return super.introduce();
  }
}

// 应用混入
Object.assign(LoggedPerson.prototype, LoggerMixin);

// 使用混入
const loggedPerson = new LoggedPerson("Alice", 25);
console.log(loggedPerson.introduce());
// [LoggedPerson] 正在自我介绍
// 我叫 Alice,今年 25 岁

// JavaScript - 组合模式
class Composable {
  constructor() {
    this.methods = new Map();
  }

  addMethod(name, method) {
    this.methods.set(name, method);
  }

  callMethod(name, ...args) {
    const method = this.methods.get(name);
    if (method) {
      return method.apply(this, args);
    }
    throw new Error(`方法 ${name} 不存在`);
  }
}

// 使用组合模式
const composable = new Composable();
composable.addMethod("greet", function (name) {
  return `Hello, ${name}!`;
});

console.log(composable.callMethod("greet", "World")); // Hello, World!

设计模式

Python 设计模式

python
# Python - 单例模式
class Singleton:
    _instance = None

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

    def __init__(self):
        if not hasattr(self, 'initialized'):
            self.data = []
            self.initialized = True

    def add_data(self, item):
        self.data.append(item)

    def get_data(self):
        return self.data.copy()

# 使用单例
singleton1 = Singleton()
singleton2 = Singleton()
print(singleton1 is singleton2)  # True

# Python - 工厂模式
class AnimalFactory:
    @staticmethod
    def create_animal(animal_type, name):
        if animal_type == "dog":
            return Dog(name)
        elif animal_type == "cat":
            return Cat(name)
        else:
            raise ValueError(f"未知的动物类型: {animal_type}")

# 使用工厂
dog = AnimalFactory.create_animal("dog", "旺财")
cat = AnimalFactory.create_animal("cat", "咪咪")

JavaScript 设计模式

javascript
// JavaScript - 单例模式
class Singleton {
  static instance = null;

  constructor() {
    if (Singleton.instance) {
      return Singleton.instance;
    }
    this.data = [];
    Singleton.instance = this;
  }

  addData(item) {
    this.data.push(item);
  }

  getData() {
    return [...this.data];
  }
}

// 使用单例
const singleton1 = new Singleton();
const singleton2 = new Singleton();
console.log(singleton1 === singleton2); // true

// JavaScript - 工厂模式
class AnimalFactory {
  static createAnimal(animalType, name) {
    switch (animalType) {
      case "dog":
        return new Dog(name);
      case "cat":
        return new Cat(name);
      default:
        throw new Error(`未知的动物类型: ${animalType}`);
    }
  }
}

// 使用工厂
const dog = AnimalFactory.createAnimal("dog", "旺财");
const cat = AnimalFactory.createAnimal("cat", "咪咪");

练习

  1. 创建一个 BankAccount 类,包含存款、取款、查询余额功能

参考答案:

python
# Python
class BankAccount:
    def __init__(self, balance=0):
        self.balance = balance
    def deposit(self, amount):
        self.balance += amount
    def withdraw(self, amount):
        if amount <= self.balance:
            self.balance -= amount
        else:
            print("余额不足")
    def get_balance(self):
        return self.balance
acc = BankAccount(100)
acc.deposit(50)
acc.withdraw(30)
print(acc.get_balance())
javascript
// JavaScript
class BankAccount {
  constructor(balance = 0) {
    this.balance = balance;
  }
  deposit(amount) {
    this.balance += amount;
  }
  withdraw(amount) {
    if (amount <= this.balance) {
      this.balance -= amount;
    } else {
      console.log("余额不足");
    }
  }
  getBalance() {
    return this.balance;
  }
}
const acc = new BankAccount(100);
acc.deposit(50);
acc.withdraw(30);
console.log(acc.getBalance());
  1. 实现一个 Shape 抽象类,创建 CircleRectangleTriangle 子类

参考答案:

python
# Python
from abc import ABC, abstractmethod
class Shape(ABC):
    @abstractmethod
    def area(self):
        pass
class Circle(Shape):
    def __init__(self, r):
        self.r = r
    def area(self):
        return 3.14 * self.r ** 2
class Rectangle(Shape):
    def __init__(self, w, h):
        self.w = w
        self.h = h
    def area(self):
        return self.w * self.h
class Triangle(Shape):
    def __init__(self, b, h):
        self.b = b
        self.h = h
    def area(self):
        return 0.5 * self.b * self.h
shapes = [Circle(2), Rectangle(3, 4), Triangle(3, 5)]
for s in shapes:
    print(s.area())
javascript
// JavaScript
class Shape {
  area() {
    throw new Error("必须实现 area 方法");
  }
}
class Circle extends Shape {
  constructor(r) {
    super();
    this.r = r;
  }
  area() {
    return Math.PI * this.r ** 2;
  }
}
class Rectangle extends Shape {
  constructor(w, h) {
    super();
    this.w = w;
    this.h = h;
  }
  area() {
    return this.w * this.h;
  }
}
class Triangle extends Shape {
  constructor(b, h) {
    super();
    this.b = b;
    this.h = h;
  }
  area() {
    return 0.5 * this.b * this.h;
  }
}
const shapes = [new Circle(2), new Rectangle(3, 4), new Triangle(3, 5)];
shapes.forEach((s) => console.log(s.area()));
  1. 使用继承创建一个简单的游戏角色系统

参考答案:

python
# Python
class Character:
    def __init__(self, name, hp):
        self.name = name
        self.hp = hp
    def attack(self, target):
        print(f"{self.name} 攻击 {target.name}")
class Warrior(Character):
    def attack(self, target):
        print(f"{self.name} 用剑砍 {target.name}")
class Mage(Character):
    def attack(self, target):
        print(f"{self.name} 释放魔法攻击 {target.name}")
hero = Warrior("战士", 100)
villain = Mage("法师", 80)
hero.attack(villain)
villain.attack(hero)
javascript
// JavaScript
class Character {
  constructor(name, hp) {
    this.name = name;
    this.hp = hp;
  }
  attack(target) {
    console.log(`${this.name} 攻击 ${target.name}`);
  }
}
class Warrior extends Character {
  attack(target) {
    console.log(`${this.name} 用剑砍 ${target.name}`);
  }
}
class Mage extends Character {
  attack(target) {
    console.log(`${this.name} 释放魔法攻击 ${target.name}`);
  }
}
const hero = new Warrior("战士", 100);
const villain = new Mage("法师", 80);
hero.attack(villain);
villain.attack(hero);
  1. 实现单例模式来管理应用程序配置

参考答案:

python
# Python
class Config:
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super().__new__(cls)
        return cls._instance
    def __init__(self):
        self.value = 42
cfg1 = Config()
cfg2 = Config()
print(cfg1 is cfg2)
javascript
// JavaScript
class Config {
  constructor() {
    if (Config.instance) return Config.instance;
    this.value = 42;
    Config.instance = this;
  }
}
const cfg1 = new Config();
const cfg2 = new Config();
console.log(cfg1 === cfg2);
  1. 比较 Python 和 JavaScript 的面向对象特性差异

参考答案:

  • Python 支持多继承、抽象基类、属性装饰器、数据描述符。
  • JavaScript 只支持单继承,类本质是语法糖,原型链机制。
  • Python 有私有属性(约定 _/__),JS 没有真正私有(ES6 有 # 私有字段)。
  • 两者都支持多态、继承、封装。

下一步

现在你已经了解了面向对象编程,接下来我们将学习异常处理。