面向对象

关于面向对象的标准定义网上有很多,不再讲述,现在我们来通俗点理解:
面向对象编程相对于面向过程编程和函数式编程来说,看的更长远,实现功能相对更简单。
面向对象:对象就是物体,这种编程思想就是设定一个有一定功能的物体,然后利用这个物体的功能做你想做的事情。(这个物体有attributes,比如名字啊,年龄啊等等等等,有methods,比如吃喝拉撒睡等等等等,功能==methods)
面向过程:你想干嘛,就直接写个功能,然后做你想做的事情。
假如你想写个程序去洗衣店洗衣服,面向对象就是设定一个人,把这个对象赋予拿衣服,搭车,交易,取衣服,回家这所有的过程的功能。当你想洗衣服的时候,创造这个对象的实例出来,然后命令他去做就好了。
面向过程:你就得写拿衣服,搭车,交易,取衣服,回家这所有的过程。实现这一个功能感觉和面向对象编程的思想差不多,但是如果你下一次还想洗衣服,就得再写一遍这个过程,假如会有很多次洗衣服,那就得写更多次,很麻烦,易出错。
 

定义类,实例化对象

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 面向对象(基础篇)的更多相关文章

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

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

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

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

  3. Python3面向对象基础

    面向对象概述 面向对象 面向对象的世界,引入了对象的概念,对象具有属性:数据,对象具有过程或者方法:成员函数.成员函数的作用就是处理属性. 例子 对象:Car 属性:fuel_level, isSed ...

  4. java类与对象基础篇

    java面向对象基础篇 面向对象程序设计(Object Oriented Proframming ,OOP) 面向对象的本质是:以类的方式组织代码,以对象的方式组织(封装)数据. 面向对象的核心思想是 ...

  5. 图解Python 【第五篇】:面向对象-类-初级基础篇

    由于类的内容比较多,分为类-初级基础篇和类-进阶篇 类的内容总览图: 本节主要讲基础和面向对象的特性 本节内容一览图: 前言总结介绍: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 ...

  6. Python3学习(1)-基础篇

    Python3学习(1)-基础篇 Python3学习(2)-中级篇 Python3学习(3)-高级篇 安装(MAC) 直接运行: brew install python3 输入:python3 --v ...

  7. 夯实Java基础系列1:Java面向对象三大特性(基础篇)

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 [https://github.com/h2pl/Java-Tutorial](https: ...

  8. Python(三)基础篇之「模块&面向对象编程」

    [笔记]Python(三)基础篇之「模块&面向对象编程」 2016-12-07 ZOE    编程之魅  Python Notes: ★ 如果你是第一次阅读,推荐先浏览:[重要公告]文章更新. ...

  9. Python 经典面试题汇总之基础篇

    基础篇 1:为什么学习Python 公司建议使用Python,然后自己通过百度和向有学过Python的同学了解了Python.Python这门语言,入门比较简单,它简单易学,生态圈比较强大,涉及的地方 ...

随机推荐

  1. Elastic学习第一天遇到的问题以及添加的一些操作

    1.刚开始安装好了之后,启动之后, 报错: ERROR: max file descriptors [] ] 需要设置max file descriptors为65536,出现这个是因为普通的用户是1 ...

  2. 使用Ring Buffer构建高性能的文件写入程序

    最近常收到SOD框架的朋友报告的SOD的SQL日志功能报错:文件句柄丢失.经过分析得知,这些朋友使用SOD框架开发了访问量比较大的系统,由于忘记关闭SQL日志功能所以出现了很高频率的日志写入操作,从而 ...

  3. [Android]使用MVP解决技术债务(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5892671.html 使用MVP解决技术债务 原文:https ...

  4. (十一)Maven远程仓库的各种配置

    1.远程仓库的配置 在平时的开发中,我们往往不会使用默认的中央仓库,默认的中央仓库访问的速度比较慢,访问的人或许很多,有时候也无法满足我们项目的需求,可能项目需要的某些构件中央仓库中是没有的,而在其他 ...

  5. javaScript对象-基本包装类型的详解

    本人按书上的内容大致地把javaScript对象划分成“引用类型”.“基本包装类型”和“内置对象”三块内容. 我们这篇先了解下基本包装类型的详细用法吧! 一.我们先解下相关概念: 1.引用类型的值(对 ...

  6. JavaScript—从数组的indexOf方法深入——Object的Property机制。

    在js中,可以说万物皆对象(object),一个数组也是一个对象(array). 很多对象都有很多很方便的方法 比如数组的push,concat,slice等等,但是如果一些对象,它没有实现这些方法, ...

  7. 文本处理三剑客之sed命令

    第十八章.文本处理三剑客之sed命令 目录 sed介绍 sed命令常用选项 sed常用编辑命令 sed使用示例 sed高级语法 18.1.sed简介 sed全名stream editor,流编辑器,s ...

  8. Fedora javac 命令提示 [javac: 未找到命令...]

    [joy@localhost ~]$ java -version openjdk version "1.8.0_91" OpenJDK Runtime Environment (b ...

  9. (转)浅谈Java中的对象和对象引用

    原文地址: http://www.cnblogs.com/dolphin0520/p/3592498.html 在Java中,有一组名词经常一起出现,它们就是"对象和对象引用",很 ...

  10. Collections.shuffle

    1.Collections.shuffler 最近有个需求是生成十万级至百万级的所有随机数,最简单的思路是一个个生成,生成新的时候排重,但是这样时间复杂度是o(n^2),网上看了几个博客的解决方法都不 ...