1. python面向对象编程回顾
  • 基础概念:

    • 面向对象的编程简称OOP,它把对象作为程序的基本单元,一个对象包含了数据操作数据的函数
    • 面向对象的设计思想是抽象出Class,根据Class(类)创建Instance(实例对象),这也是面向对象的最重要的概念。是抽象出来的模板,而实例是根据模板创建出来的一个个具体的“对象”,每个对象都有相同的方法,但是各自的数据可能不同
    • python中所有的数据类型都可以看作是类,同时也可以自定义一个Class
    • 面向对象的抽象程度又比函数要高,因为一个Class既包含数据,又包含操作数据的方法。
    • 面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递
    • 数据封装继承多态是面向对象的三大特点
  • 类的定义:

//定义类的一般形式

class Student(object):
<statement 1>
...
<statement n >
//class声明这是一个类,类名一般都用大写字母开头,括号里面表示该类从哪里继承来的(父类),如果没有
合适的继承类,就使用object类,这是所有类最终都会继承的类。缩进语句块里面用来声明该类的各种数据和
functions
//实例代码
>>> class Student(object):
... Readline internal error
Traceback (most recent call last):
...
^
IndentationError: expected an indented block //报错?缩进用个Tab不行吗?
>>> class Student(object):
... pass //要一个空格缩进?
...
  • 创建类的实例
>>> Student()							//通过类名+()就创建出了一个类实例对象
<__main__.Student object at 0x0000024713B0AF60>
>>> instance = Student()
>>> instance //可以发现它是一个Student 类的 object
<__main__.Student object at 0x0000024713B0AE10>
>>> Student //但Student才并且仍是Student类
<class '__main__.Student'>
  • 属性
>>> instance.name = 'yo'		//此时我们就可以给实例变量自由的添加属性
>>> instance.name //但是添加的属性不会对类产生任何影响
'yo'
//但是我们可以在创建类的时候,提前定义好一些该类的每一个实例对象都该拥有的属性。
//通过定义一个特殊的__init__方法,在创建实例的时候,把name,age等属性绑上去:
>>> class Student(object):
... def __init__(self,name,age):
... self.name = name
... self.age = age //我python的缩进是不是弄错了。。
... //进入虚拟环境再用python缩进就正常了,代码好看多了。
>>> class Student(object):
... def __init__(self,name,age): //__init__方法的第一个参数永远是self,表示创建的实例本身
... self.name = name //下面的就表示类自身(Student)的一些属性
... self.age = age
... >>> instance = Student() //重新定义的类如果还不传参数就会报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() missing 2 required positional arguments: 'name' and 'age' >>> instance = Student(name='ocean',age=19) //实例化的时候self不需要传入
>>> instance = Student('ocean',19) //传入参数的方法和用函数一样,有多种方式
>>> instance.name
'ocean'
>>> instance.age
19
>>> instance.score = 99.9 //此时,除了必须的,同样可以添加“个性化属性"
>>> class Student(object):
... def __init__(self): // __init__() 特殊方法(构造方法),该方法在类实例化时会自动调用
... print(666)
...
>>> yo = Student()
666
>>> class Student(object):
... def __init__(self):
... print(self) //一直不知道这个self表示的是什么,不如看看。
...
>>> yo = Student()
<__main__.Student object at 0x000001E1E2C9F188>
>>> Student //可以看出,self表示的是类实例化后的yo,而不是Student类
<class '__main__.Student'>

OMG,我居然也可以 ,温柔。 --19.8.17

  • 数据封装
//在Student类的内部定义访问数据的函数,这样,就把“数据”给封装起来了。
//这些封装数据的函数是和Student类本身是关联起来的,我们称之为类的方法: >>> class Student(object):
... def __init__(self,name,age):
... self.name = name
... self.age = age
... def print(self,score): //封装数据的函数,self是必要的一个参数!
... print("name:%s age:%s"%(self.name,self.age))
... print("score = %s"%(score))
...
>>> instance = Student('ocean',19)
>>> instance.print(99.9)
name:ocean age:19
score = 99.9 //事实上,封装做的就是在类的内部定义函数,从而能够在类的内部对数据进行
处理,我们在外部只需要传入必要的参数,类在内部加工数据,传出我们想要的
结果,而不需要再外部设置函数如此以来使得类变得powerful
  • 继承
//在定义一个class的时候,我们可以从现有的某个已经存在了的类继承,被继承的类被称为父类或者基类(还
是很形象的),产生新的class被称为子类。(之前一直用的object被称为根类)
//上代码

>>> class Animal():
... def printf(self):
... print("This is a Animal")
...
>>> ins0 = Animal()
>>> ins0.printf()
This is a Animal >>> class Dog(Animal): //定义一个Dog类,继承自Animal类
... pass
...
>>> ins1 = Dog()
>>> ins1.printf() //调用继承自父类方法,看来只是原封不动的搬了过来
This is a Animal >>> class Cat(Animal): //定义一个 Cat 类,继承自Animal类
... def printf(self): //在子类中重写printf()方法
... print("This is a cat.")
...
>>> ins2 = Cat()
>>> ins2.printf() //调用继承自父类方法,可以发现子类重写的方法成功的将原方法覆盖掉
This is a cat.
  • 调用父类构造函数
