文章目录

  • 面向过程
  • 面向过程特点
  • 面向对象
  • 面向对象特点
  • 对象和类
  • 定义类
  • 类创建对象
  • 封装特性
  • 封装的特性
  • 继承特性
    • 多继承
  • 新式类与经典类
  • 私有属性与私有方法
  • 私有属性和私有方法:
  • 多态
    • 多态特点

C语言属于面向过程的语言,而C++、JAVA、python都属于面向对象的语言。

面向过程

面向过程”(Procedure Oriented)是一种以过程为中心的编程思想。分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。面向过程最重要的是模块化的思想方法。例如前面博客所写的学生信息管理系统的主函数

面向过程特点

模块化 流程化
优点: 性能比面向对象高, 因为类调用时需要实例化,开销比较大,比较消耗资源;
单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。
缺点: 没有面向对象易维护、易复用、易扩展

面向对象

面向对象是按人们认识客观世界的系统思维方式,把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。(一个类具有的共同行为)

面向对象特点

封装 继承 多态
优点:易维护、易复用、易扩展。
由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护
缺点: 性能比面向过程低。

对象和类

类(Class) 是现实或思维世界中的实体在计算机中的反映,它将数据以及这些数据上的操作封装在一起。是一个抽象画的概念。
对象(Object) 是具有类型的变量,即:将类实例化/具体化产生的值。类和对象是面向对象编程技术中的最基本的概念。
比如:类和对象 的区别就是鱼和三文鱼的区别; 猫和蓝猫的区别。

定义类

#class 类的名称:
class Person:       #定义类的方式pass            #占位关键字,什么也不做
print(Person)#运行结果
<class '__main__.Person'>         #表示存储于当前脚本的Person类。__main__表示当前脚本

类创建对象

实例化是指在面向对象的编程中,把用类创建对象的过程称为实例化
是将一个抽象的概念类,具体到该类实物的过程。
实例化过程中一般由类名对象名 = 类名(参数1,参数2…参数n)构成。

# 对象:将类实例化/具体化产生的值
personObj = Person()
print(personObj)                                                # 当前脚本的Person类实例化出来的对象存储的内存地址是0x7f28164b04d0
#运行结果:<__main__.Person object at 0x7f28164b04d0>

封装特性

封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。
通俗来讲就是将对象和属性绑定在一起的操作,用对象进行调用。
所以,在使用面向对象的封装特性时,需要:
1). 将内容封装到某处
2). 从某处调用被封装的内容
调用被封装内容的方式有:
1). 通过对象直接调用被封装的内容:对象名.属性名
2). 通过self间接调用被封装的内容:self.属性名
3). 通过self间接调用被封装的内容: self.方法名()
如:案例:实现数据的封装:

class Student:def __init__(self, name, score1, score2):# 将对象和属性封装在一起self.name = nameself.score1 = score1self.score2 = score2def compute_sum_score(self):# 获取封装的属性信息方法一: 通过self.属性名的方式获取。return  self.score1 + self.score2
stu1 = Student(name="小红", score1=100, score2=99)# 获取封装的属性信息方法二: 通过对象名.属性名的方式获取。
print("学生姓名: ",  stu1.name)# 获取封装的属性信息方法三: 通过对象名.方法名的方式获取。 stu1.compute_sum_score()为方法名
sum_scores = stu1.compute_sum_score()
print("总分数: ", sum_scores)#打印结果:
学生姓名:  小红
总分数:  199

构造方法__init__与其他普通方法不同的地方在于,在创建对象(或实例化对象)时会立即调用构造方法。自动执行构造方法里面的内容。

class Student:# 实例化对象的过程中自动执行的函数def __init__(self):         # self是形参# self实质上实例化出来的对象。系统自动将实例化的对象传递给构造方法。print("self: ", self)print("正在运行构造方法........")print(Student)      # <class '__main__.Student'>
# 实例化产生对象的过程
stu1 = Student()
print("stu1: ", stu1)#打印结果:
<class '__main__.Student'>
self:  <__main__.Student object at 0x000001B0A0D76CC0>
正在运行构造方法........
stu1:  <__main__.Student object at 0x000001B0A0D76CC0>

