Task 07–面向对象的编程

Python 是一门“面向对象的编程语言”(Object Oriented Programming)。这是指 Python 中有一个叫做 类(class)的结构,能够让你用一种特定的方式结构化你的软件。通过使用类,你可以让你的程序保持连贯性,使用起来更清晰。至少理论上是这样。

一、类(class)

1.1 类(class)的概念及实例

在学习前我对‘类’的概念还十分模糊,认为类是一个模板,它描述一类对象的行为和状态,大概与“物以类聚”相似。下面进行实例练习:

class Song(object):def __init__(self, lyrics):self.lyrics = lyricsdef sing_me_a_song(self):for line in self.lyrics:print(line)happy_bday = Song(["Happy birthday to you","I don't want to get sued","So I'll stop right there"])bulls_on_parade = Song(["They rally around tha family","With pockets full of shells"])
happy_bday.sing_me_a_song()
bulls_on_parade.sing_me_a_song()
Happy birthday to you
I don't want to get sued
So I'll stop right there
They rally around tha family
With pockets full of shells

同样,根据前面的学习,遇到不懂的代码,通过进行逐句写标注的方式进行理解

class Song(object):#通过class定义类Song,类Song是从类object上继承下来的def __init__(self, lyrics):#通过定义__init__()函数,把lyrics属性绑定到即将创建的实例上去self.lyrics = lyrics#理解起来有些困难def sing_me_a_song(self):#定义函数sing_me_a_song,参数为self,也就是上面创建的实例for line in self.lyrics:#这里使用for...in循环将列表内的每一个元素代入变量lineprint(line)#并打印字符串happy_bday = Song(["Happy birthday to you","I don't want to get sued","So I'll stop right there"])bulls_on_parade = Song(["They rally around tha family","With pockets full of shells"])#根据类Song,通过类名+()创建出Song的实例。对象happy_bday和对象bulls_on_parade分别指向Song的两个实例
happy_bday.sing_me_a_song()
bulls_on_parade.sing_me_a_song()#调用函数sing_me_a_song,对象分别为happy_bday和bulls_on_parade

通过上面的标注以及查找相关资料对‘类’的理解加深了一些。比如:
class后面紧接着是类名,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来的。通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类。
但是代码中的init()方法、使用类的方法还是不太理解。

1.2 附加练习

1、用这个方法再写一些歌,确保你明白你正在用字符列表来传歌词。

class Song(object):def __init__(self,lyrics):self.lyrics = lyricsdef sing_me_a_song(self):for line in self.lyrics:print(line)
Vanilla = Song(["First time I met you in America","You showed me the way to your lonely mars","Where I tumbled down","Where I fall apart","Would you let me call your name","Vanilla"])Vanilla.sing_me_a_song()
First time I met you in America
You showed me the way to your lonely mars
Where I tumbled down
Where I fall apart
Would you let me call your name
Vanilla

2、把歌词放在一个单独的变量里,然后把这个变量放在类里面来使用。

class Song(object):def __init__(self,lyrics):self.lyrics = lyricsdef sing_me_a_song(self):for line in self.lyrics:print(line)lyrics_1 = ["First time I met you in America","You showed me the way to your lonely mars","Where I tumbled down","Where I fall apart","Would you let me call your name","Vanilla"]Vanilla = Song(lyrics_1)Vanilla.sing_me_a_song()
First time I met you in America
You showed me the way to your lonely mars
Where I tumbled down
Where I fall apart
Would you let me call your name
Vanilla

这一题的意思我认为是,用单独变量存储歌词,然后把这个变量作为参数传递给类。
3、在网上搜搜“面向对象的编程”,然后填满你的大脑。别担心你看不懂,因为几乎一半的东西我也看不懂。

1.3 面向对象的编程

概述
面向过程:根据业务逻辑从上到下写垒代码
函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
面向对象:对函数进行分类和封装,让开发“更快更好更强…”
面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处。
创建类和对象
面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。
类就是一个模板,模板里可以包含多个函数,函数里实现一些功能。
对象则是根据模板创建的实例,通过实例对象可以执行类中的函数。

  • class是关键字,表示类
  • 创建对象,类名称后加括号即可
    注:类中的函数第一个参数必须是self(详细见:类的三大特性之封装)
    类中定义的函数叫做 “方法”。

面向对象三大特性
面向对象的三大特性是指:封装、继承和多态。

一、封装

封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。

