python 类和oop
2022-04-05 17:00 jym蒟蒻 阅读(74) 评论(0) 编辑 收藏 举报文章目录
- oop:面向对象程序设计
- python类的特点:
- oop基本概念:
- 1.属性继承搜索:
- 2.类和实例:
- 3.类方法调用
- 4.编写类树
- 5.代码重用
1.类:一些函数的包,这些函数大量使用并处理内置对象类型。
2.类的设计是为了创建和管理新的对象。类是定义新种类东西的方式。
3.通过类来实现一个对象,也就意味着建立对象实际结构和关系的模型。
4.继承:学生属于人,学生拥有一般人的属性,在oop术语里面,学生继承了人的通用属性,这些通用属性只需实现一次,就能在我们创建所有种类人的时候使用。
5.组合:组合就是组件的集合。学生是一个组合的实例,学生类里面还包含其他对象,比如学习。每个组件都可以写成类,定义自己的行为和关系,学习可以写成一个学习类。
6.对于GUI系统:写成图形组件的集合(按钮,标签)可以称为接口,绘制图形组件的容器时,图形组件也跟着绘制,这是一种组合。我们编写定制的图形组件(有独特颜色形状的按钮或标签),可以通过接口的继承机制实现。
1多重实例:类是产生对象的工厂,每调用一个类,就产生一个独有命名空间的新对象。这个对象能够读取类的属性,并可以用自己的命名空间来存储数据,而且不同对象数据也不同。
2通过继承进行定制:在类的外部重新定义其属性从而扩充这个类。
3运算符重载:类可以定义对象来响应在内置类型上的几种运算。
object.attribute(对象.属性)
这个表达式,会在python中启动搜索,去搜索一个种种对象连接的树,寻找attribute首次出现的对象,找到之后停止搜索。先搜索object,然后是该对象之上的所有类,从下到上,从左到右。
下面这个例子:c1c2c3为类对象,l1,l2为实例对象。
1.就搜索树来看,实例从他的类继承属性,类是从搜索树中所有比他更上层的类中继承属性。
2.超类提供了所有子类共享的行为,但因为搜索由下而上,子类可能在树中较低位置重新定义超类变量名,覆盖超类的定义。
3.比如l2.w的搜索顺序:l2,c1,c2,c3,也就是说,l2从c3继承了属性w
l1.x搜索顺序:l1,c1
l1.name搜索顺序:l1
如果说找不到某一属性,比如:l1.k,此时发生错误。
类通常都有函数,而实例有一些数据项,类的函数使用了这些数据。实例像是带有数据的记录,类是处理这些记录的数据。
调用类函数的时候,总会有一个主体对象,这个主体就是类的实例。python把隐含的实例传进方法中。方法能够通过实例或类进行调用。jack.givemoney()同于employee.givemoney(jack)。
l2.w()的意思是调用c3.w处理l2,l2.w()同于c3.w(l2)
每个class对象会生成一个新对象。
每次类调用时,会生成新的实例对象。
实例自动连接至创建这些实例的类。
类连接至其超类的方式,将超类列在类头部的括号内,其从左至右的顺序会决定树中的次序。(在类树中,class语句小括号内有一个以上超类,他们从左至右的次序决定超类搜索的顺序)
上面的图可以表示成:
#创建三个类对象
class C2:#省略具体内容
class c3: #省略
class C1(c2,c3):#省略
#创建两个实例对象
l1=c1()
l2=c2()
附加在实例上的属性只属于那些实例,而附加在类上的属性,由所有子类及其实例共享。如c1和l1
python把隐含的实例传进方法中第一个特殊的参数,习惯称之为self。
class c1(c2,c3):
def setname(self,who):
self.name=who
l1=c1()
l1.setname('jack')
print(l1.name)
类通过函数为实例提供行为,上面例子,l1传入self里,指明了类处理的实例是l1,然后通过类里面的函数def对self做赋值运算,把属性添加到类对象之中。self用来存储实例内部变量名。
对于类来说:属性通常是在class语句中通过赋值语句添加在类中,而不是通过def函数。
对于实例来说:属性通常是在类内,对传给def函数的特殊参数(self),做赋值运算,而添加在实例中。
通过构造函数,创建实例时初始化实例。
上述代码,在setname方法调用前,c1不会把name属性附加在实例上,那么在调用l1.setname前引用l1.name会产生未定义变量名的错误。如果类要确保name变量名一定会在实例中被设置,通常在构造时就填好这个属性。
class c1(c2,c3):
def _init_(self,who):
self.name=who
l1=c1('jack')
print(l1.name)
每次从类产生实例时,python会自动调用名为_init_
的方法,它也称之为构造函数。新实例传入self参数,类调用小括号内的任何值成为第二个及以后的参数。
通过类,我们可以定制现有的软件来编写代码,而不是对现有代码进行原处修改,或者每个项目都从头开始。自动属性继承搜索,软件定制,这些是通过模块和函数做不到的。
方法只有特殊第一参数self的函数,我门可以把要处理的对象传给简单函数,模拟其行为。方法参与了类的继承,我们可以通过定义新方法编写子类,而不用原处修改代码。
class employee:
def computesalary(self):#省略内容
def giveraise(self):#省略
def promote(self):#省略
def retire(self):#省略
employee是一个通用的超类,定义所有员工默认的通用行为。
class engineer(employee):
def computesalary(self):#省略
这里engineer继承了employee,是他的一个子类,这里我们重载了computesalary方法,实现了定制的目的。这个engineer类型的员工的其他行为会继承employee里面的行为。
之所以说定制,是因为这里的computesalary在employee的下面。所以类树搜索时搜到他就截止。
jack=employee()
kk=engineer()
我们可以对树中任何类创建实例,创建的实例所用的类,会决定其属性搜索从哪个层次开始。
company=[jack,kk]
for emp in company:
print(emp.computesalary())
两个实例对象,可以嵌入到一个更大的容器对象里,从而可以代表一个部门
这个for里面也用到了多态,隐藏了接口的差异性。
多态还可以用到下面:
处理数据流的程序,可以写成预期有输入和输出方法的对象,而不用关心那些方法实际做的是什么
def processor(reader,converter,writer):
while 1:
data = reader.read()
if not data:break
data=converter(data)
writer.write(data)
class reader:
def read(self):#省略
def other(self):#省略
class filereader(reader):
def read(self):#省略
class socketreader(reader):
def read(self):#省略
#...省略...
processor(filereader(...),converter,filewriter(...))
processor(ftpreader(...),converter,xmlwriter(...))
所谓框架,就是把常见程序设计成类,让你可以编写一些子类,写一两个方法,树中较高位置的框架类会替你做大多数工作。