一 面向对象介绍

面向过程:
核心是:“过程”二字

过程的终极奥义就是将程序流程化
过程是“流水化”,用来分步骤解决问题的

面向对象:
核心是“对象”二字
对象的终极奥义就是将程序“整合”
对象是“容器”,用来盛放数据与功能的

类也是“容器”,该容器用来存放同类对象共有的数据与功能

python这门语言到底提供了什么语法来允许我们将数据与功能很好地整合到一起

程序=数据+功能

学生的容器=学生的数据+学生的功能
课程的容器=课程的数据+课程的功能
  1、编程范式/思想
面向过程
介绍:
核心是“过程”二字
过程就是“流水化"
过程终极奥义是将程序流程化 优点:
1、将程序流程化,进而程序的设计会变得简单化 缺点:
1、可扩展性差 面向对象
介绍:
核心是“对象”二字
对象就是“容器",用来盛放数据与功能
对象终极奥义是将程序进行高度整合 优点:
1、提升程序的解耦合程度,进而增强程序的可扩展性 缺点:
1、设计复杂 2、面向对象编程
一:现实生活中:
1)先找出现实生活中的对象
2)然后总结归纳出现实生活中的类 二:程序中:
1)先定义程序中的类
2)后调用类产生程序中的对象(调用类的过程又称之为实例化)

二 什么是面向对象的程序设计及为什么要有它

面向过程的程序设计:核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就好比精心设计好一条流水线,是一种机械式的思维方式。

优点是:复杂度的问题流程化,进而简单化(一个复杂的问题,分成一个个小的步骤去实现,实现小的步骤将会非常简单)

缺点是:一套流水线或者流程就是用来解决一个问题,生产汽水的流水线无法生产汽车,即便是能,也得是大改,改一个组件,牵一发而动全身。

应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。

面向对象的程序设计:核心是对象二字,(要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。面向对象的程序设计好比如来设计西游记,如来要解决的问题是把经书传给东土大唐,如来想了想解决这个问题需要四个人:唐僧,沙和尚,猪八戒,孙悟空,每个人都有各自的特征和技能(这就是对象的概念,特征和技能分别对应对象的数据属性和方法属性),然而这并不好玩,于是如来又安排了一群妖魔鬼怪,为了防止师徒四人在取经路上被搞死,又安排了一群神仙保驾护航,这些都是对象。然后取经开始,师徒四人与妖魔鬼怪神仙交互着直到最后取得真经。如来根本不会管师徒四人按照什么流程去取),对象是特征与技能的结合体,基于面向对象设计程序就好比在创造一个世界,你就是这个世界的上帝,存在的皆为对象,不存在的也可以创造出来,与面向过程机械式的思维方式形成鲜明对比,面向对象更加注重对现实世界的模拟,是一种“上帝式”的思维方式。

优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。

缺点:

1. 编程的复杂度远高于面向过程,不了解面向对象而立即上手基于它设计程序,极容易出现过度设计的问题。一些扩展性要求低的场景使用面向对象会徒增编程难度,比如管理linux系统的shell脚本就不适合用面向对象去设计,面向过程反而更加适合。

2. 无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法准确地预测最终结果。于是我们经常看到对战类游戏,新增一个游戏人物,在对战的过程中极容易出现阴霸的技能,一刀砍死3个人,这种情况是无法准确预知的,只有对象之间交互才能准确地知道最终的结果。

应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方

面向对象的程序设计并不是全部。对于一个软件质量来说,面向对象的程序设计只是用来解决扩展性。

三 实现面向对象编程