所以,在使用面向对象的封装特性时,需要:

  • 将内容封装到某处

  • 从某处调用被封装的内容

第一步:将内容封装到某处

self 是一个形式参数(形式参数在前面的练习有写到)

  • 当执行 obj1 = Foo(‘wupeiqi’, 18 ) 时,self 等于 obj1

  • 当执行 obj2 = Foo(‘alex’, 78 ) 时,self 等于 obj2

所以,内容其实被封装到了对象 obj1 和 obj2 中,每个对象中都封装了 name 和 age ,之前说的“内容封装到某处”其在内容里类似于下图来保存。

第二步:从某处调用被封装的内容

调用被封装的内容时,有两种情况:

  • 通过对象直接调用

  • 通过self间接调用

1、通过对象直接调用被封装的内容

上图展示了对象 obj1 和 obj2 在内存中保存的方式,根据保存格式可以如此调用被封装的内容:对象.属性名

class Foo:def __init__(self, name, age):self.name = nameself.age = ageobj1 = Foo('wupeiqi', 18)
print obj1.name    # 直接调用obj1对象的name属性
print obj1.age     # 直接调用obj1对象的age属性obj2 = Foo('alex', 73)
print obj2.name    # 直接调用obj2对象的name属性
print obj2.age     # 直接调用obj2对象的age属性

2、通过self间接调用被封装的内容

执行类中的方法时,需要通过self间接调用被封装的内容

class Foo:def __init__(self, name, age):self.name = nameself.age = agedef detail(self):print self.nameprint self.ageobj1 = Foo('wupeiqi', 18)
obj1.detail()  # Python默认会将obj1传给self参数,即:obj1.detail(obj1),所以,此时方法内部的 self = obj1,即:self.name 是 wupeiqi ;self.age 是 18obj2 = Foo('alex', 73)
obj2.detail()  # Python默认会将obj2传给self参数,即:obj1.detail(obj2),所以,此时方法内部的 self = obj2,即:self.name 是 alex ; self.age 是 78

综上所述,对于面向对象的封装来说,其实就是使用构造方法将内容封装到对象中,然后通过对象直接或者self间接获取被封装的内容。
二、继承

继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。如下图所示:

多继承问题详见参考链接。
三、多态

Pyhon不支持多态并且也用不到多态,多态的概念是应用于Java和C++这一类强类型语言中
参考链接:https://www.cnblogs.com/zunchang/p/7965685.html

那么什么样的代码才是面向对象?

  • 简单来说,如果程序中的所有功能都是用 类 和 对象 来实现,那么就是面向对象编程了。

二、学着去说面向对象

在这个练习中,我要教你如何去说“面向对象”。我所做的就是给你一些你需要了解的词和定义。然后我会给出一些需要填空的句子让你去理解。最后,你要完成一个大练习,从而在大脑中巩固这些句子。

2.1 词汇训练

类(class) :告诉 Python 创建一个新类型的东西(Tell Python to make a new type of thing)。

对象(object)两种含义:最基本类型的东西, 任何实例。(the most basic type of thing, and any instance of something.)

实例(instance) :当你告诉 Python 创建一个类的时候你所得到的东西。(What you get when you tell Python to create a class.)

def :你如何在类里面定义一个函数。(How you define a function inside a class.)

self :在一个类的函数里面,self 是被访问的实例/对象的一个变量。(Inside the functions in a class, self is a variable for the instance/object
being accessed.)

继承(inheritance) :关于一个类能从另一个类那里继承它的特征的概念,很像你和你的父母。(The concept that one class can inherit traits from another class, much like you and your parents.)

组合(composition) :关于一个类可以由其他一些类构成的概念, 很像一辆车包含几个轮子。(The concept that a class can be composed of other classes as parts, much like how a car has wheels.)

属性(attribute) :类所拥有的从组合那里得到的特性,通常是变量。(A property classes have that are from composition and are usually variables.)

is-a :一种用来表达某物继承自一种东西的表述, 就像“三文鱼是一种鱼”。(A phrase to say that something inherits from another, as in a “salmon” is a “fish.”)

has-a :一种用来表达某物是由一些东西组成或具有某种特性的表述,就像“三文鱼有一个嘴巴”。(A phrase to say that something is composed of other things or has a trait, as in “a salmon has-a mouth.”)

花点时间为这些术语做一些闪词卡(flash cards)并记住它们,虽然在你完成这个练习之前单纯的记忆没有任何意义,但你必须要先了解这些基础的词汇。

