python面向对象
内置方法
__call__方法
- 使得对象具备当作函数来调用的能力
class Person:
def __call__(self, *args, **kwargs):
print("xxx", args, kwargs)
pass
p = Person()
p("hello")#xxx ('hello',) {}
class PenFactory:
def __init__(self, p_type):
self.p_type = p_type
def __call__(self, p_color):
print("类型:%s, 颜色%s" % (self.p_type, p_color))
gangbi = PenFactory("钢笔")
gangbi("绿色")
gangbi("红色")
'''
类型:钢笔, 颜色绿色
类型:钢笔, 颜色红色
'''
索引操作
- 对一个实例对象进行索引操作
class Person:
def __init__(self):
self.cache = {}
def __setitem__(self, key, value):
#print("setitem", key, value)
self.cache[key] = value
def __getitem__(self, item):
#print("getitem", item)
return self.cache[item]
def __delitem__(self, key):
#print("delitem", key)
del self.cache[key]
#想对对象进行类似字典的操作需要在里面定义内置的item函数
p = Person()
p["name"] = "niko" #setitem name niko
print(p.__dict__)#{'cache': {'name': 'niko'}}
print(p["name"])#niko
del p["name"]
print(p.__dict__)#{'cache': {}}
切片操作
class Person:
def __init__(self):
self.items = [1, 2, 3, 4]
def __setitem__(self, key, value):
print(key.start, key.stop, key.step, value)
self.items[key] = value
def __getitem__(self, item):
print("getitem", item)
p = Person()
p[0 : 4 : 2] = ["a", "b"]
print(p.__dict__)
p[0 : 2]
'''
0 4 2 ['a', 'b']
{'items': ['a', 2, 'b', 4]}
getitem slice(0, 2, None)
'''
比较操作
- 对于反向操作的比较运算符,如果只定义了其中一种方法,但是使用的是另外一种比较运算,系统会采用调换参数的方式进行方法调用。但是,不支持叠加操作。
import functools
@functools.total_ordering #会自动补全其他方式
class Person:
def __init__(self, age, height):
self.age = age
self.height = height
def __lt__(self, other):
print(self.age, other.age)#采用调换参数实现
return self.age < other.age#p1自动映射为self,p2映射为other
def __eq__(self, other):
return self.age == other.age
p1 = Person(18, 160)
p2 = Person(19, 240)
print(p1 < p2)#True
print(p1 * p2)#False
print(p1 == p2)#False
print(Person.__dict__)#{ '__lt__': <function Person.__lt__ at 0x0000022E1DBB4F70*, '__eq__': <function Person.__eq__ at 0x0000022E1DBB4EE0*}
print(Person.__dict__)
#: <function Person.__init__ at 0x0000022DD1554F70*, '__lt__': <function Person.__lt__ at 0x0000022DD1554EE0*, '__eq__': <function Person.__eq__ at 0x0000022DD155D040*, '__gt__': <function _gt_from_lt at 0x0000022DD14D7AF0*, '__le__': <function _le_from_lt at 0x0000022DD14D7B80*, '__ge__': <function _ge_from_lt at 0x0000022DD14D7C10*}
print(p1 <= p2)#True 组合了小于和等于
上下文环境的布尔值
class Person:
def __bool__(self):#代表了该类型对象的真假
return False
pass
p = Person()
print(bool(p))#False
遍历操作
- 怎样可以使得我们自己创建的对象可以使用for in进行遍历?①实现__getitem__方法 ②实现__iter__方法
- 怎样可以使得我们自己创建的对象可以使用next进行访问?
class Person:
def __init__(self):
self.result = 1
def __getitem__(self, item):#要自行设置终止条件,不要死循环
print("getitem")
self.result += 1
if self.result *= 6:
raise StopIteration("停止遍历")
return self.result
def __iter__(self):#方式2优先级高于getitem
#要返回迭代器,有next方法的对象才是迭代器
return self
def __next__(self):
self.result += 1
if self.result *= 6:
raise StopIteration("停止遍历")
return self.result
p = Person()
for i in p:
print(i)
'''
2
3
4
5
'''
next访问对象
class Person:
def __init__(self):
self.result = 1
def __next__(self):
self.result += 1
if self.result *= 6:
raise StopIteration("停止遍历")
return self.result
p = Person()
print(next(p))
'''
2
'''
- 对象如为迭代器必须要实现iter和next俩个方法
class Person:
def __init__(self):
self.age = 1
def __iter__(self):
self.age = 1
return self
def __next__(self):
self.age += 1
if self.age *= 3:
raise StopIteration("Stop")
return self.age
p = Person()
import collections
print(isinstance(p, collections.Iterator))#True
for i in p:
print(i)
for i in p:
print(i)
'''
2
2
'''
- 迭代器只可以遍历一次,想多次使用需要在iter中进行回退操作,也就是初始化
- getitem即使可以使用for in访问但是并不是可迭代对象
- Iterable必须是要有iter方法
- 可迭代对象一定可for in访问,反之不成立
class Person:
def __init__(self):
self.age = 1
def __iter__(self):
self.age = 1
return self
def __call__(self, *args, **kwargs):
self.age += 1
if self.age *= 4:
raise StopIteration("Stop")
return self.age
p = Person()
pi = iter(p , 4)#iter的第一个参数是一个可调用函数 第二个参数是终止值
print(pi)
for i in pi:
print(i)
'''
<callable_iterator object at 0x0000024C494A4D90*
2
3
'''
描述器
- 可以描述一个属性操作的对象
- 属性指向一个特殊的对象,该对象具有__set__,get,__delete__方法
定义
定义方式1:property
class Person:
def __init__(self):
self.__age = 18
@property
def age(self):
return self.__age
@age.setter
def age(self, value):
print("setter")
if value < 0:
value = 0
self.__age = value
@age.deleter
def age(self):
del self.__age
#age = property(get_age, set_age, del_age)
p = Person()
print(p.age) #18
p.age = 19
print(p.age)#19
定义方式2
class Age:
def __get__(self, instance, owner):
print("get")
return self
def __set__(self, instance, value):
print("set")
self = value
def __delete__(self, instance):
print("delete")
del self
class Person:
age = Age()
p = Person()
print(p.age)
p.age = 19
- 一个实例属性的正常访问顺序
- 1.实例对象自身的__dict__字典
- 2.对应类对象的__dict__字典
- 3.如果有父类,会在父类的__dict__字典中检测
- 4.如果没找到,但是有__getattr__方法,就会调此方法
- 那么究竟是如何实现__get__的优先调用?
- 内部:如果实现了描述器方法__get__就会直接调,没有就按照上述机制去查找
- 资料描述器:get/set
- 非资料描述器:仅仅实现了get方法
- 资料描述器自身属性非资料描述器
采用属性类定义
class Age:
#self是Age对象 instance是所定义的类对象
#Age对象是在各个类对象之中共享的
def __get__(self, instance, owner):
print("get", instance, owner)
return self.v
def __set__(self, instance, value):
print("set")
self.v = value
def __delete__(self, instance):
print("delete")
del self
class Person:
age = Age()
p = Person()
p.age = 18 #get <__main__.Person object at 0x0000018F6805F1C0* <class '__main__.Person'*
print(p.age)#18
p2 = Person()
p2.age = 10
print(p2.age)#get <__main__.Person object at 0x0000018F680C8850* <class '__main__.Person'*10
print(p.age)#get <__main__.Person object at 0x0000018F680C8850* <class '__main__.Person'*10
class Age:
#self是Age对象 instance是所定义的类对象
#Age对象是在各个类对象之中共享的
def __get__(self, instance, owner):
print("get", instance, owner)
return instance.v
def __set__(self, instance, value):
print("set")
instance.v = value
def __delete__(self, instance):
print("delete")
del self
class Person:
age = Age()
p = Person()
p.age = 18
print(p.age)
p2 = Person()
p2.age = 10
print(p2.age)
print(p.age)
'''
set
get <__main__.Person object at 0x000001A01723F1C0* <class '__main__.Person'*
18
set
get <__main__.Person object at 0x000001A0172A8850* <class '__main__.Person'*
10
get <__main__.Person object at 0x000001A01723F1C0* <class '__main__.Person'*
18
'''
对象的生命周期
class Person:
def __new__(cls, *args, **kwargs):
print("new可以拦截对象的创建")
pass
def __init__(self):
print("对象创建")
def __del__(self):
print("该对象被释放了886")
p = Person()#new可以拦截对象的创建
print(p)#None
del p
内存管理机制
存储方面
- python中无基本数据类型,都是对象
- 所有对象,都会在内存中开辟一块空间进行存储(会通过不同的类型和内容,开辟不同的空间大小进行存储,同时会返回“引用”(地址),用于后续对象操作
- 对于整数和短小的字符,python会进行缓存,不创建多个对象
- 容器对象存储的其他对象,仅仅是其他对象的引用,而不是其他对象本身(列表,元组)
引用计数器机制
引用计数增加场景
- 对象被创建
- 对象被引用p2 = p1
- 对象被作为参数被传到另外一个参数中去
- 对象作为一个元素存储在容器中
垃圾回收机制(处理循环引用问题
- 从经历过“引用计数器机制”仍未被释放的对象中找到循环引用并释放。
- 分代回收机制
垃圾回收时机
- 自动回收
- 手动回收
import gc
print(gc.isenabled)()#默认开
gc.disable()#关闭
print(gc.isenabled())#false
#装饰器 谁在外层先执行谁
import win32com.client
speaker = win32com.client.Dispatch("SAPI.SpVoice")
speaker.Speak("Hello world")
class Caculater:
def __say(func):
def inner(self, num):
speaker = win32com.client.Dispatch("SAPI.SpVoice")
speaker.Speak(num)
func(self, num)
return inner
def __init__(self):
self.result = 0
@__say
def add(self, num):
self.result = self.result + num
@__say
def sub(self, num):
self.result = self.result - num
@__say
def mutiple(self, num):
self.result = self.result * num
@__say
def div(self, num):
self.result = self.result / num
caculator = Caculater()
caculator.add(5)
caculator.sub(10)
继承
- 单继承:仅仅继承了一个父类
- 多继承:继承了多个父类
class Animal:
pass
class Dog:
pass
class cute(Animal, Dog):#多继承
pass
print(cute.__bases__)#(<class '__main__.Animal'*, <class'__main__.Dog'*)
print(bool.__bases__)#(<class 'int'*,)
print(int.__bases__)#(<class 'object'*,)
- 继承机制下,私有属性和私有方法都不能继承!内置的方法可以继承。
- 是继承了相关内容的访问权,而不是写入权。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GrZVkagk-1679875777914)(1.png “继承类别”)]
- 单继承:从下往上找,先从自己找,再从父类,再父父类。
- 无重叠的多继承链:先左链条往上再右链条往上,单调原则。
- 有重叠的多继承链:先父类(左-右)再爷类
class Person:
pass
class yawen(Person):
pass
import inspect
print(inspect.getmro(yawen))#(<class '__main__.yawen'*, <class '__main__.Person'*, <class 'object'*)
资源累加
#super 沿着MRO链条找到下一级结点,去调用对应的方法
class B:
def __init__(self):
self.b = 1
pass
class A(B):
def __init__(self):
super().__init__()
self.a = 2
a = A()
print(a.__dict__)#{'b': 1, 'a': 2}
多态
- 定义:一个类所能衍生出的多种形态,在继承的前提下,调用父类的同一个方法,产生不同的功能。
- 多态一般是在静态语言里面实现的,python是动态语言,实质上没有真正的多态,也不需要多态。
抽象类
- 一个抽象出来的类,不能直接创建实际的对象;抽象方法是一个抽象出来的方法,不具备具体的实现,也不能直接调用,子类不实现该方法会报错。
python中的实现
- 无法直接支持,需要借助一个模块 import abc
- 设置类的元类为abc.ABCMeta
- 使用装饰器修饰抽象方法@abc.abstractmethod
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "{}岁的小狗{}".format(self.age, self.name)
def play(self):
print("%s在玩" % self)
d = Dog("niko", 2)
d.play()#2岁的小狗niko在玩
面向对象设计原则
- SOLID
- S(Single Responsibility Principle)单一职责原则,一个类只负责一个职责。
- O(Open Closed Principle)开放封闭原则:对扩展开放,对修改关闭
- L(Liskov Substitution Principle)里氏替代方法:子类一定得具备父类的特性、方法
- I(Interface Segregation Principle)接口分离原则,如果一个类具有过多的接口方法,并且这些方法在使用的过程中并非是不可分割,那么应当将他们分离。
- D(Dependency Inversion Principle)依赖倒置原则:高层模块不应该直接依赖底层模块。# python面向对象
内置方法
__call__方法
- 使得对象具备当作函数来调用的能力
class Person:
def __call__(self, *args, **kwargs):
print("xxx", args, kwargs)
pass
p = Person()
p("hello")#xxx ('hello',) {}
class PenFactory:
def __init__(self, p_type):
self.p_type = p_type
def __call__(self, p_color):
print("类型:%s, 颜色%s" % (self.p_type, p_color))
gangbi = PenFactory("钢笔")
gangbi("绿色")
gangbi("红色")
'''
类型:钢笔, 颜色绿色
类型:钢笔, 颜色红色
'''
索引操作
- 对一个实例对象进行索引操作
class Person:
def __init__(self):
self.cache = {}
def __setitem__(self, key, value):
#print("setitem", key, value)
self.cache[key] = value
def __getitem__(self, item):
#print("getitem", item)
return self.cache[item]
def __delitem__(self, key):
#print("delitem", key)
del self.cache[key]
#想对对象进行类似字典的操作需要在里面定义内置的item函数
p = Person()
p["name"] = "niko" #setitem name niko
print(p.__dict__)#{'cache': {'name': 'niko'}}
print(p["name"])#niko
del p["name"]
print(p.__dict__)#{'cache': {}}
切片操作
class Person:
def __init__(self):
self.items = [1, 2, 3, 4]
def __setitem__(self, key, value):
print(key.start, key.stop, key.step, value)
self.items[key] = value
def __getitem__(self, item):
print("getitem", item)
p = Person()
p[0 : 4 : 2] = ["a", "b"]
print(p.__dict__)
p[0 : 2]
'''
0 4 2 ['a', 'b']
{'items': ['a', 2, 'b', 4]}
getitem slice(0, 2, None)
'''
比较操作
- 对于反向操作的比较运算符,如果只定义了其中一种方法,但是使用的是另外一种比较运算,系统会采用调换参数的方式进行方法调用。但是,不支持叠加操作。
import functools
@functools.total_ordering #会自动补全其他方式
class Person:
def __init__(self, age, height):
self.age = age
self.height = height
def __lt__(self, other):
print(self.age, other.age)#采用调换参数实现
return self.age < other.age#p1自动映射为self,p2映射为other
def __eq__(self, other):
return self.age == other.age
p1 = Person(18, 160)
p2 = Person(19, 240)
print(p1 < p2)#True
print(p1 * p2)#False
print(p1 == p2)#False
print(Person.__dict__)#{ '__lt__': <function Person.__lt__ at 0x0000022E1DBB4F70*, '__eq__': <function Person.__eq__ at 0x0000022E1DBB4EE0*}
print(Person.__dict__)
#: <function Person.__init__ at 0x0000022DD1554F70*, '__lt__': <function Person.__lt__ at 0x0000022DD1554EE0*, '__eq__': <function Person.__eq__ at 0x0000022DD155D040*, '__gt__': <function _gt_from_lt at 0x0000022DD14D7AF0*, '__le__': <function _le_from_lt at 0x0000022DD14D7B80*, '__ge__': <function _ge_from_lt at 0x0000022DD14D7C10*}
print(p1 <= p2)#True 组合了小于和等于
上下文环境的布尔值
class Person:
def __bool__(self):#代表了该类型对象的真假
return False
pass
p = Person()
print(bool(p))#False
遍历操作
- 怎样可以使得我们自己创建的对象可以使用for in进行遍历?①实现__getitem__方法 ②实现__iter__方法
- 怎样可以使得我们自己创建的对象可以使用next进行访问?
class Person:
def __init__(self):
self.result = 1
def __getitem__(self, item):#要自行设置终止条件,不要死循环
print("getitem")
self.result += 1
if self.result *= 6:
raise StopIteration("停止遍历")
return self.result
def __iter__(self):#方式2优先级高于getitem
#要返回迭代器,有next方法的对象才是迭代器
return self
def __next__(self):
self.result += 1
if self.result *= 6:
raise StopIteration("停止遍历")
return self.result
p = Person()
for i in p:
print(i)
'''
2
3
4
5
'''
next访问对象
class Person:
def __init__(self):
self.result = 1
def __next__(self):
self.result += 1
if self.result *= 6:
raise StopIteration("停止遍历")
return self.result
p = Person()
print(next(p))
'''
2
'''
- 对象如为迭代器必须要实现iter和next俩个方法
class Person:
def __init__(self):
self.age = 1
def __iter__(self):
self.age = 1
return self
def __next__(self):
self.age += 1
if self.age *= 3:
raise StopIteration("Stop")
return self.age
p = Person()
import collections
print(isinstance(p, collections.Iterator))#True
for i in p:
print(i)
for i in p:
print(i)
'''
2
2
'''
- 迭代器只可以遍历一次,想多次使用需要在iter中进行回退操作,也就是初始化
- getitem即使可以使用for in访问但是并不是可迭代对象
- Iterable必须是要有iter方法
- 可迭代对象一定可for in访问,反之不成立
class Person:
def __init__(self):
self.age = 1
def __iter__(self):
self.age = 1
return self
def __call__(self, *args, **kwargs):
self.age += 1
if self.age *= 4:
raise StopIteration("Stop")
return self.age
p = Person()
pi = iter(p , 4)#iter的第一个参数是一个可调用函数 第二个参数是终止值
print(pi)
for i in pi:
print(i)
'''
<callable_iterator object at 0x0000024C494A4D90*
2
3
'''
描述器
- 可以描述一个属性操作的对象
- 属性指向一个特殊的对象,该对象具有__set__,get,__delete__方法
定义
定义方式1:property
class Person:
def __init__(self):
self.__age = 18
@property
def age(self):
return self.__age
@age.setter
def age(self, value):
print("setter")
if value < 0:
value = 0
self.__age = value
@age.deleter
def age(self):
del self.__age
#age = property(get_age, set_age, del_age)
p = Person()
print(p.age) #18
p.age = 19
print(p.age)#19
定义方式2
class Age:
def __get__(self, instance, owner):
print("get")
return self
def __set__(self, instance, value):
print("set")
self = value
def __delete__(self, instance):
print("delete")
del self
class Person:
age = Age()
p = Person()
print(p.age)
p.age = 19
- 一个实例属性的正常访问顺序
- 1.实例对象自身的__dict__字典
- 2.对应类对象的__dict__字典
- 3.如果有父类,会在父类的__dict__字典中检测
- 4.如果没找到,但是有__getattr__方法,就会调此方法
- 那么究竟是如何实现__get__的优先调用?
- 内部:如果实现了描述器方法__get__就会直接调,没有就按照上述机制去查找
- 资料描述器:get/set
- 非资料描述器:仅仅实现了get方法
- 资料描述器自身属性非资料描述器
采用属性类定义
class Age:
#self是Age对象 instance是所定义的类对象
#Age对象是在各个类对象之中共享的
def __get__(self, instance, owner):
print("get", instance, owner)
return self.v
def __set__(self, instance, value):
print("set")
self.v = value
def __delete__(self, instance):
print("delete")
del self
class Person:
age = Age()
p = Person()
p.age = 18 #get <__main__.Person object at 0x0000018F6805F1C0* <class '__main__.Person'*
print(p.age)#18
p2 = Person()
p2.age = 10
print(p2.age)#get <__main__.Person object at 0x0000018F680C8850* <class '__main__.Person'*10
print(p.age)#get <__main__.Person object at 0x0000018F680C8850* <class '__main__.Person'*10
class Age:
#self是Age对象 instance是所定义的类对象
#Age对象是在各个类对象之中共享的
def __get__(self, instance, owner):
print("get", instance, owner)
return instance.v
def __set__(self, instance, value):
print("set")
instance.v = value
def __delete__(self, instance):
print("delete")
del self
class Person:
age = Age()
p = Person()
p.age = 18
print(p.age)
p2 = Person()
p2.age = 10
print(p2.age)
print(p.age)
'''
set
get <__main__.Person object at 0x000001A01723F1C0* <class '__main__.Person'*
18
set
get <__main__.Person object at 0x000001A0172A8850* <class '__main__.Person'*
10
get <__main__.Person object at 0x000001A01723F1C0* <class '__main__.Person'*
18
'''
对象的生命周期
class Person:
def __new__(cls, *args, **kwargs):
print("new可以拦截对象的创建")
pass
def __init__(self):
print("对象创建")
def __del__(self):
print("该对象被释放了886")
p = Person()#new可以拦截对象的创建
print(p)#None
del p
内存管理机制
存储方面
- python中无基本数据类型,都是对象
- 所有对象,都会在内存中开辟一块空间进行存储(会通过不同的类型和内容,开辟不同的空间大小进行存储,同时会返回“引用”(地址),用于后续对象操作
- 对于整数和短小的字符,python会进行缓存,不创建多个对象
- 容器对象存储的其他对象,仅仅是其他对象的引用,而不是其他对象本身(列表,元组)
引用计数器机制
引用计数增加场景
- 对象被创建
- 对象被引用p2 = p1
- 对象被作为参数被传到另外一个参数中去
- 对象作为一个元素存储在容器中
垃圾回收机制(处理循环引用问题
- 从经历过“引用计数器机制”仍未被释放的对象中找到循环引用并释放。
- 分代回收机制
垃圾回收时机
- 自动回收
- 手动回收
import gc
print(gc.isenabled)()#默认开
gc.disable()#关闭
print(gc.isenabled())#false
#装饰器 谁在外层先执行谁
import win32com.client
speaker = win32com.client.Dispatch("SAPI.SpVoice")
speaker.Speak("Hello world")
class Caculater:
def __say(func):
def inner(self, num):
speaker = win32com.client.Dispatch("SAPI.SpVoice")
speaker.Speak(num)
func(self, num)
return inner
def __init__(self):
self.result = 0
@__say
def add(self, num):
self.result = self.result + num
@__say
def sub(self, num):
self.result = self.result - num
@__say
def mutiple(self, num):
self.result = self.result * num
@__say
def div(self, num):
self.result = self.result / num
caculator = Caculater()
caculator.add(5)
caculator.sub(10)
继承
- 单继承:仅仅继承了一个父类
- 多继承:继承了多个父类
class Animal:
pass
class Dog:
pass
class cute(Animal, Dog):#多继承
pass
print(cute.__bases__)#(<class '__main__.Animal'*, <class'__main__.Dog'*)
print(bool.__bases__)#(<class 'int'*,)
print(int.__bases__)#(<class 'object'*,)
- 继承机制下,私有属性和私有方法都不能继承!内置的方法可以继承。
- 是继承了相关内容的访问权,而不是写入权。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eJWOq5co-1679875778926)(1.png “继承类别”)]
- 单继承:从下往上找,先从自己找,再从父类,再父父类。
- 无重叠的多继承链:先左链条往上再右链条往上,单调原则。
- 有重叠的多继承链:先父类(左-右)再爷类
class Person:
pass
class yawen(Person):
pass
import inspect
print(inspect.getmro(yawen))#(<class '__main__.yawen'*, <class '__main__.Person'*, <class 'object'*)
资源累加
#super 沿着MRO链条找到下一级结点,去调用对应的方法
class B:
def __init__(self):
self.b = 1
pass
class A(B):
def __init__(self):
super().__init__()
self.a = 2
a = A()
print(a.__dict__)#{'b': 1, 'a': 2}
多态
- 定义:一个类所能衍生出的多种形态,在继承的前提下,调用父类的同一个方法,产生不同的功能。
- 多态一般是在静态语言里面实现的,python是动态语言,实质上没有真正的多态,也不需要多态。
抽象类
- 一个抽象出来的类,不能直接创建实际的对象;抽象方法是一个抽象出来的方法,不具备具体的实现,也不能直接调用,子类不实现该方法会报错。
python中的实现
- 无法直接支持,需要借助一个模块 import abc
- 设置类的元类为abc.ABCMeta
- 使用装饰器修饰抽象方法@abc.abstractmethod
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "{}岁的小狗{}".format(self.age, self.name)
def play(self):
print("%s在玩" % self)
d = Dog("niko", 2)
d.play()#2岁的小狗niko在玩
面向对象设计原则
- SOLID
- S(Single Responsibility Principle)单一职责原则,一个类只负责一个职责。
- O(Open Closed Principle)开放封闭原则:对扩展开放,对修改关闭
- L(Liskov Substitution Principle)里氏替代方法:子类一定得具备父类的特性、方法
- I(Interface Segregation Principle)接口分离原则,如果一个类具有过多的接口方法,并且这些方法在使用的过程中并非是不可分割,那么应当将他们分离。
- D(Dependency Inversion Principle)依赖倒置原则:高层模块不应该直接依赖底层模块