# 一、先定义类
# 类是对象相似数据与功能的集合体
# 所以类中最常见的是变量与函数的定义,但是类体其实是可以包含任意其他代码的
# 注意:类体代码是在类定义阶段就会立即执行,会产生类的名称空间
# 类的命名应该使用“驼峰体”
class Student:
# 1、变量的定义
school = '清华大学' # 数据 # 2、功能的定义
def tell_stu_info(stu_obj):
print('学生信息:名字:{} 年龄:{} 性别:{}'.format(
stu_obj['stu_name'],
stu_obj['stu_age'],
stu_obj['stu_gender'],
)) def set_info(stu_obj, x, y, z):
stu_obj['stu_name'] = x
stu_obj['stu_age'] = y
stu_obj['stu_gender'] = z # print('---->') # 类的定义阶段,就会立即执行 print(Student.__dict__)
print(Student.__dict__['school'])
# 属性访问的语法
# 1、访问数据属性
print(Student.school) # 等同于Student.__dict__['school']
# 2、访问函数属性
print(Student.set_info) # 等同于Student.__dict__['set_info'] # 二、再调用类产生对象
# 产生对象名称空间,并与类名称空间产生关联
Stu1_obj = Student()
Stu2_obj = Student()
Stu3_obj = Student() print(Stu1_obj.__dict__)
print(Stu2_obj.__dict__)
print(Stu2_obj.__dict__) # 对象定制自己独有的属性
# 问题1:代码重复
# 问题2:属性的查找顺序
Stu1_obj.stu_name = 'lq' # Stu1_obj.__dict__['stu_name']='lq'
Stu1_obj.stu_age = 18 # Stu1_obj.__dict__['stu_age']=18
Stu1_obj.stu_gender = 'female' # Stu1_obj.__dict__['stu_gender']='female'
print(Stu1_obj.__dict__) Stu2_obj.stu_name = 'zd'
Stu2_obj.stu_age = 19
Stu2_obj.stu_gender = 'male'
print(Stu2_obj.__dict__) Stu3_obj.stu_name = 'xiaobao'
Stu3_obj.stu_age = 5
Stu3_obj.stu_gender = 'female'
print(Stu3_obj.__dict__) # 解决问题:
# 解决方案一:
def init(obj, x, y, z):
obj.stu_name = x
obj.stu_age = y
obj.stu_gender = z init(Stu1_obj, 'lq', 18, 'male')
print(Stu1_obj.__dict__) # 解决方案二:
# 一:先定义类
class Student: # 类的命名应该使用“驼峰体”
# 1、变量的定义
school = '清华大学' # 数据 # 空对象,'egon',18,'male'
def __init__(obj, x, y, z):
obj.stu_name = x # 空对象.stu_name='egon'
obj.stu_age = y # 空对象.stu_age=18
obj.stu_gender = z # 空对象.stu_gender='male' # 2、功能的定义
def tell_stu_info(stu_obj):
print('学生信息:名字:{} 年龄:{} 性别:{}'.format(
stu_obj['stu_name'],
stu_obj['stu_age'],
stu_obj['stu_gender'],
)) def set_info(stu_obj, x, y, z):
stu_obj['stu_name'] = x
stu_obj['stu_age'] = y
stu_obj['stu_gender'] = z # 二:再调用类产生对象
# 调用类的过程又称之为实例化,发生了三件事
# 1、先产生一个空对象
# 2、python会自动调用类中的__init__方法,然后将空对象已经调用类是括号内传入的参数一同传给__init__方法
# 3、返回初始完的对象 Stu1_obj = Student('lq', 19, 'male')
Stu2_obj = Student('zd', 19, 'male')
Stu3_obj = Student('xiaobao', 18, 'male') print(Stu1_obj.__dict__)
print(Stu2_obj.__dict__)
print(Stu3_obj.__dict__) # 总结__init__方法
# 1、会在调用类时自动触发执行,用来为对象初始化自己独有的数据
# 2、__init__内应该存放是为对象初始化属性的功能,但是可以存放任意其他代码,想要在
# 类调用时就立刻执行的代码都可以放到该方法内
# 3、__init__方法必须返回None

四 属性查找

先查找对象名称空间中查找数据属性,找不到,再到类的名称空间里找