封装的特性

将变化隔离;
便于使用;
提高复用性;
提高安全性;
封装练习:创建一个类People,拥有的属性为姓名, 性别和年龄, 拥有的方法为购物,玩游戏,学习;实例
化对象,执行相应的方法。 显示如下:
小明,18岁,男,去西安赛格购物广场购物
小王,22岁,男,去游乐场玩耍
小红,10岁,女,在学校学习
提示:
属性:name,age,gender
方法:shopping(), playGame(), learning()
代码如下:

class People:def __init__(self, name, gender, age):self.name = nameself.gender = genderself.age = agedef shopping(self):print("%s,%d岁,%s,去西安赛格购物广场购物" %(self.name,self.age,self.gender))def playGame(self):print("%s,%d岁,%s,去游乐场玩耍" %(self.name,self.age,self.gender))def learning(self):print("%s,%d岁,%s,在学校学习" % (self.name, self.age, self.gender))People1=People(name="小明",gender="男",age=18)
People2=People(name="小王",gender="男",age=22)
People3=People(name="小红",gender="女",age=10)
People1.shopping()
People1.learning()
People3.playGame()
#打印结果:
小明,18岁,男,去西安赛格购物广场购物
小明,18岁,男,在学校学习
小红,10岁,女,去游乐场玩耍

继承特性

继承描述的是事物之间的所属关系,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类、扩展类(Subclass),而被继承的class称为基类(Baseclass)、父类或超类(Superclass)。
实现继承:子类在继承的时候,在定义类时,小括号()中为父类的名字。
继承的工作机制:会将父类的属性、方法,会被继承给子类。
1)举例如下: 如果子类没有定义__init__方法,父类有, 那么在子类继承父类的时候这个方法就被继承了,所以只要创建对象,就默认执行了那个继承过来的__init__方法。
2)调用父类的方法:
1>父类名.父类的方法名()
2>super(): py2.2+的功能

class Student(object):def __init__(self,name,age,gender):self.name=nameself.age=ageself.gender=genderdef learn(self):print("%s正在学习编程...." %(self.name))
# 父类: Student   子类: MathStudent,EnglishStudent
# 如果子类没有定义__init__方法,父类有,
# 那么在子类继承父类的时候这个方法就被继承了,所以只要创建对象,就默认执行了那个继承过来的__init__方法。
class MathStudent(Student):pass
class EnglishStudent(Student):passs1=Student("小明",10,'male')
print(s1.name,s1.age,s1.gender)s2=MathStudent("罗尔",100,'male')
s2.learn()               #子类没有定义__init__方法,所以会直接继承父类的__init__方法
s1.learn()#打印结果:
小明 10 male
罗尔正在学习编程....
小明正在学习编程....

3)重写父类方法
就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法。

class Student(object):                                   #父类def __init__(self,name,age,gender):self.name=nameself.age=ageself.gender=genderdef learn(self):print("%s正在学习编程...." %(self.name))class MathStudent(Student):                              #子类def learn(self):super(MathStudent,self).learn()print("%s正在学习英语四级......"%(self.name))s1=Student("小明",10,'male')
print(s1.name,s1.age,s1.gender)s2=MathStudent("罗尔",100,'male')
s2.learn()                    #既打印了父类的learn方法,也打印了子类的learn方法
s1.learn()
#打印结果:
小明 10 male
罗尔正在学习编程....
罗尔正在学习英语四级......
小明正在学习编程....

多继承

子类有多个父类,并且具有它们的特征,#继承的顺序可以通过print(Student.mro)即(print(子类名.mro)进行查看:

class TeacherMajor(object):                   #父类1def __init__(self, students_count):self.student_count = students_countclass DoctorMajor(object):                    #父类2def __init__(self, patients_count):self.patients_count = patients_count# 子类Student拥有2个父类TeacherMajor和DoctorMajor
class Student(TeacherMajor, DoctorMajor):                               #子类def __init__(self, name, students_count, patients_count):self.name = nameTeacherMajor.__init__(self, students_count)DoctorMajor.__init__(self, patients_count)# # 继承的顺序如何查看?
print(Student.__mro__)
stu1 = Student("粉条", 90, 95)
print(stu1.patients_count)
print(stu1.student_count)#打印结果:
(<class '__main__.Student'>, <class '__main__.TeacherMajor'>, <class '__main__.DoctorMajor'>, <class 'object'>)
95
90