2.2 短语训练

接下来是一些 Python 代码片段以及右边的解释。

class X(Y) :创建一个名为 X 并继承自 Y 的类。(“Make a class named X that is-a Y.”)
class X(object): def init(self, J) 类 X 有一个带有 self 和 J 参数的 init 函数。(“class X has-a init that takes self and J parameters.”)
class X(object): def M(self, J):类 X 有一个带有 self 和 J 参数的 M 函数。(“class X has-a function named M that takes self and J parameters.”)
foo = X():设 foo 为类 X 的一个实例。(“Set foo to an instance of class X.”)
foo.M(J) 从 foo 那里获取 M 函数,并用 self 和 J 参数来调用它。(“From foo, get the M function, and call it with parameters self, J.”)
foo.K = Q 从 foo 那里获取 K 属性,并设它为 Q。(“From foo, get the K attribute, and set it to Q.”)
在上述每一句中,当你看到 X, Y, M, J, K, Q, 以及 foo, 你可以把它们当做空格,比如,我还可以把这些句子写成:
1.“Make a class named ??? that is-a Y.”
(创建一个名为 ??? 的类,它继承自 Y。)
2.“class ??? has-a init that takes self and ??? parameters.”
(类 ??? 有一个带了 self 和 ??? 参数的 init。)
3.“class ??? has-a function named ??? that takes self and ??? parameters.”
(类 ??? 有一个名为 ??? 的函数,这个函数带有 self 和 ??? 两个参数。)
4.“Set foo to an instance of class ???.”
(设 foo 为类 ??? 的一个实例。)
5.“From foo, get the ??? function, and call it with self=??? and parameters ???.”
(从 foo 那里获取 ??? 函数,并用 self=??? 以及参数 ??? 来调用它。)
6.“From foo, get the ??? attribute, and set it to ???.”
(从 foo 那里获取 ??? 属性,把它设为 ???。)

2.3 读更多代码(以后的任务)

你现在需要继续读更多的代码,并在这些代码中复习你之前学过的短语。试着找到尽可能多的包含类的文件,然后跟着如下要求去做:

1、给出每个类的名字,以及其他的类从它那里继承了什么。

2、在每个类下面,列出它所拥有的函数以及它们的参数。

3、列出所有它用 self 使用的属性。

4、对于每个属性,给出它继承自哪个类。

这些练习的目的是过一遍真实的代码,并试着把你学过的短语和它们的用法匹配和关联起来。如果你做足了训练,你会开始看到这些匹配模式(match patterns)呼之欲出,而不再是一些你不明白的空格或字符。

三、总结

3.1相关知识

概念

  • 类(class)的概念:
    class后面紧接着是类名,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来的。通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类。
  • 实例(instance)的概念:
    定义好了类,就可以根据类创建出该类的实例,创建实例是通过类名+()实现的。
  • init()函数的概念:
    在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的__init__方法,在创建实例的时候,就把你认为必须绑定的属性绑上去。

注意

  • 类相当于盖楼房的图纸一样,虽然定义了有哪些成员,但并没有实际的空间
  • 类可以实例化出多个对象,实例化出的对象占有实际空间(用来存储成员变量)
  • 注意到__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。
  • 有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去。

3.2 总结

最后一个task了,其中的一些知识理解起来还是有些困难,比较抽象,比如第一个附加练习,需要在查阅资料的基础上再进行理解,建议遇到这种抽象化的知识点课程,可以多加几个实例~,教程给出的方法还是很实用的,需要后面自己上手编程时多加练习。感谢一起乘风破浪的船员们和航海士们,期待下一次的组队学习!