class Student:  # 类的命名应该使用“驼峰体”
# 1、变量的定义
school = '清华大学' # 数据
count = 0 def __init__(self, x, y, z):
Student.count += 1 # 实例化计数
self.stu_name = x # 空对象.stu_name='egon'
self.stu_age = y # 空对象.stu_age=18
self.stu_gender = z # 空对象.stu_gender='male' # 2、功能的定义
def tell_stu_info(obj):
print('学生信息:名字:{} 年龄:{} 性别:{}'.format(
obj.stu_name,
obj.stu_age,
obj.stu_gender,
)) def set_info(obj, x, y, z):
obj.stu_name = x
obj.stu_age = y
obj.stu_gender = z Stu1_obj = Student('lq', 19, 'male')
Stu2_obj = Student('zd', 19, 'male')
Stu3_obj = Student('xiaobao', 18, 'male') # 类中存放的是对象共有的数据与功能
# 一、类可以访问:
# 1、类的数据属性
print(Student.school)
# 2、类的函数属性
print(Student.set_info)
print(Student.tell_stu_info)
# 二、但其实类中的东西是给对象用的
# 1、类的数据属性是共享给所有对象用的,大家访问的地址都一样
print(Student.school)
print(Stu1_obj.school)
print(Stu2_obj.school)
print(Stu3_obj.school)
Stu1_obj.school = '上海中学' # 对象Stu1,自己名称空间里建school数据属性
print(Stu1_obj.school) # 2、类中定义的函数主要是给对象使用的,而且是绑定给对象的,虽然所有对象指向的都是相同的功能,
# 但是绑定到不同的对象就是不同的绑定方法,内存地址各不相同 # 类调用自己的函数属性必须严格按照函数的用法来
Student.tell_stu_info(Stu1_obj)
Student.tell_stu_info(Stu2_obj)
Student.tell_stu_info(Stu3_obj)
Student.set_info(Stu1_obj, 'LQ', 33, 'MALL')
Student.set_info(Stu2_obj, 'ZD', 33, 'MALL')
Student.set_info(Stu3_obj, 'XIAOBAO', 6, 'MALL')
'''
学生信息:名字:lq 年龄:19 性别:male
学生信息:名字:zd 年龄:19 性别:male
学生信息:名字:xiaobao 年龄:18 性别:male
学生信息:名字:LQ 年龄:33 性别:MALL
学生信息:名字:ZD 年龄:33 性别:MALL
学生信息:名字:XIAOBAO 年龄:6 性别:MALL
''' # 绑定方法的特殊之处在于:谁来调用绑定方法就会将谁当做第一个参数自动传入,
# 所以类中定义的函数第一个参数默认self,类中函数方法(无参函数,也需要有self的原因)
print(Student.tell_stu_info)
print(Stu1_obj.tell_stu_info) # 绑定方法,
print(Stu2_obj.tell_stu_info)
print(Stu3_obj.tell_stu_info)
'''
<function Student.tell_stu_info at 0x000001D76D422550>
<bound method Student.tell_stu_info of <__main__.Student object at 0x000001D76D3C30A0>>
<bound method Student.tell_stu_info of <__main__.Student object at 0x000001D76D3C3310>>
<bound method Student.tell_stu_info of <__main__.Student object at 0x000001D76D3C9550>>
''' # 直接对象来调用函数方法,对象直接当第一个参数自动传入,不用再像类调用函数方法时,传对象参数
# 比从类中调用,更简单,并且语意明确
Stu1_obj.tell_stu_info()
Stu2_obj.tell_stu_info()
Stu3_obj.tell_stu_info()
Stu1_obj.set_info('LQ', 33, 'MALL')
Stu2_obj.set_info('ZD', 33, 'MALL')
Stu3_obj.set_info('XIAOBAO', 6, 'MALL')
'''
学生信息:名字:lq 年龄:19 性别:male
学生信息:名字:zd 年龄:19 性别:male
学生信息:名字:xiaobao 年龄:18 性别:male
学生信息:名字:LQ 年龄:33 性别:MALL
学生信息:名字:ZD 年龄:33 性别:MALL
学生信息:名字:XIAOBAO 年龄:6 性别:MALL
''' # Python中一切皆为对象,且Python3中类与类型是一个概念
# 在上述介绍类与对象的使用过程中,我们更多的是站在底层原理的角度去介绍类与对象之间的关联关系,
# 如果只是站在使用的角度,我们无需考虑语法“对象.属性
# "中”属性“到底源自于哪里,只需要知道是通过对象获取到的就可以了,所以说,对象是一个高度整合的产物,
# 有了对象,我们只需要使用“对象.xxx”的语法就可以得到跟这个对象相关的所有数据与功能,十分方便且解耦合程度极高。

五 练习

对象可以当参数传递

