面向对象:Python的类和Java有什么不一样?

admin 📖 8 分钟阅读

你熟悉的OOP,Python全都有

Java程序员最熟悉的就是面向对象了。Python同样支持OOP,但语法更灵活,限制更少

没有interface?没有private?没有构造函数重载?Python用另一套方式解决了这些问题。

一、类的定义

# Python
class Student:
    def __init__(self, name, age, score):
        self.name = name
        self.age = age
        self.score = score
    
    def is_pass(self):
        return self.score >= 60
    
    def __str__(self):
        return f"Student({self.name}, {self.age}岁, {self.score}分)"

s = Student("张三", 20, 85) print(s) # Student(张三, 20岁, 85分) print(s.is_pass()) # True

// Java
public class Student {
    private String name;
    private int age;
    private int score;
    
    public Student(String name, int age, int score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }
    
    public boolean isPass() {
        return this.score >= 60;
    }
}

区别:

  • init是Python的初始化方法
  • self相当于Java的this,但必须显式写
  • str相当于toString()
  • Python不需要写访问修饰符

二、访问控制:没有private?

Python用命名约定实现:

class BankAccount:
    def __init__(self, owner, balance):
        self.owner = owner      # 公开
        self._balance = balance # 约定protected
        self.__pin = "1234"     # 名称改写private
    
    def get_balance(self):
        return self._balance

account = BankAccount("张三", 10000) print(account.owner) # OK print(account._balance) # 能访问但不该

print(account.__pin) # 报错

print(account._BankAccount__pin) # 能绕过去

哲学: "We are all consenting adults here"。信任程序员,不做强制限制。

三、没有interface?用ABC

from abc import ABC, abstractmethod

class Shape(ABC): @abstractmethod def area(self): pass
@abstractmethod def perimeter(self): pass
def describe(self): return f"面积: {self.area()}, 周长: {self.perimeter()}"

class Circle(Shape): def init(self, radius): self.radius = radius
def area(self): return 3.14159 self.radius * 2
def perimeter(self): return 2 3.14159 self.radius

shapes = [Circle(5), Circle(3)] for shape in shapes: print(shape.describe())

s = Shape() # 报错!不能实例化抽象类

四、@property:Python的getter/setter

class Circle:
    def __init__(self, radius):
        self._radius = radius
    
    @property
    def radius(self):
        return self._radius
    
    @radius.setter
    def radius(self, value):
        if value < 0:
            raise ValueError("半径不能为负数")
        self._radius = value
    
    @property
    def area(self):
        return 3.14159 * self._radius ** 2

c = Circle(5) print(c.radius) # 5 c.radius = 10 print(c.area) # 314.159

五、多重继承

class Flyable:
    def fly(self):
        return "我在飞"

class Swimmable: def swim(self): return "我在游泳"

class Duck(Flyable, Swimmable): pass

duck = Duck() print(duck.fly()) # "我在飞" print(duck.swim()) # "我在游泳"

六、魔术方法

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 __mul__(self, scalar):
        return Vector(self.x * scalar, self.y * scalar)
    
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y
    
    def __repr__(self):
        return f"Vector({self.x}, {self.y})"
    
    def __getitem__(self, index):
        if index == 0: return self.x
        if index == 1: return self.y
        raise IndexError

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

总结

特性PythonJava
运算符重载add不支持
**下一篇聊迭代器和生成器。**

本系列持续更新中,关注不迷路。

🤖 本文内容由AI辅助整理生成,仅供参考
← 上一篇 函数是Python的灵魂:lambda、装饰器、闭包 下一篇 → 迭代器和生成器:优雅处理大数据的秘密武器