Task 07--面向对象的编程相关推荐

  1. 侯捷C++视频笔记——C++面向对象高级编程(上)

    C++面向对象高级编程(上) 01.C++编程简介 学习目标: 1.学习良好的编写C++类的形式,包括两种,分别是无指针成员类(如Complex)和有指针成员类(如String) 2.学习类之间的关系 ...

  2. 侯捷C++视频笔记——C++面向对象高级编程(下)

    C++面向对象高级编程(下) 01.简介 学习目标: 1.探讨上篇没有探讨过的问题 2.继续深入了解面向对象,包括虚指针,虚表,虚函数,以及多态 02.转换函数与explicit 1.转换函数 转换函 ...

  3. 笔记整理2----Java语言基础(二)06 断点调试与数据加密+07 面向对象-类与对象+08 java常用API-基础+09 java集合+10 IO流-基础

    06 断点调试与数据加密+07 面向对象-类与对象+08 java常用API-基础+09 java集合+10 IO流-基础 第06天 java基础语法 今日内容介绍  Eclipse断点调试  基 ...

  4. 《C++面向对象高效编程(第2版)》——3.11 类名、成员函数名、参数类型和文档...

    本节书摘来自异步社区出版社<C++面向对象高效编程(第2版)>一书中的第3章,第3.11节,作者: [美]Kayshav Dattatri,更多章节内容可以访问云栖社区"异步社区 ...

  5. python笔记2(函数 面向对象 文件编程 上下文管理器)

    记录python听课笔记 文章目录 记录python听课笔记 一,函数 1.介绍python里的函数 2.用户自定义函数 3.变量的作用域 4.参数的传递 5.参数的默认值 6.向函数内部批量传递数据 ...

  6. 《C++面向对象高效编程(第2版)》——2.29 泛化关系(is-a)

    本节书摘来自异步社区出版社<C++面向对象高效编程(第2版)>一书中的第2章,第2.29节,作者: [美]Kayshav Dattatri,更多章节内容可以访问云栖社区"异步社区 ...

  7. 《C++面向对象高效编程(第2版)》——2.20 什么是多线程安全类

    本节书摘来自异步社区出版社<C++面向对象高效编程(第2版)>一书中的第章,第2.20节,作者: [美]Kayshav Dattatri,更多章节内容可以访问云栖社区"异步社区& ...

  8. 《C++面向对象高效编程(第2版)》——2.30 has-a关系的重要性

    本节书摘来自异步社区出版社<C++面向对象高效编程(第2版)>一书中的第2章,第2.30节,作者: [美]Kayshav Dattatri,更多章节内容可以访问云栖社区"异步社区 ...

  9. 《C++面向对象高效编程(第2版)》——导读

    前言 C++面向对象高效编程(第2版) 面向对象软件开发已逐渐成为开发软件的首选.优秀的面向对象软件开发人员.设计人员.系统架构师对其需求与日俱增.要想成为一名成功的面向对象编程(OOP)人员必须忘却 ...

  10. 《C++面向对象高效编程(第2版)》——3.13 采用语义

    本节书摘来自异步社区出版社<C++面向对象高效编程(第2版)>一书中的第3章,第3.13节,作者: [美]Kayshav Dattatri,更多章节内容可以访问云栖社区"异步社区 ...

最新文章

  1. R构建多项式回归模型(Polynomial Regression)
  2. xlrd,xlwt模塊
  3. 关于汉诺塔,C++代码,代码效果演算
  4. 647. Palindromic Substrings 回文子串
  5. java pdf 书签_Java 展开或折叠PDF中的书签
  6. Exchange2010恢复已禁用邮箱后用户登录会出错
  7. HTML+CSS+JS实现love520爱心表白
  8. LeetCode_database刷题记录(620. 有趣的电影)
  9. Unity3D 拆包工具 AssetStudio 编译构建
  10. java学习(六)多线程 中
  11. bme280中文技术手册_华为认证数通高级路由交换技术高级工程师 V1.0发布通知
  12. 计算机三位科学家,华南理工大学这三位年轻科学家太优秀了!
  13. input输入框计算总和
  14. K8S你知道,K9S你可能也知道,那Lens呢?
  15. php电子书mobi,EPUB / PDF / MOBI 電子書下載
  16. “放管服”改革背景下公安车驾管业务办理情况调研
  17. 生命计算机在线,抖音死亡计算器寿命计算器在线测试入口 使用生命年龄计算器...
  18. 安卓原生系统_安卓原生系统为什么比MIUI和EMUI等国产系统更流畅
  19. 其他浏览器可以上网,只有谷歌浏览器不行解决方案
  20. 光纤信号服务器,485转光纤的两种方式

热门文章

  1. KMS11激活Window系列
  2. Docker整理篇(docker-compose与私服搭建)
  3. 数据系统架构-6.BI数据展示平台
  4. 连接mysql的url是什么意思_URL是什么意思?
  5. 运满满服务器繁忙显示500,运满满上线两年多 听听货车司机怎么说
  6. 中国土地市场网-js解密
  7. 机器学习第四课:SVM前置知识点(凸优化问题)
  8. 信捷DS5B伺服驱动器Modbus控制程序编写
  9. Opencv做鼠标绘图
  10. 【漫漫转码路】Day 38 C++ day09