Python3 面向对象(基础篇)
面向对象
面向过程:你想干嘛,就直接写个功能,然后做你想做的事情。
假如你想写个程序去洗衣店洗衣服,面向对象就是设定一个人,把这个对象赋予拿衣服,搭车,交易,取衣服,回家这所有的过程的功能。当你想洗衣服的时候,创造这个对象的实例出来,然后命令他去做就好了。
面向过程:你就得写拿衣服,搭车,交易,取衣服,回家这所有的过程。实现这一个功能感觉和面向对象编程的思想差不多,但是如果你下一次还想洗衣服,就得再写一遍这个过程,假如会有很多次洗衣服,那就得写更多次,很麻烦,易出错。
定义类,实例化对象
- class myclass: # 用关键字class进行类的定义 即 “class 类名:”
- def __init__(self):
- # 类中定义的函数叫做 “方法” __init__ 方法是构造方法 根据类创建对象时自动执行
- # self为实例化的对象本身 即即将被实例化的对象obj
- print("this is my class")
- obj = myclass() # 实例化类 创建对象 会自动执行类中的 __init__ 运行结果:this is my class
- 当然, __init__() 方法可以有参数,参数通过 __init__() 传递到类的实例化操作上。例如:
- class myclass:
- def __init__(self, name1, age1):
- self.name = name1
- self.age = age1
- # 因为会自动执行类中的 __init__方法,且该方法中有参数,所以实例化对象时需要传递参数
- # self是一个形式参数, 当执行下句代码时,实例化对象obj1,那么self就等于obj1这个对象
- obj1 = myclass("IKTP", 22)
- # 当执行下句代码时,实例化对象obj2,那么self就等于obj2
- # 且这两个对象同都拥有两个属性:name,age
- obj2 = myclass("hahaha", 23)
- # 当需要调用对象的属性时,即name和age属性,可以直接用对象名字后打点调用需要的属性,例如:
- print(obj1.name) # 执行结果:IKTP
- print(obj1.age) # 执行结果:22
- print(obj2.name) # 执行结果:hahaha
- print(obj2.age) # 执行结果:23
方法
方法分为三种:实例方法,类方法,静态方法
- class myclass:
- public_var = "this is public_var"
- def __init__(self, name1, age1):
- self.name = name1
- self.age = age1
- # 在类里面定义的函数,统称为方法,方法参数自定义,可在方法中实现相关的操作
- # 创建实例方法时,参数必须包括self,即必须有实例化对象才能引用该方法,引用时不需要传递self实参
- def speak(self):
- print("this is def speak.%s 说:我今年%d岁。" % (self.name, self.age))
- # 我们要写一个只在类中运行而不在实例中运行的方法. 如果我们想让方法不在实例中运行
- # 比如我们需要类中的基础字段public_var,根本不需要实例化对象就可以拿到该字段
- # 这时就需要装饰器@classmethod来创建类方法,至于classmethod的使用场合,会在下篇文章介绍
- # 创建类方法时,参数必须包括cls,即必须用类来引用该方法,引用时不需要传递cls实参
- @classmethod
- def speak2(cls):
- print("this is classmethod")
- return cls.public_var
- # 经常有一些跟类有关系的功能但在运行时又不需要实例和类参与的情况下需要用到静态方法
- # 写在类里的方法,必须用类来调用(极少数情况下使用,一般都在全局里直接写函数了)
- @staticmethod
- def speak3(name2, age2):
- print("this is staticmethod.%s 说:我今年%d岁。" % (name2, age2))
- obj = myclass("IKTP", 22)
- # 无论是类方法、静态方法还是普通方法都可以被实例化的对象调用
- # 但是静态方法和类方法可以不用对象进行调用
- obj.speak() # 执行结果:this is def speak.IKTP 说:我今年22岁。
- var = obj.speak2() # 执行结果:this is classmethod
- print(var) # 执行结果: this is public_var
- obj.speak3("liu", 23) # 执行结果:this is staticmethod.liu 说:我今年23岁。
- myclass.speak() # 报错,实例方法不能直接被调用,必须需要实例化的对象调用
- var2 = myclass.speak2() # 不需要实例化对象即可拿到该字段
- print(var2) # 不需要实例化对象即可拿到该字段
- myclass.speak3("abc", 12) # 不需要实例化对象即可执行
继承
- 继承是面向对象的重要特征之一,继承是两个类或者多个类之间的父子关系,子类继承了父类的所有公有实例变量和方法。
继承实现了代码的重用。重用已经存在的数据和行为,减少代码的重新编写。
python在类名后用一对圆括号表示继承关系,括号中的类表示父类
- class father:
- father_var = "this is father_var"
- def father_def(self):
- print("this is father_def")
- class son(father): # 括号里有类名,代表该类是子类(派生类),继承自父类(基类)father
- pass
- obj = son()
- # son子类中没有father_var 则去父类father中寻找
- print(obj.father_var) # 执行结果:this is father_var
- # son子类中没有father_def方法 则去父类father中寻找
- obj.father_def() # 执行结果:this is father_def
- 如果父类中有构造方法且子类也有构造方法,则在子类中必须亲自调用且传递相对应的参数
- # 如果父类中有构造方法且子类也有构造方法,则在子类中必须亲自调用且传递相对应的参数
- # 否则无法找到在父类中定义的属性
- # ##############################错误方式##################################
- class father:
- def __init__(self, n):
- self.name = n
- class son(father):
- def __init__(self):
- print("aaaaa")
- obj = son()
- # 子类中没有name属性,且没有在子类中调用并传递相对应的参数给父类的构造方法,所以找不到name属性 报错
- print(obj.name)
- ########################################################################
- # #########################正确方式######################################
- class father:
- def __init__(self, n):
- self.name = n
- class son(father):
- def __init__(self):
- father.__init__(self, "")
- obj = son()
- print(obj.name) # 执行结果 6666
- ########################################################################
- 如果父类中没有构造方法 则不必调用
如果父类中有构造方法但子类中没有构造方法,则在实例化子类对象的时候需要传递父类中的构造参数
- class father:
- def __init__(self, n):
- print("bbbbbbbb")
- self.name = n
- class son(father):
- def speak(self):
- print("aaaaa")
- obj = son() # 报错 因为子类没有构造方法,所以会执行父类的构造方法,但是没有给父类的构造方法传递参数
- obj = son("IKTP")
- print(obj.name) # 执行结果: IKTP
在子类中调用父类的方法
- class father:
- def speak(self):
- print("this is father speak")
- class son(father):
- def speak2(self):
- # ######调用父类的speak方法的三种方式######
- father.speak(self) # 直接类名后打点调用方法,需要传递self
- super().speak() # super()代指父类
- super(son, self).speak()
- ########################################
- print("this is son speak2")
- obj = son()
- obj.speak2()
- # 运行结果:this is father speak
- # this is father speak
- # this is father speak
- # this is son speak2
覆盖(重写)父类方法
- class father:
- def speak(self):
- print("this is father speak")
- def speak2(self):
- print("this is father speak2")
- class son(father):
- def speak2(self):
- print("this is son speak2")
- obj = son()
- obj.speak2() # 运行结果:this is son speak2
- # 对象总会先在实例化该对象的类里寻找属性字段或者方法,
- # 如果有则执行,如果该类里没有,则再去父类里寻找
- # 由于父类本来拥有speak2方法,但是子类里又写了一个speak2方法
- # 所以obj不会去父类里寻找该方法,只会执行子类里的speak2方法,这样就称为覆盖或重写
多继承
一个类可同时继承多个类,与多个类具有继承关系,则这个类可调用所有父类中的方法和字段
- class father1():
- father1_var = "this is father1_var"
- def father1_def(self):
- print("this is father1_def")
- class father2():
- father2_var = "this is father2_var"
- def father2_def(self):
- print("this is father2_def")
- class son(father1, father2): # son类同时继承father1类和father2类
- def son_def(self):
- print("this is son_def")
- obj = son()
- print(obj.father1_var)
- print(obj.father2_var)
- obj.father1_def()
- obj.father2_def()
- # 执行结果:
- # this is father1_var
- # this is father2_var
- # this is father1_def
- # this is father2_def
那么问题来了,假如父类中有相同的字段或者方法名,那么会调用谁的呢?我们来试一试
myclass类同时继承son类和son2类,son类继承father类,father类和son2类又同时继承grandf类
并且每个类里面都有speak方法,我们实例化myclass对象调用speak方法去试试
- class grandfather:
- def speak(self):
- print("this is grandfather_def")
- class father(grandfather):
- def speak(self):
- print("this is father_def")
- class son(father):
- def speak(self):
- print("this is son_def")
- class son2(grandfather):
- def speak(self):
- print("this is son2_def")
- class myclass(son, son2):
- def speak(self):
- print("this is myclass_def")
- obj = myclass()
- obj.speak() # 执行结果:this is myclass_def
- #先执行myclass里的speak方法
将myclass里的方法speak方法注释掉再运行
- class grandfather:
- def speak(self):
- print("this is grandfather_def")
- class father(grandfather):
- def speak(self):
- print("this is father_def")
- class son(father):
- def speak(self):
- print("this is son_def")
- class son2(grandfather):
- def speak(self):
- print("this is son2_def")
- class myclass(son, son2):
- pass
- obj = myclass()
- obj.speak() # 执行结果:this is son_def
#执行的是son类里的方法
将myclass、son类里的方法speak方法注释掉再运行
- class grandfather:
- def speak(self):
- print("this is grandfather_def")
- class father(grandfather):
- def speak(self):
- print("this is father_def")
- class son(father):
- pass
- class son2(grandfather):
- def speak(self):
- print("this is son2_def")
- class myclass(son, son2):
- pass
- obj = myclass()
- obj.speak() # 执行结果:this is father_def
#执行的是father类的方法
将myclass、son、father类里的方法speak方法注释掉再运行
- class grandfather:
- def speak(self):
- print("this is grandfather_def")
- class father(grandfather):
- pass
- class son(father):
- pass
- class son2(grandfather):
- def speak(self):
- print("this is son2_def")
- class myclass(son, son2):
- pass
- obj = myclass()
- obj.speak() # 执行结果:this is son2_def
#执行的是son2类里的方法
将myclass、son、father、son2类里的方法speak方法注释掉再运行
- class grandfather:
- def speak(self):
- print("this is grandfather_def")
- class father(grandfather):
- pass
- class son(father):
- pass
- class son2(grandfather):
- pass
- class myclass(son, son2):
- pass
- obj = myclass()
- obj.speak() # 执行结果:this is grandfather_def
#执行的方法是grandfather类的方法
由上可知,myclass实例化的对象找speak方法的执行顺序是 myclass-->son-->father-->son2-->grandfather
所以得出结论:经典类的搜索方式是按照“从左至右,深度优先”的方式去查找属性,有共同父类的话最后查找父类,无共同父类则“从左到右”挨个将左边类的所有父类关系查找一遍,再向右查找
Python3 面向对象(基础篇)的更多相关文章
- 十六、python面向对象基础篇
面向对象基础: 在了解面向对象之前,先了解下变成范式: 编程范式是一类典型的编程风格,是一种方法学 编程范式决定了程序员对程序执行的看法 oop中,程序是一系列对象的相互作用 python支持多种编程 ...
- [python面向对象]--基础篇
1.#类 #类就是一个模板,模板里可以包含多个函数,函数里实现一些功能 #定义一个类 class bar: def foo(self,agr): print(self,agr) obj = bar() ...
- Python3面向对象基础
面向对象概述 面向对象 面向对象的世界,引入了对象的概念,对象具有属性:数据,对象具有过程或者方法:成员函数.成员函数的作用就是处理属性. 例子 对象:Car 属性:fuel_level, isSed ...
- java类与对象基础篇
java面向对象基础篇 面向对象程序设计(Object Oriented Proframming ,OOP) 面向对象的本质是:以类的方式组织代码,以对象的方式组织(封装)数据. 面向对象的核心思想是 ...
- 图解Python 【第五篇】:面向对象-类-初级基础篇
由于类的内容比较多,分为类-初级基础篇和类-进阶篇 类的内容总览图: 本节主要讲基础和面向对象的特性 本节内容一览图: 前言总结介绍: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 ...
- Python3学习(1)-基础篇
Python3学习(1)-基础篇 Python3学习(2)-中级篇 Python3学习(3)-高级篇 安装(MAC) 直接运行: brew install python3 输入:python3 --v ...
- 夯实Java基础系列1:Java面向对象三大特性(基础篇)
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 [https://github.com/h2pl/Java-Tutorial](https: ...
- Python(三)基础篇之「模块&面向对象编程」
[笔记]Python(三)基础篇之「模块&面向对象编程」 2016-12-07 ZOE 编程之魅 Python Notes: ★ 如果你是第一次阅读,推荐先浏览:[重要公告]文章更新. ...
- Python 经典面试题汇总之基础篇
基础篇 1:为什么学习Python 公司建议使用Python,然后自己通过百度和向有学过Python的同学了解了Python.Python这门语言,入门比较简单,它简单易学,生态圈比较强大,涉及的地方 ...
随机推荐
- datatables中的Options总结(1)
datatables中的Options总结(1) 最近一直研究dataTables插件,下面是总结的所有的选项内容,用了帮助学习datatables插件. 这些选项的配置在$().Datatable( ...
- 《Web开发中块级元素与行内元素的区分》
一.块级元素的特性: 占据一整行,总是重起一行并且后面的元素也必须另起一行显示. HTML中块级元素列举如下: address(联系方式信息) article(文章内容) aside(伴随内容) au ...
- querySelectorAll 方法相比 getElementsBy 系列方法区别
最近有人问到querySelectorAll 方法相比 getElementsBy 系列方法区别,一时没想起来说些什么,今天查下文档,总结一下它们的区别,以便自己理解. 1. W3C 标准queryS ...
- Atitit.安全性方案规划设计4gm v1 q928
Atitit.安全性方案规划设计4gm v1 q928 1. 安全架构设计与功能安全检测1 2. https1 3. 账号安全体系1 4. 配置文件安全 1 5. 源码加密与安全2 6. 最高强度的 ...
- React-Native坑:Invariant Violation:Application 项目名 has not been registered.
前言 在学习一门新技术的你也许有跟我一样的困惑,照着书上或者视频上的敲了.但是就是有各种问题没有出来自己想要的结果.我会将自己在这个过程中遇到的坑都记录下来,不一定全覆盖,但希望这些文章可以解决你的问 ...
- Linux-学习前言
本随笔会持续,不定期更新.我有上网找与Linux相关的博客,发现很多人只写了几篇就没更新了,没有坚持下来!希望我能keep on. 最近一个月是考试月,可能更新会比较少.
- js生成和下载二维码
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...
- 《Ansible权威指南》笔记(4)——Playbook
七.Playbook1.语法特性如下:(1)"---"首行顶格开始(2)#号注释(3)缩进统一,不同的缩进代表不同的级别,缩进要对齐,空格和tab不能混用(4)区别大小写,键值对k ...
- Java 性能优化之 String 篇
原文:http://www.ibm.com/developerworks/cn/java/j-lo-optmizestring/ Java 性能优化之 String 篇 String 方法用于文本分析 ...
- Crimm Imageshop 2.3。
下载地址:http://files.cnblogs.com/Imageshop/ImageShop.rar 一款体积小,能绿色执行,又功能丰富的图像处理软件. Imageshop2.3为单EXE文件, ...