新式类与经典类

1)新式类定义:
class 类名(object):
pass
2)经典类定义:
class 类名:
pass
“新式类”和“经典类”的区分在Python 3之后就已经不存在,在Python3.x之后的版本,因为所有的类都派生自内置类型object(即使没有显示继承object类型),即所有的类都是“新式类”。
区别:
最明显的区别在于继承搜索的顺序不同,即:经典类多继承搜索顺序**(深度优先算法**):先深入继承树左侧查找,然后再返回,开始查找右侧。新式类多继承搜索顺序(广度优先算法):先在水平方向查找,然后再向上查找。

私有属性与私有方法

默认情况下,属性在 Python 中都是“public”, 大多数 OO 语言提供“访问控制符”来限定成员函数的访问。
在 Python中,实例的变量名如果以 __ 开头,就变成了一个私有变量/属性(private),
实例的函数名如果以 __开头,就变成了一个私有函数/方法(private)
被“访问控制符”限定的属性或者方法只有内部可以访问,外部不能访问。

私有属性和私有方法:

class Student(object):def __init__(self, name, age, score):self.name = nameself.age = age# self.__score是私有属性, 只能在类的内部访问, 类的外部不可以访问。self.__score = score# __get_level是私有方法,只能在类的内部访问, 类的外部不可以访问。def __get_level(self):if 90 <= self.__score <= 100:return "优秀"elif 80 <= self.__score < 90:return "良好"elif 60 <= self.__score < 80:return "及格"else:return "不及格"stu1 = Student("粉条", 10, 59)
print(stu1.__score)
print("学生分数的等级: ", stu1.__get_level())#打印结果:
AttributeError: 'Student' object has no attribute '__get_level'

可见,给属性和方法加__变成私有属性和私有方法之后,从外部反复问会失败,那么,我们如果还是想访问该怎么解决呢?
很简单:给修改过的属性或者方法前面加上_类名,就又可以访问到了。
即:python2版本不能直接访问 __属性名 是因为 Python 解释器对外把 __属性名 重名名了 _类名__属性名 ,
所以,仍然可以通过 _类名__属性名 来访问 __属性名 。 因为不同版本的 Python 解释器可能会把 __属性名 改成不同的变量名。
私有属性与私有方法优势:
确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护, 代码更加健壮。
如果又要允许外部代码修改属性怎么办?可以给类增加专门设置属性方法。
为什么大费周折?因为在方法中,可以对参数做检查,避免传入无效的参数。

多态

多态(Polymorphism)按字面的意思就是“多种状态”。
在面向对象语言中,接口的多种不同的实现方式即为多态。通俗来说: 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。

多态特点

多态的好处就是:
当我们需要传入更多的子类,只需要继承父类就可以了,而方法既可以直接不重写(即使用父类的),也可以重写一个特有的。
调用方只管调用,不管细节,而当我们新增一种的子类时,只要确保新方法编写正确,而不用管原来的代码。这就是著名的“开闭”原则:
对扩展开放(Open for extension):允许子类重写方法函数。
对修改封闭(Closed for modification):不重写,直接继承父类方法函数。