# 整合---》解耦合---》扩展性增强

# 学校
class School:
school_name = 'OLDBOY' def __init__(self, nickname, addr):
self.nickname = nickname
self.addr = addr
self.classes = [] def related_class(self, grade_obj): # 传对象,在.'属性'
self.classes.append(grade_obj)  # 列表存储的班级对象
# self.classes.append(班级名称) def class_tell_info(self):
print(self.nickname)
for grade_obj in self.classes:
grade_obj.tell_course() # 1、学校
# 1)创建校区
school_obj1 = School('上海校区', '上海')
school_obj2 = School('北京校区', '北京') # 2)为学校开设班级
# school_obj1.related_class('脱产14期')
# school_obj1.related_class('脱产15期')
# school_obj2.related_class('脱产29期') # 3)查看每个校区开设的班级
# school_obj1.class_tell_info() # 班级
class Grade:
def __init__(self, name):
self.name = name
self.course = None def related_course(self, course_obj):
self.course = course_obj # 变量名有,就是修改,没有,就是新建 def tell_course(self):
print('班级名:{}'.format(self.name),end=' ')
self.course.tell_info() # 2、班级
# 1)创建班级
grade_obj1 = Grade('脱产14期')
grade_obj2 = Grade('脱产15期')
grade_obj3 = Grade('脱产29期') # 2)为班级关联一个课程
# grade_obj1.related_course('python全栈开发')
# grade_obj2.related_course('linux运维')
# grade_obj3.related_course('python全栈开发') # 3)查看班级开设的课程信息
# grade_obj1.tell_course()
# grade_obj2.tell_course()
# grade_obj3.tell_course() # 4) 为学校开设办班级
# 上海校区开了:脱产14期,上海校区开了脱产15期
school_obj1.related_class(grade_obj1)
school_obj1.related_class(grade_obj2) # print(school_obj1.classes) # 课程列表里,是对象 # 北京校区开了:脱产29期
school_obj2.related_class(grade_obj3) # school_obj1.class_tell_info() # 课程
class Course:
def __init__(self, name, period, price):
self.name = name
self.period = period
self.price = price def tell_info(self):
print('<课程名:{},课程周期:{},课程价格{}>'.format(self.name, self.period, self.price)) # 1)创建课程
course_obj1 = Course('python全栈开发', '6个月', 20000)
course_obj2 = Course('linux运维', '5个月', 18000) # 2) 查看课程的详细信息
# course_obj1.tell_info()
# course_obj2.tell_info() # 3) 为班级关联课程对象
grade_obj1.related_course(course_obj1)
grade_obj2.related_course(course_obj2)
grade_obj3.related_course(course_obj1) # grade_obj1.tell_course()
# grade_obj2.tell_course()
# grade_obj3.tell_course() school_obj1.class_tell_info()
school_obj2.class_tell_info() class Student:
pass

