面向对象

关于面向对象的标准定义网上有很多,不再讲述,现在我们来通俗点理解:
面向对象编程相对于面向过程编程和函数式编程来说,看的更长远,实现功能相对更简单。
面向对象:对象就是物体,这种编程思想就是设定一个有一定功能的物体,然后利用这个物体的功能做你想做的事情。(这个物体有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. c++ builder 2010 错误 F1004 Internal compiler error at 0x9740d99 with base 0x9

    今天遇到一个奇怪的问题,拷贝项目后,在修改,会出现F1004 Internal compiler error at 0x9740d99 with base 0x9 ,不管怎么改,删除改动,都没用,关闭 ...

  2. 最小生成树计数 bzoj 1016

    最小生成树计数 (1s 128M) award [问题描述] 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一 ...

  3. 通过Java代码实现对数据库的数据进行操作:增删改查

    在写代码之前,依然是引用mysql数据库的jar包文件:右键项目-构建路径-设置构建路径-库-添加外部JAR 在数据库中我们已经建立好一个表xs :分别有xuehao  xingming    xue ...

  4. IOS 2D游戏开发框架 SpriteKit-->续(创建敌对精灵)

    这次包括之后讲的spritekit 我都会围绕一个案例来说,这个案例就是一个简单的2d飞机大战游戏,今天这里我讲创建敌对精灵,就是敌对飞机,敌对飞机不停的被刷新到屏幕上.....当然这里涉及到的类其实 ...

  5. mysql 用户管理和权限设置

    用户管理 mysql>use mysql; 查看 mysql> select host,user,password from user ; 创建 mysql> create user ...

  6. 简单实用angular.js购物车功能

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. 浏览器渲染引擎,提高css渲染速度。

    一.渲染引擎渲染引擎的职责是……渲染,也就是把请求的内容显示到浏览器屏幕上.默认情况下渲染引擎可以显示HTML,XML文档以及图片. 通过插件(浏览器扩展)它可以显示其它类型文档. 二.各种渲染引擎我 ...

  8. React Native知识10-ListView组件

    ListView - 一个核心组件,用于高效地显示一个可以垂直滚动的变化的数据列表.最基本的使用方式就是创建一个ListView.DataSource数据源,然后给它传递一个普通的数据数组,再使用数据 ...

  9. Appfuse:扩展自己的GenericManager

    通过代码生成机制的appfuse访问数据都通过GenericManager来实现,GenericManager默认提供了以下几个方法: package org.appfuse.service; imp ...

  10. 让代码更简单——自定义toBean实现

    经过历时三天的鏖战,终于将阶段性项目——新闻发布系统做完了.在编码过程中,发现了很多冗余代码,统一流程,却需要不断重复编码——将用户输入实例化为对象的过程. 例: Person.set("i ...