面向对象编程三种特性相关推荐

  1. Go面向对象编程的三大特性

    Go面向对象编程的三大特性 1.基本介绍 Golang仍然有面向对象编程的继承,封装和多态的特性,只是实现的方式和其它OOP语言不一样. 2.面向对象编程思想-抽象 抽象: 在定义一个结构体类型时,实 ...

  2. 面向对象编程的三大特性

    面向对象编程的三大特性 封装 该露的露,该藏的藏 我们程序设计要追求"高内聚,低耦合".高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用. ...

  3. 【Java】《Java面向对象编程的三大特性》阅读笔记

    前言 偶然读到这篇文章(<Java面向对象编程的三大特性>),想来这也算论文?这种还不满网络都是?读罢觉得写得还真不错,这里以我愚见,简单点评一二,不足之处还望指教. 阅读笔记 笔记1 文 ...

  4. JS面向对象的三种写法

    欢迎来我的博客交流 /*面向对象的三种写法 *1.构造函数 *2.class类 * 2.直接操作对象 * */ /**/function myShow(name){this.name = name;t ...

  5. c语言编程非线性方程求解,c语言计算机编程三种方法求解非线性方程

    c语言计算机编程三种方法求解非线性方程 本 科 专 业 学 年 论 文题 目:非线性方程求解比较姓 名: 何 娟 专 业: 计算机科学技术系 班 级: 08 级本科(2)班 指 导 老 师: 刘 晓 ...

  6. c语言编程非线性方程求解,c语言计算机编程三种方法求解非线性方程.doc

    c语言计算机编程三种方法求解非线性方程.doc 本 科 专 业 学 年 论 文题 目非线性方程求解比较姓 名 何 娟 专 业 计算机科学技术系 班 级 08 级本科(2)班 指 导 老 师 刘 晓 娜 ...

  7. Python每日一练(3)-编程三种境界

    目录 1. 三招隔行输出编程三种之境界 2. 只用一行代码输出编程三种之境界 3. 动态滚动多行输出编程三种之境界 4. 动态滚动一行输出编程三种之境界 5. 滚动字幕输出编程三种之境界 6. 多行滚 ...

  8. 面向对象编程(三) --- 抽象类和接口

    抽象类和接口 1抽象类 1.1抽象类的使用 2.接口 2.1接口的使用规则 2.2实现多个接口 2.3接口使用实例 2.4接口间的继承 2.5 Clonable 接口和深拷贝 1抽象类 1.1抽象类的 ...

  9. python面向对象编程的三大特性_Python面向对象总结及类与正则表达式详解

    Python3 面向对象 -------------------------------------------------------------------------------- 一丶面向对象 ...

最新文章

  1. RVDS2.2安装及破解步骤
  2. react --- 搭建环境
  3. java 反正多次重复提交_java web开发时防止刷新后的重复提交
  4. c语言中赋予从2开始的偶数,2013年计算机二级C语言上机试题三十二及答案
  5. HttpRequest 类
  6. aws sqs_JMS和AWS SQS的更多高级内容
  7. 改丝印的假华强北三代1562A,用芯良苦!
  8. camera中文版软件 ip_ip camera网络摄像机
  9. GCD - Extreme(欧拉函数变形)
  10. 程序员版的《后来的我们》,结局竟是……
  11. Flutter之ParentDataWidget和RenderObjectWidget详解
  12. 【3dmax千千问】食住玩初学3dmax插件神器第24课:3dmax自学渲染效果图教程|疯狂模渲大师、室内设计师、效果图绘图员都应该如何认识VRAY或扫描线CORONA渲染器及其VR核心算法的作用?
  13. 《面试》游戏开发常用面试问题以及答案
  14. mac pro M1(ARM)安装:VMWare Fusion及linux(centos7/ubuntu)(一)
  15. 必备知识:工业相机相关知识(初学者必备)
  16. QQ VS 360 大战开始
  17. JAVA并发十二连招,你能接住吗?
  18. 后端开发发展学习路线
  19. python驾到~障碍通通闪开,美女批量入内存~
  20. (四)MySQL员工部门查询

热门文章

  1. notify()会立刻释放锁么?
  2. MetaMask钱包登录Ganache-cli内的账户,出现无法获取链 IC,您的 RPC URL 地址是正确的么?问题
  3. 快速在数据库添加一年的日期,区分休息日和工作日
  4. 交通信号灯课程设计(红绿灯)
  5. 加密解密--换行符作祟
  6. pandas_数据处理分析基本
  7. linux su -c 命令
  8. 基于51单片机的出租车计价器的设计
  9. 计算机二级c语言模拟上机,计算机二级C语言上机模拟题
  10. PHP 可以利用的危险的函数