面向对象是Python最重要的特性,在Python中一切数据类型都是面向对象的。
1、面向对象概述
面向对象的编程思想是,按照真实世界客观事物的自然规律进行分析,客观世界中存在什么样的实体,构建软件系统就存在什么样的实体。
例如,在真实世界的学校里,会有学生和老师实体,学生有学号、姓名、所在班级等属性(数据),学生还有学习、提问、吃饭和走路等操作。学生只是抽象的描述,这个抽象的描述称为“类”。在学校活动的是学生个体,即张同学、李同学等,这些具体的个体称为“对象”,对象也称为“实例”。
在现实世界有类和对象,软件世界也有面向对象,只不过他们会以某种计算机语言编写的程序代码形式存在,这就是面向对象编程。
2、面向对象三个基本特性
面向对象思想有三个基本特性:封装性、继承性和多态性。
封装性
面向对象的封装使外部访问者不能随意存取对象的内部数据,隐藏了对象的内部细节,只保留有限的对外接口。外部访问者不需要关心对象的内部细节,操作对象变得简单。
继承性
举例,轮船与客船的关系,客船具有轮船的全部特征和行为。
在面向对象中,轮船是一般类,客船是特殊类,特殊类拥有一般类的全部数据和操作,称为特殊类继承一般类。一般类称为“父类”或“超类”,特殊类称为“子类”或“派生类”。
多态性
多态性是指在父类中成员被子类继承之后,可以具有不同的状态或表现行为。
3、类和对象
Python中的数据类型都是类,类是组成Python程序的基本要素,它封装了一类对象的数据和操作。
定义类
Python语言中一个类的实现包括类定义和类体。
类定义语法格式如下:
class 类名 [(父类)]: 类体
其中,class是声明类的关键字,“类名”是自定义的类名,应该遵守Python命名规范,采用大驼峰法命名。“父类”声明当前继承的父类,父类可以省略声明,表示直接继承object类。
演示:
class Student(object):# 类体pass
注意:上述代码声明了一个学生类,它继承了object类,object是所有类的根类,在Python中任何一个类都直接或间接的继承object,所以(object)部分代码可以省略。 pass语句什么操作都不执行,用来维持程序结构的完整,进行占位。
创建和使用对象
一个对象的生命周期包括三个阶段:创建、使用和销毁。销毁对象时Python的垃圾回收机制释放不再使用的内存,不需要程序员负责。程序员只需关心创建和使用对象。
创建对象代码演示:
class Student(object):# 类体passstudent = Student()print(student)
结果:
解释:Student()表达式创建了一个学生对象,并把创建的对象赋值给student变量,student是指向学生对象的一个引用。通过student变量可以使用刚刚创建的学生对象。print函数打印对象输出。事实上,print函数调用了对象的_str_()方法输出字符串信息,str()方法是object类的一个方法。
实例变量
类成员展示:
“实例变量”就是某个实例(或对象)个体特有的“数据”,例如学生的姓名、学号、性别等。
代码演示:
class Student(object):"""定义学生类"""def __init__(self, name, sex, student_id):self.name = name# 定义姓名实例变量self.sex = sex# 定义性别实例变量self.student_id = student_id# 定义学号实例变量student = Student('张三', 1, 1711010201)print('姓名:{0}'.format(student.name))print('性别:{0}'.format('女'if student.sex == 0 else '男'))print('学号:{0}'.format(student.student_id))
结果:
注意:代码def语句是构造方法,构造方法是用来创建和初始化实例变量的。构造方法中的self指向当前实例的引用。代码self.name是在创建和初始化实例变量name,其中self.name表示对象的name实例变量。student.name是访问name实例变量。
类变量
“类变量”是所有实例(或对象)共有的变量。例如,学生的学费,假设每人的学费相同,那就可以在学生的类中设置一个类变量。
代码演示(上例代码重构):
class Student(object):"""定义学生类"""tuition = 4800# 类变量学费def __init__(self, name, sex, student_id):self.name = name# 定义姓名实例变量self.sex = sex# 定义性别实例变量self.student_id = student_id# 定义学号实例变量student = Student('张三', 1, 1711010201)print('姓名:{0}'.format(student.name))print('性别:{0}'.format('女'if student.sex == 0 else '男'))print('学号:{0}'.format(student.student_id))print('学费:{0}'.format(Student.tuition))
结果:
注意:类变量在方法之外定义,访问通过“类名.类变量”的形式访问。切勿通过“实例名.类变量”的形式访问,不符合设计规范。也不要在类之外创建实例变量,他们无法通过类中的方法访问。
构造方法
在前几例代码中有_init_()方法,该方法用来创建和初始化实例变量,这种方法就是“构造方法”。init()方法也属于魔法方法。
在此不做代码演示。
注意:定义时他的第一个参数是self,其后的参数才是用来初始化实例变量的,这些参数可以有默认值。调用构造方法是不需要传入self。
实例方法
实例方法与实例变量一样都是某个实例(或对象)个体特有的。
方法是定义在类中的函数,而定义实例方法时他的第一个参数也应该是self,这个过程是将当前实例与该方法绑定起来,使该方法称为实例方法。
代码演示:
class Student(object):"""定义学生类"""tuition = 4800# 类变量学费def __init__(self, name, sex, student_id, weight):self.name = name# 定义姓名实例变量self.sex = sex# 定义性别实例变量self.student_id = student_id# 定义学号实例变量self.weight = weight# 定义体重实例变量def eat(self):self.weight += 0.8print('eat...')student = Student('张三', 1, 1711010201, 60)print('姓名:{0}'.format(student.name))print('性别:{0}'.format('女'if student.sex == 0 else '男'))print('学号:{0}'.format(student.student_id))print('学费:{0}'.format(Student.tuition))print('体重:{0}'.format(student.weight))student.eat()print('{0}体重:{1}'.format(student.name, student.weight))
结果:
注意:student.eat()语句就是调用实例方法
类方法
“类方法”与“类变量”类似属于类,不属于个体实例的方法,类方法不需要与实例绑定,但需要与类绑定,定义时他的第一个参数是类的type实例。type是描述Python数据类型的类,Python中所有数据类型都是type的一个实例。
代码演示:
class Student(object):"""定义学生类"""tuition = 4800# 类变量学费def __init__(self, name, sex, student_id, weight):self.name = name# 定义姓名实例变量self.sex = sex# 定义性别实例变量self.student_id = student_id# 定义学号实例变量self.weight = weight# 定义体重实例变量def eat(self):self.weight += 0.8print('eat...')# 学费与重修费之和@classmethoddef tuition_add(cls, repair_fee):return cls.tuition + repair_feestudent = Student('张三', 1, 1711010201, 60)print('姓名:{0}'.format(student.name))print('性别:{0}'.format('女'if student.sex == 0 else '男'))print('学号:{0}'.format(student.student_id))print('学费:{0}'.format(Student.tuition))print('体重:{0}'.format(student.weight))student.eat()print('{0}体重:{1}'.format(student.name, student.weight))print('学费与重修费总和:{0}'.format(Student.tuition_add(400)))
结果:
注意:定义类方法的两个关键: 一、方法第一个参数是cls是type类型,是当前Student类型的实例; 二、方法使用装饰器@classmethod声明该方法是类方法。 类方法使用: 类方法可以访问类变量和其他类方法,但不可访问其他实例方法和实例变量; 类方法调用采用“类名.类方法”形式调用。可以通过实例调用,但不符合规矩。
静态方法
如果定义的方法既不想与实例绑定,又不想与类绑定,只是想把类作为他的命名空间,那么可以定义静态方法。
代码演示(上述代码重构):
class Student(object):"""定义学生类"""tuition = 4800# 类变量学费def __init__(self, name, sex, student_id, weight):self.name = name# 定义姓名实例变量self.sex = sex# 定义性别实例变量self.student_id = student_id# 定义学号实例变量self.weight = weight# 定义体重实例变量def eat(self):self.weight += 0.8print('eat...')# 学费与重修费之和# 类方法@classmethoddef tuition_add(cls, repair_fee):return cls.tuition + repair_fee# 静态方法@staticmethoddef tuition_with(repair_fee):return Student.tuition_add(repair_fee)student = Student('张三', 1, 1711010201, 60)print('姓名:{0}'.format(student.name))print('性别:{0}'.format('女'if student.sex == 0 else '男'))print('学号:{0}'.format(student.student_id))print('学费:{0}'.format(Student.tuition))print('体重:{0}'.format(student.weight))student.eat()print('{0}体重:{1}'.format(student.name, student.weight))print('学费与重修费总和:{0}'.format(Student.tuition_add(400)))print('学费与重修费总和:{0}'.format(Student.tuition_with(400)))
结果:
注意:@staticmethod装饰器,声明方法是静态方法,方法参数不指定self和cls。 调用静态方法与调用类方法相似都通过类名实现,也可以通过实例调用,但不符合规范。 类方法与静态方法在很多场景是类似的,只是在定义时有一些区别。类方法需要绑定类,静态方法不需要绑定类,静态方法与类的耦合度更加松散。 在类中定义静态方法只是为了提供一个基于类名的命名空间。
欢迎参考学习,有错请指证,喜欢的请关注本人博客,不定期更新学习心得,学习笔记。
Python基础学习——面向对象编程(第一讲:面向对象概述 面向对象三个基本特征(封装性 继承性 多态性) 类和对象(定义类 创建和使用对象 实例变量 类变量 构造方法 实例方法 类方法 静态方法))