最早的程序设计方法是面向过程的程序设计,这里的过程,其实就是流程。世间有万事,万事各不同,所谓不同,就是流程不同。既然你的程序是针对某个具体的问题,处理的方法和流程当然不同,这样说来,你所精心设计的程序,往往只能解决具体问题,而不具备普遍性和可变性。 面向对象程序设计(ObjectOrientedProgramming,OOP),它是一种程序设计思想,其本质是通过抽象方法建立模型,再将模型具体化的方法。 举一个例子。汽车是一个非常宽泛的概念,大大小小,不同颜色,形态各异的汽车,都属于汽车这个类,颜色、轮胎数量、车门个数等属性都是汽车类的属性,启动、前进、加速、倒车、刹车等都是汽车类的动作(这里的动作被称为方法),这些属性和方法既可以指定为具体值,也可以仅仅列出而不赋值。我们也可以定义汽车类的一个子类,譬如红色小轿车,而一辆具体的车,假如车号为88888的汽车是红色小轿车类的一个实例,该汽车便是一个对象,该对象除了已经继承了红色小轿车类的颜色属性,其他的属性和方法还是继承了父类汽车的属性和方法。 综上,面向对象程序设计以对象为核心,该方法认为程序由一系列对象组成。类是对现实世界的抽象,包括表示静态属性的数据和对数据的操作,对象是类的实例化。对象间通过消息传递相互通信,来模拟现实世界中不同实体间的联系。在面向对象的程序设计中,对象是组成程序的基本模块。 面向对象程序设计具有三大基本特征:封装、继承和多态。 下面简要的介绍一下上述提到的名词: 1、对象(Object) 这是一个抽象的概念,世间万物皆对象,任何事情和物品都可以用对象来描述。譬如说,在设计学生信息处理程序时,可以将王小明同学看成一个研究对象,他有静态属性和动态属性。静态属性有姓名、性别、出生年月(静态属性一般简称为属性)等,动态属性有动作、行为(动态属性一般被称为方法)等。 2、类(class) 一个共享相同结构和行为的对象的集合。类(Class)定义了一类事物(对象)的抽象特点。通常来说,类定义了每个对象共有的属性和方法。举例来说,学生这个类会包含了所有学生的一切基础特征,例如籍贯、性别、专业和预约考试、查询成绩。王小明同学就是学生类的一个实例,是学生类的具体化,当然也就继承了学生类的全部属性和方法,如他一定有籍贯、性别、专业三个属性和预约考试、查询成绩两个方法。 3、封装(encapsulation) 封装就是对用户隐藏实现细节。如我们使用手机通话时,关心的是通话的内容,而不需要了解无线电波是如何传播的。此时的手机就是一个黑盒子,我们无须知道其工作原理。 面向对象程序设计中的封装,有两层含义:其一是将数据和操作捆绑在一起,创造出一个新的类型的过程;其二是将接口与实现分离的过程。 采用封装思想可以保证类内部数据结构的完整性,使用该类时,用户看不到类中的数据结构,只能通过设计者提供的方法来访问即可,从而提高了程序的可维护性。 4、继承 在日常生活中,继承这个概念适合于长辈与晚辈之间。对于类,也可以分为父类和子类。对象可以继承它从属的类的属性和方法,子类也可以继承父类的属性和方法, 5、多态 有一句俗语说一龙生九子,九子各不同。虽然各个子类都继承了父类,但继承的都是共有的属性和方法,而各个子类都有属于自身特有的属性和方法,比如不同专业的学生的课程会不同。 下面举一个例子说明消息传递方面的的多态:比如教师和学生都是用户,都是通过鼠标点击同一个按钮(譬如查看成绩),但进入的界面就不一样,教师看到的是全班所有学生的成绩,而学生看到的只有本人成绩。 6、消息传递 指的是一个对象调用了另一个对象的方法(或者称为成员函数)。 7、方法 也称为成员函数,是指对象上的操作,作为类声明的一部分来定义。方法定义了可以对一个对象执行那些操作。 下面重点介绍类的概念及其应用 1、定义类 具有相同的属性和方法的对象所构成的集合就是类。 语法: classClassName: statement 其中,ClassName是类名,一般使用大写字母开头,如果类名中包括两个单词,应当采用驼峰式命名法,即每个单词的首字母大写,其余字母小写。statement表示类体,包含类变量(或类成员)、方法和属性等定义语句,如果没有类体可以描述,就用pass语句代替。如:classStudent: pass 这个空的类,你可以将其想象为一个占位符,虽然它没有实质性的意义,但在以后的编程过程中你可以根据需求去扩充它,让它饱满。 下面举例说明一个完整的类的语法结构,如: classStudent: definit(self,name,tel): self。namename self。teltel defprinttel(self): print(s:s(self。name,self。tel)) 这里定义了一个类,类名为Student。init()是一个特殊方法(是两个连续的号),类似于Java中的构造方法,每当创建一个类的实例,Python就会自动执行它。其中必须包含参数self,它指向类本身,在实例化时则指向实例本身。上面的Student类的init()方法还有两个参数name和tel,实例化时将被具体的实例变量所代替。printtel()方法访问的类本身的数据,在实例化时也是调用了实例变量。 2、类实例化 类的实例化相当于将类具体化,赋予一组具体的值。和函数调用相似,但又比函数调用复杂。因为类既包含数据,又包含操作数据的方法。 如: tomStudent(Tom,8888888) jimStudent(Jim,7777777) tom。printtel() jim。printtel() 运行结果: Tom:8888888 Jim:7777777 可以看出,创建实例是通过类名和()实现的,实例参数要和类属性对应,如’Tom’和类属性name对应,‘8888888’和类属性tel对应。 tom是Student类的一个实例,它也就能调用类的方法,如tom。printtel()。如在上面的例子中,添加下面的语句: tom。nameBaumlR。W tom。printtel() 运行结果: Tom:8888888 Jim:7777777 BaumlR。W:8888888 可见,语句tom。nameBaumlR。W使实例tom的属性name的值发生了改变。 3、私有属性与私有方法 类可以有公有属性与公有方法,也可以有私有属性与私有方法,公有部分的对象可以从外部访问,而私有部分的对象只有在类的内部才可访问。定义私有属性(或方法)时要在的属性名(或方法名)的前面加上两个连续的号。 现在通过下例介绍私有属性与私有方法的用法: classPubAndPri: pub10此为公有属性 pri20此为私有属性 xPubAndPri()x为类PubAndPri的实例 print(publicvar:,x。pub)通过实例名访问公有属性 print(privatevar:,x。pri)通过实例名访问私有属性 运行结果: publicvar:10 Traceback(mostrecentcalllast): FileC:UsersAdministratorAppDataLocalProgramsPythonPython382。py,line11,in print(privatevar:,x。pri) AttributeError:PubAndPriobjecthasnoattributepri 可见,通过实例名访问私有属性时就会报错。 为了访问私有属性,只能在类中增加一访问私有属性的方法。将上例中的程序修改如下: classPubAndPri: pub10 pri20 definit(self): print(privatevar:,pri)在方法中访问私有属性 xPubAndPri() print(publicvar:,x。pub) print(privatevar:,x。PubAndPripri) f访问私有属性,格式:实例名。类名私有属性名(第一个为一个,第二个为两个) 运行结果: publicvar:10 privatevar:20 由上可以看出,私有属性可以通过实例名。类名私有属性名的方式访问,但在构造方法中要有相关的访问语句。 4、继承与多态 子类可以继承父类的所有公共成员。父类也称基类,子类也称派生类。声明父类的方法是在类名后面的括号中列出。若不声明父类,默认的父类是object。 下面通过一个实例来介绍继承与多态: 程序1:子类完全继承父类 classPerson(object):定义了一个类Person definit(self,name,sex):类Person有两个属性name和sex self。namename self。sexsex defprintinfo(self):定义了Person类的方法 ifself。sexmale: print(self。nameisman) elifself。sexfemale: print(self。nameiswoman) classChild(Person):定义了一个子类Child,父类为Person pass KingChild(King,male)创建子类Child的实例 MaryPerson(Mary,female)创建父类Person的实例 print(King。nameisKing。sex,,Mary。nameisMary。sex) King。printinfo()调用子类Child的printinfo方法 Mary。printinfo()调用父类Person的printinfo方法 运行结果: KingismaleMaryisfemale Kingisman Maryiswoman 程序2:子类重写父类的方法 classPerson(object):定义了一个类Person definit(self,name,sex):类Person有两个属性name和sex self。namename self。sexsex defprintinfo(self):定义了Person类的方法 ifself。sexmale: print(self。nameisman) elifself。sexfemale: print(self。nameiswoman) classChild(Person):定义了一个子类Child,父类为Person defprintinfo(self):重写方法printinfo() ifself。sexmale: print(self。nameisboy) elifself。sexfemale: print(self。nameisgirl) KingChild(King,male)子类实例化 MaryPerson(Mary,female)父类实例化 print(King。nameisKing。sex,,Mary。nameisMary。sex) King。printinfo() Mary。printinfo() 输出结果: KingismaleMaryisfemale Kingisboy Maryiswoman 对比程序1和程序2的运行结果可知,程序1中的子类完全继承了父类的属性和方法,程序2中的子类在继承父类的属性和方法的基础上,又对父类的方法进行了重写,从而使子类并不和父类完全相同,这种情况被称为多态,比如程序2中的子类就有不同于父类中的方法printinfo(),子类的实例调用的是子类特有的方法,父类的实例调用的是父类的方法。 程序3:子类中重写父类的构造方法 classPerson(object):定义了一个类Person definit(self,name,sex):类Person有两个属性name和sex self。namename self。sexsex classChild(Person):定义了一个子类Child,父类为Person definit(self,name,sex,brother,sister):子类构造方法添加两个属性 Person。init(self,name,sex)继承父类的构造方法 self。brotherbrother添加属性 self。sistersister添加属性 KingChild(King,male,Tom,Jane)创建子类Child的实例 MaryPerson(Mary,female)创建父类Person的实例 print(King。name,:,King。sex,King。brother,King。sister) print(Mary。name,:,Mary。sex) 输出结果: King:maleTomJane Mary:female 如上,子类在继承父类属性的基础上,可以通过重写构造方法再建立独有的属性。