第8 章 类和对象 以另一种思维看待世界
对世界万物的状态与行为进行归纳与分类,以此分析个体与个体间的相互作用与影响方法。
Table of Contents
前言
审视问题域的视角
你是不是人
类和对象
code
数据封装
前言
在刚学 java的时候,老师就开始灌输 everythingisobject(万物皆对象)的思想,
一切事物皆对象,通过面向对象的方式,将现实世界的事物抽象成对象,现实世界中的关系抽象成类、继承,帮助人们实现对现实世界的抽象与数字建模。
面向对象的分析根据抽象关键的问题域来分解系统。面向对象的设计是一种提供符号设计系统的面向对象的实现过程,它用非常接近实际领域术语的方法把系统构造成“现实世界”的对象。
审视问题域的视角
在现实世界中存在的客体是问题域中的主角,所谓客体是指客观存在的对象实体和主观抽象的概念,他是人类观察问题和解决问题的主要目标。
在一个熟悉的环境中,例如大家应该对学校都很熟悉,对于一个学校来说,无论学校大小,学生和老师都是主要的成员,也可以说是主要的客体,每个客体都有一些属性和行为,学生有学号、姓名、性别等属性,以及上课、考试、做实验等行为。因此,每个个体都可以用属性和行为来描述。
你是不是人
记得上学的时候,好像是思想品德或者政治之类的哲学课。提到 你是不是人,当时问的一个同学,那个同学回答说:‘我是人’, 老师呵斥 你不是人,当然这并不是和这个同学有仇,也不是这个同学做了什么。这里的 人和 你在哲学上病不是一个,也就是 你永远不可能是人, 人是我们每个特殊个体高度归纳,而我们每个都是一个 特殊的个体,而不是抽象的 人, 人是我们的 共性,我们每个个体又有自己的 特性,所以 人非人(具体哲学意义,去问我老师吧)
抽象是人类解决问题的基本法宝。良好的抽象策略可以控制问题的复杂程度,增强系统的通用性和可扩展性。将描述客体的属性和行为绑定在一起,实现统一的抽象,从而达到对现实世界客体的真正模拟。
现实生活中,我们经常讲一类有共性的事物,进行分类,例如:桌子,椅子,汽车,动物等
类和对象
具有相同特性和行为的事物的抽象就是类。例如上面提到的 人, 人表示了一类相同特性的个体,每个个体又叫做 对象,人就是我们的高度归纳和抽象,我们就是人的具体化,同理 对象的抽象是 类, 类的具体化就是 对象,也可以说 类的实例是 对象
类具有属性,它是对象的状态的抽象。 类具有操作,它是对象的行为的抽象。
code
以人为例,在Python中,定义类是通过class关键字:
classPerson(object):
pass
class后面紧接着是 类名,即 Person,类名通常是大写开头的单词,紧接着是 (object),表示该类是从哪个类 继承下来的,继承的概念我们后面再讲,通常,如果没有合适的继承类,就使用 object类,这是所有类最终都会继承的类。毕竟我们都是 共产主义接班人
定义好了 Person类,就可以根据 Person类创建出 Person的实例,创建实例是通过 类名+ ()实现的:
classPerson(object):
pass
zhangyunan=Person()
zhangyunan
Out[4]:<__main__.personat0x10fa44940>
可以看到,变量 zhangyunan指向的就是一个 Person的实例,后面的0x10fa44940是内存地址,每个object的地址都不一样,这就是特性了,而 Person本身则是一个类。也是就我们的共性。
我怎么体现我的特性,首先我的有个名字
python可以自由地给一个实例变量绑定属性,比如,我要有个名字:
zhangyunan.name='张瑀楠'
zhangyunan.name
Out[6]:'张瑀楠'
现在社会平等了,每个人都可以有自己的名字和性别,当然这是必须的,由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的 __init__方法,在创建实例的时候,就把name,sex等属性绑上去:
classPerson(object):
def__init__(self,name,sex):
self.name=name
self.sex=sex
注意:特殊方法_init_前后有两个下划线!!!
注意到 __init__方法的第一个参数永远是 self,表示创建的实例本身,因此,在 __init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。
有了 __init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与 __init__方法匹配的参数(还记得位置参数吧)但self不需要传,Python解释器自己会把实例变量传进去:
classPerson(object):
def__init__(self,name,sex):
self.name=name
self.sex=sex
zhangyunan=Person('张瑀楠','male')
和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,并且,调用时,不用传递该参数。除此之外,类的方法和普通函数没有什么区别,所以,你仍然可以用默认参数、可变参数、关键字参数和命名关键字参数。
数据封装
面向对象编程的一个重要特点就是数据封装。在上面的 Person类中,每个实例就拥有各自的name和sex这些数据。我们可以通过函数来访问这些数据,比如访问名字
print(zhangyunan.name)
张瑀楠
我想知道自己的名字,没有必要让别人告诉我吧!
但是,既然Person实例本身就拥有这些数据,要访问这些数据,就没有必要从外面的函数去访问,可以直接在Person类的内部定义访问数据的函数,这样,就把“数据”给封装起来了。这些封装数据的函数是和Student类本身是关联起来的,我们称之为类的方法:
classPerson(object):
"""
人类,每个人都应该有名字和性别
"""
def__init__(self,name,sex):
self.name=name
self.sex=sex
defprint_name(self):
"""
打印我的名字
:return:
"""
print('我的名字是:',self.name)
zhangyunan=Person('张瑀楠','male')
zhangyunan.print_name()
我的名字是:张瑀楠
要定义一个方法,除了第一个参数是self外,其他和普通函数一样。要调用一个方法,只需要在实例变量上直接调用,除了self不用传递,其他参数正常传入:
还记得讲函数时用到的的学生等级函数吧
defscore_level(score):
ifscore<60:
level='不及格'
elifscore<70:
level='继续努力'
elifscore<80:
level='中等'
elifscore<90:
level='良好'
else:
level='优等生'
returnlevel
这方法是不是和学生有关呢?那赶紧趁热来个学生类吧!
classStudent(object):
"""
学生类,主要就是学习和切磋成绩了,除了姓名和性别,他们的分数是最重要的
"""
def__init__(self,name,sex,score):
self.name=name
self.sex=sex
self.score=score
defscore_level(self):
"""
告诉大家,我的学习成绩
:return:
"""
ifself.score<60:
level='没你考的好'# 都不及格了,就含蓄一点了
elifself.score<70:
level='开心就好'
elifself.score<80:
level='继续努力'
elifself.score<90:
level='自信满满'
else:
level='还有谁'
returnlevel
# 也不知道为什么,100分的试卷,我老是考101 分,别人都不信
zhangyunan=Student('张瑀楠','male',101)
print(zhangyunan.score_level())
还有谁
太晚了,我要读书了,明天继续
本文介绍了面向对象编程的基本概念,包括如何使用Python定义类和对象,以及如何实现数据封装。通过具体的例子展示了如何创建类和实例,并对类的方法进行了说明。

被折叠的 条评论
为什么被折叠?



