面向对象的编程语言现在比较流行的无非是:java python php C++ Ruby等,这些面向对象的编程语言呢和面向过程的函数实现方式上有着本质的不同点。简单来说就是比较抽象吧。在面向对象的编程世界里,一切皆为对象,比如你学过的数组,你定义的一个变量等等都是对象。那么呢,面向对象的编程语言有哪些特点呢?根据我的总结来看,无非就是有以下属性,1.封装 2.继承 3.多态 没有这几点特性的可以说不能算是面向对象的编程语言。好了咱们不多说了,直接看看python的面向对象到底是个啥玩意?
在生活中,我们随处可见到类这个概念,比如我们人类,是一个比较大的概念,人有自己的属性和方法,属性指的是人的标识,比如你的名字,身份证id,以及你的身高等等,你的方法指的是什么呢?指的是人会干什么,人可以走路,唱歌、跳舞、等等。其实就是这样的一个例子。在比如汽车是一个类,我们把汽车看做是是一个汽车类,这样的话汽车下面会有奔驰、宝马、奥迪、QQ等品牌的车系。那么汽车有哪些属性呢?汽车有方向盘、发动机、四个轮胎等等、那么汽车有什么方法呢?汽车可以移动、可以刹车的等等这都是汽车的方法。
在Python中,类是一个具有相同属性或者方法集合的统称。类可以实现很多函数不能实现功能,比如封装、继承、等等。
我们今天主要围绕几个方面来讲解一下面向对象。
1.我们介绍了类的概念以后,先看下在python中如何定义一个类。首先定义类的关键字是class,class后面跟的是类名字,类名一般是大写字母。我们来一个例子看看,代码如下:
class Test():
class Test(object):
class Test:
上面的几种方式都可以用来定义一个类,那么类名是Test。第一个class Test后面跟的是空括号,可以什么都不写,当然你写(object)也是可以的,因为他们的作用是等价的,你不写默认继承(object)这个类,这个是规定,你把它记住就可以了,当然第三种呢,这么写好像不太雅观,当然你这么写也是没有一点的毛病,上面三种都是正常的定义类的方法。喜欢用哪个随意,被搞懵逼了就行。
2.我们定义一个Student类,这个类什么都不做,也不给这个类加任何的属性和方法,看看怎么表示
class Student():
pass
这样我们就定义完成了,那么我们如果给这个类增加属性呢?
class Student():
pass
bart = Student()
bart.name = 'ZHANSGAHN'
print bart
print bart.name
我们给Stundent类加了一个name属性,属性的值是“ZHANGSHAN”,同时我们把bart这个实例对象所在计算机的内存位置给打印出来了。当然,我们的属性是通过具体的实例bart创建出来的。我们也可以通过bart实例来访问自身的属性。
继续讨论类,我们接下来给这个加一些初始化的属性。比如名字、年龄等等属性。
class Student():
def __init__(self,name,age):
self.name = name
self.age = age
bart = Student('zhangshan',15)
print bart.name
print bart.age
我们给Student类增加了一个__init__方法,这个方法代表的是初始化属性,也就是这个类自身的属性,任何人在使用这个类或者访问该类内部的方法时都要给类的属性进行入参。就比如我们上面的由Student类创建出来的的bart实例,你需要给这个类两个参数(‘zhanshan’,15)这样才可以实例化成功。当然这里面还有几个比较重要的点:self是什么?self代表的是类本身的一个属性,它代表的是自身,在传递参数的时候可以不给self传递参数,但是sef必须放在类方法中的第一个参数位置处。这都是硬性规定,你可以把类理解为你的丈母娘,self是你的女朋友,def是你自己。你去哪里都要带着你的女朋友self。这样的理解方式是不是好些了呢?还有一个就是类下面的def函数不叫函数,叫类方法。
上面打印的结果:
zhangshan
15
我们可以看到,通过Student类创建的bart实例可以访问类自身的name和age属性了。好的,我们类的属性有了,那么我们可不可以在Student类里面增加一个方法呢?当然可以,继续看表演:
class Student():
def __init__(self,name,age):
self.name = name
self.age = age
def print_hello(self):
print 'hello,{} my age is {}'.format(self.name,self.age)
bart = Student('zhangshan',15)
bart.print_score()
我们在类的内部增加了一个print_hello方法,它的作用是打印一句话,就是print后面的那句代码。然后呢,我们通过实例化对象bart去调用这个方法实现这个打印print_hello的功能。说明什么呢?由Student类实例化的bart实例可以访问类内部自定义的属性和方法来满足功能。
我们接下来看一下类里面的继承。其实和人的继承优点类似。比如你经常会听见谁说你的眼睛向你的妈妈,鼻子向你的妈妈,其实这都是继承,只不过是遗传基因决定的我们也可以看做是属性。那么在python中的继承怎么用呢?看下面的代码:
class Animals():
def running(self):
print 'Animals is running'
我们定义了一个Animals类,用来做为所有动物的父类。该类下面有一个类方法(功能)实现打印 'Animals is running'这段话。然后我们在定义一个狗类,这个类我们什么都不做可以直接使用父类下面的running方法来实现打印'Animals is running'这段话,看代码:
class Dogs(Animals):
pass
xiaobai = Dogs()
xiaobai.running()
OK,定义了一个Dogs类,并继承了Animals父类,并且通过Dogs类实例化了一个xiaobai具体的实例对象,我们通过这个对象可以直接访问父类的running方法,从而实现了打印'Animals is running'这段话。怎么样,是不是很有意识呢?那可不可以子类不使用父类的方法,自己去创建一些方法使用呢?答案是当然可以的。接下来看代码的实现方法:
class Animals():
def running(self):
print 'Animals is running'
class Dogs(Animals):
def sing(self):
print 'dog is singsing'
xiaobai = Dogs()
xiaobai.running()
xiaobai.sing()
代码解析:
我们在Dogs子类下面创建了一个sing方法,这个方法是子类自己的,子类可以通过实例xiaobai来访问自己的sing方法。从而实现打印“dog is singsing”,当然子类也可以继续访问父类的running方法。这样的方式是不是很灵活呢?
最后我们聊一下关于类的封装。这个很重要哦!在后面的自动测试学习过程中,对数据的封装我们会经常用到,他不仅可以让我们的代码变得清晰、而且大大增强数据封装后的重用性,让你的代码结构变得更加的清晰和结构化。
在讲封装前,我们应该先看一下面向过程和面向对象在实现一个功能的区别,把这个理解以后我们就会对面向对象的数据封装有了更清晰的认识。
需求:用函数实现一个打印学生姓名以及考试成绩的一个功能,要求是使用字典存储学生的信息。
看看上面的实现方式使用函数如何解决,看下面代码:
std1 = {'name':'zhangshan','score':100}
std2 = {'name':'lishi','score':50}
def print_score(std):
print '%s 的考试成绩是 %s'%(std['name'],std['score'])
print_score(std1)
print_score(std2)
代码解析:
1.我们定义了一个字典用例储存学生std1和std2的姓名和成绩
2.定义了一个函数print_score用来实现打印成绩的功能
3.调用整个函数用来输出不同学生的姓名和成绩
打印的结果是:
zhangshan 的考试成绩是 100
lishi 的考试成绩是 50
这种方式是通过函数实现的,对最后实现的结果需要每一步做好预置条件,比如定义一个字典,定义一个函数,在去调用,向这种方式就是属于面向过程。那么在看下面向对象的实现方式和面向过程的实现由什么不同呢?
首先面向对象是把整个学生看做是一个对象,这个学生有名字name属性和score分数属性,而且学生是有一个打印成绩的方法。我们知道了这几点来看下使用面向对象怎么去实现上面的需求点。
class Student():
def __init__(self,name,score):
self.name = name
self.score = score
def print_score(self):
print '%s的考试成绩是%s'%(self.name,self.score)
DEMO1 = Student('zhanshan',100)
DEMO2 = Student('lishi',50)
DEMO1.print_score()
DEMO2.print_score()
我们看下上面的代码,可以狠明显的看出面向对象和面向过程的在实现方式上的一个本质区别。首先我定义了一个Student类,然后给类绑定了两个属性一个是name一个是score,并且在Student类下面创建了一个print_score方法,用来实现打印不同学生成绩的一个功能。最后由Student类实例化DEMO1和DEMO2两个实例化对象,通过这两个对象调用自身的print_score方法。这样就实现了打印不同学生成绩的功能了。怎么样,是不是感觉很有意思呢?
好了,关于类的知识其实还有很多,我们后面会慢慢给大家补充,今天先到这里吧。