你熟悉的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
总结
| 特性 | Python | Java |
|---|---|---|
| 运算符重载 | add等 | 不支持 |
本系列持续更新中,关注不迷路。