https://zhuanlan.zhihu.com/p/28010894
https://www.zhihu.com/question/20021164
@classmethod
@staticmethod
定义: 高层模块不应该依赖低层模块, 二者都应该依赖其抽象, 抽象不应该依赖细节, 细节应该依赖抽象
问题由来: A直接依赖B, 如果将A改为依赖C, 则必须修改A的代码,
解决方案: A改为依赖接口I, 类B和类C各自实现接口I, 类A通过接口I间接与类B或者类C发生联系
左后
区别在于当存在类的继承的情况下对多态的支持不同, OOP、多态上的意义 是什么意思?
构造前的交互
依赖倒置原则: 核心在于面向接口编程
https://blog.csdn.net/zhengzhb/article/details/7289269
妈妈讲故事的例子:
Mother类
Book类
Newspaper类
class Book{
public String getContent(){
return "很久很久以前有一个阿拉伯的故事……";
}
}
class Mother{
public void narrate(Book book){
System.out.println("妈妈开始讲故事");
System.out.println(book.getContent());
}
}
public class Client{
public static void main(String[] args){
Mother mother = new Mother();
mother.narrate(new Book());
}
按照这样的写法, 如果将需求改为了读报纸, 必须要修改mother类才能够满足要求, 这其实很荒唐, 因为mother类可以读书却不能读报纸是不合逻辑的, 所以引入一个抽象的接口IReader
读物, 只要是带文字的都属于读物,书和报纸分别实现读物接口, Mother类也和IReader
接口发生依赖关系, 这样就符合依赖倒置原则。
class Newspaper implements IReader {
public String getContent(){
return "今天是元旦新年";
}
}
class Book implements IReader{
public String getContent(){
return "很久以前..."
}
}
class Mother {
public void narrate(IReader reader){
System.out.println("妈妈开始讲故事");
System.out.println(reader.getContent());
}
}
public class Client {
public static void main(String[] args) {
Mother mother = new Mother();
mother.narrate(new Book());
mother.narrate(new Newspaper());
}
}
构造前交互 构造plugin 对象之前, 先从类中获取一定的信息。
特殊构造函数
如果不引用任何类或者实例相关的属性和方法, 只是单纯通过传入参数并返回数据的功能性方法, 那么就适合用静态方法来定义, 节省实例化对象的成本, 等同于在类外面的模块层另写一个函数
《Python Tricks》
class Pizza:
def __init__(self, ingredients):
self.ingredients = ingredients
@classmethod
def margherita(cls);
return cls(['mozzarella', 'tomatoes'])
@classmethod
def prosciutto(cls);
return cls(['mozzarella', 'tomatoes', 'ham'])
@classmethod
里面定义的方法作用的对象是类, 使用cls
关键字, @staticmethod
关键字里面调用的方法是
instance method里面调用的方法是针对于某个实例, 使用self
关键字来锁定
我们可以通过直接调用 Pizza.margherita()
来生成一个新的Pizza实例对象,
可以将@classmethod
作为构造器来使用,
ChainWarehouse
class Pizza:
@staticmethod
def circle_area(r);
return r ** 2 * math.pi
Static Methods 是一个相对独立的部分, circle_area()
不需要调用类中的属性和方法, 这样可以避免修改导致低级错误, 更加易于测试
一般来说 classmethod可以完全替代staticmethod, 区别在于classmethod增加了一个对实际调用类的引用