//上代码
>>> class Student():
... def __init__(self,age):
... self.age = age
... print(age)
...
>>> yo = Student(19)
19 >>> class Colleage_stu(Student):
... def __init__(self,age,score):
... print(age)
... print(score)
...
>>> ocean = Colleage_stu(19,99) //成功的覆盖掉了构造方法(__init__)
19
99 >>> class Colleage_stu(Student):
... def __init__(self,age,score):
... Student.__init__(self,age) //继承Student类的self和age方法
... self.score = score //添加 自己的方法score
... print(score)
...
>>> ocean = Colleage_stu(19,99) //成功习得自己的方法score
19
99 >>> class Colleage_stu(Student):
... def __init__(self,age,score):
... print(score)
... Student.__init__(self,age)
... print(age)
...
>>> ocean = Colleage_stu(19,99) //基本上可以为所欲为
99
19
19 >>> class Colleage_stu(Student):
... def __init__(self,age,score):
... Student.__init__(self,age,score) //只要不缺心眼的继承一个父类没有的属性
... print(score)
...
>>> ocean = Colleage_stu(19,99)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __init__
TypeError: __init__() takes 2 positional arguments but 3 were given
  • 多继承
//所谓多继承,就是继承自多个父类白,啧啧啧~

>>> class Teacher():
... def __init__(self,class): //敲了好几遍才意识到这个class还不能用。讲究~
File "<stdin>", line 2
def __init__(self,class):
^
SyntaxError: invalid syntax
>>> class Teacher():
... def __init__(self,grade): //换了grade就ok了
... print(grade)
...
>>> class Student():
... def __init__(self,age):
... print(age)
...
>>> stu = Student(19)
19
>>> tec = Teacher(10) //验证了一下没毛病 >>> class School(Teacher,Student):
... def __init__(self,grade,age,name):
... print(name)
... Student.__init__(self,age)
... print(age*10)
... Teacher.__init__(self,grade)
... print(grade*10)
...
>>> Tsinghua = School(10,19,"ocean") //还是只要别继承父类没有的属性就可以为所欲为
ocean
19
190
10
100
  • 多态
//上代码
>>> type(Cat)
<class 'type'>
>>> type(ins2)
<class '__main__.Cat'> //ins2是Cat类型的数据
>>> type(ins0)
<class '__main__.Animal'> //ins0是Animal类型的数据 >>> isinstance(ins2,Cat) //ins2属于Cat类,of course
True
>>> isinstance(ins0,Animal) //ins0属于Animal类,of course
True
>>> isinstance(ins2,Animal) //ins2同样属于Animal类!它继承自父类。
True //这就是所谓的多态
  • 多态的好处
>>> def run_twice(animal):	//此函数接受一个Animal类型的变量
... animal.printf()
... animal.printf()
...
>>> run_twice(Animal()) //运行成功,但是为什么定义的时候接受的类名是小写?
This is a Animal
This is a Animal >>> def run_twice(Animal): //大写是可以的
... Animal.printf()
... Animal.printf()
...
>>> run_twice(Animal())
This is a Animal
This is a Animal >>> run_twice(Dog()) //我们定义的时候没有定义Dog类,但是他是继承自Animal的,具有多态
This is a Animal
This is a Animal
>>> run_twice(Cat())
This is a cat.
This is a cat.
//由于Animal类型有run()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的
run()方法,这就是多态的意思:
//对于一个变量,我们只需要知道它的父类,而不需要确切的知道子类的内部结果,就可以通过调用父类的方法
来调用子类的相对应的方法。
//这就是多态真正的威力:调用方只管调用,不管细节,而当我们新增一种Animal的子类时,只要确保run()方
法编写正确,不用管原来的代码是如何调用的。

Questions:

>>> class Animal():
... def printf(self):
... print("This is a animal.")
...
>>> class Dog(Animal):
... pass
...
>>> class Cat(Animal):
... def printf(self):
... print("This is a cat.")
...
>>> def run(Cat):
... Cat.printf()
...
>>> run(Cat())
This is a cat.
>>> run(Animal())
This is a animal.
>>> run(Dog()) //我都凌乱了,run函数定义的是Cat类,怎么会和Dog类还有父类产生关系?
This is a animal.
>>> ins0 = Animal()
>>> ins2 = Cat()
>>> isinstance(ins0,Cat)
False
  1. python super()函数回顾
  • super() 函数是用于调用父类(超类)的一个方法。(多继承问题
  1. 对实例类进行调用

最新文章

  1. python中如何避免中文是乱码
  2. 【Java EE 学习 23】【log4j的使用】【ant的使用】【内省】
  3. 一封给JVM懵懂者的情书【不看错过一生幸福】
  4. Python邮件脚本
  5. Armitage主屏幕说明与命令行启动
  6. 看雪 安卓 dex文件
  7. DelphiTXT文档编辑器
  8. 《python基础教程》笔记之 元组
  9. iOS 面试常见问题最全梳理
  10. javascript学习笔记(window .alert 是什么)
  11. 安装Oracle,新建组、用户的时候的一个错误
  12. 获取合并单元格中值的一个方法POI
  13. mysql主从复制原理探索
  14. c++ 如何把RGB图像转换成HSV图像?
  15. (一一三)使用系统自带框架操作SQLite3数据库
  16. Linux下Python模式下【Tab】自动补全
  17. web前端学习python之第一章_基础语法(一)
  18. socket服务器编程的一般思路
  19. WebHook之PHP实践@coding.net
  20. Php的常见错误及错误分析

热门文章

  1. Python入门之元组
  2. elasticsearch mapping简单介绍
  3. python多线程采集图片
  4. 还在用逆向工程?太Low了,试试通用Mapper吧!
  5. 三 HTML框架标签
  6. 【剑指Offer面试编程题】题目1385:重建二叉树--九度OJ
  7. 记录要做的事情,把sql字符串替换写成工具网页。
  8. Linux centosVMware MySQL主从介绍、准备工作、配置主、配置从、测试主从同步
  9. list中会直接绑定HashMap中的数据
  10. 本地模拟内存溢出并分析Dump文件