python面向对象(基础)的更多相关文章

  1. Python 面向对象 基础

    编程范式概述:面向过程 和 面向对象 以及函数式编程 面向过程:(Procedure Oriented)是一种以事件为中心的编程思想. 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现 ...

  2. python面向对象基础

    面向对象基础 1. 简述 编程方式: 面向过程: 根据代码在脚本的堆叠顺序,从上到下依次执行 函数式编程:将相同功能的代码封装到函数中,直接调用即可,减少代码重复性 面向对象:对函数进行分类和封装,将 ...

  3. Python 面向对象基础知识

    面向对象基础知识 1.什么是面向对象编程? - 以前使用函数 - 类 + 对象 2.什么是类什么是对象,又有什么关系? class 类: def 函数1(): pass def 函数2(): pass ...

  4. python 面向对象基础和高级复习

    面向对象基础 面向对象编程 面向过程编程:类似于工厂的流水线 优点:逻辑清晰 缺点:扩展性差 面向对象编程:核心是对象二字,对象属性和方法的集合体,面向对象编程就是一堆对象交互 优点:扩展性强 缺点: ...

  5. 十六、python面向对象基础篇

    面向对象基础: 在了解面向对象之前,先了解下变成范式: 编程范式是一类典型的编程风格,是一种方法学 编程范式决定了程序员对程序执行的看法 oop中,程序是一系列对象的相互作用 python支持多种编程 ...

  6. 1.Python面向对象基础

    面向对象(OOP) 面向对象编程--object oriented programming 简写 OOP   面向过程和面向对象的区别: 面向过程: 1.把完成某一个需求的所有步骤从头到尾逐步实现 2 ...

  7. [python面向对象]--基础篇

    1.#类 #类就是一个模板,模板里可以包含多个函数,函数里实现一些功能 #定义一个类 class bar: def foo(self,agr): print(self,agr) obj = bar() ...

  8. Python面向对象基础:编码细节和注意事项

    在前面,我用了3篇文章解释python的面向对象: 面向对象:从代码复用开始 面向对象:设置对象属性 类和对象的名称空间 本篇是第4篇,用一个完整的示例来解释面向对象的一些细节. 例子的模型是父类Em ...

  9. Python面向对象基础一

    公司可能过一两个月就要从深圳搬到东莞松山湖,项目组的现在有的在转Java或其他语言的,问我们要不要转java+hoodap+spark方向,我还是先不转,毕竟之前是从ios转回C#,这现在在转其他的那 ...

  10. python面向对象基础-01

    面向对象(OOP)基本概念 前言 话说三国时期曹军于官渡大败袁绍,酒席之间,曹操诗兴大发,吟道:喝酒唱歌,人生真爽! 众将直呼:"丞相好诗",于是命印刷工匠刻板印刷以流传天下; 待 ...

随机推荐

  1. 通过解析库探究函数式抽象代价 ( ini 解析示例补充)

    上一篇 用 HexColor 作为示例,可能过于简单 这里再补充一个 ini 解析的示例 由于实在写不动用其他库解析 ini 了, 春节都要过完了,累了,写不动了, 所以随意找了一份解析ini的库, ...

  2. JS Leetcode 374. 猜数字大小 题解分析

    壹 ❀ 引 本题来自LeetCode 374. 猜数字大小,题目难度简单,与昨天的题目一样,也是一道标准二分法的题目,不知道是不是端午节的缘故,这两天的题目都比较简单,题目描述如下: 猜数字游戏的规则 ...

  3. NEMU PA 4 实验报告

    一.实验目的 在前面的PA123中,我们分别实现了基本的运算单元,实现了各种指令和程序的装载,实现了存储器的层次结构.而在PA4中,为了让NEMU可以处理异常情况以及和外设交互,我们要做的事情有以下: ...

  4. Android架构组件LiveData

    LiveData LiveData是基于观察者模式创建的,其中,LiveData是被观察者,观察者通过注册方法,监听被观察者的数据变化.LiveData在数据发生变化的时候,会通知观察者. LiveD ...

  5. STC8H8K64U 的 USB 功能测试(续)

    对 STC8H8K64U 的USB测试昨天没搞定, 判断可能是供电的问题, 直接用5V不行, 从USB2TTL上采电3.3V时存在一个问题, 就是 D-/D+ 在上电前就已经连接了, 不符合 USB ...

  6. 我的小程序之旅九:微信开放平台unionId机制介绍

    一.机制说明 参考文档:https://developers.weixin.qq.com/minigame/dev/guide/open-ability/union-id.html 如果开发者拥有多个 ...

  7. 【MongoDB】C# .Net MongoDB常用语法

    1.1.驱动安装 使用NuGet包管理器安装MongoDB C#驱动:MongoDB.Driver 1.2. C#连接MongoDB //获取MongoDB连接客户端 MongoClient clie ...

  8. 《HelloGitHub》第 95 期

    兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣.入门级的开源项目. https://github.com/521xueweiha ...

  9. 用Docker发布网站时,自动下载Directory.Build.props及其Import的文件

    为Blazor网站项目,"添加Docker支持" 这时,网站项目根目录下会新增Dockerfile. 里面文字内容如下 #See https://aka.ms/customizec ...

  10. 【Azure Key Vault】.NET 代码如何访问中国区的Key Vault中的机密信息(Get/Set Secret)

    问题描述 使用 .NET Azure.Identity 中的 DefaultAzureCredential 认证并连接到Azure Key Vault中, 在Key Vault 的示例中,并没有介绍如 ...