面向对象概述

面向对象

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

例子

对象:Car

属性:fuel_level, isSedan, speed, steering_wheel, coordinates

方法:accelerate(), takeleft()

每个对象都有自己的内存地址或身份,对象也就是类的实例。

对象

它们表示所有开发的应用程序内的**实体**
实体之间可以通过交互来解决现实世界的问题
例如:Person是实体,而Car也是实体。Person可以驾驶Car,从一个地方开到另一个地方。

**类可以帮助开发人员表示现实世界中的实体**
类可以定义对象的属性和行为。属性是数据成员,行为由成员函数表示。
类包含了构造函数,这些函数的作用是为对象提供初始状态。
类就像模板一样,非常易于重复使用

方法

它们表示对象的行为
方法可以对属性进行处理,从而实现所需的功能。
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def get_person(self,):
return "<Person (%s, %s)>" % (self.name, self.age) # 定义一个人
p = Person("John", 32)
print("Type of Object:", type(p), "Memory Address:", id(p))
Type of Object: <class '__main__.Person'> Memory Address: 2252412092992

封装

对象的行为对于外部世界来说是不可见的,或者说对象的状态信息是私密的。
客户端不能通过直接操作来改变对象的内部状态。相反,客户端需要通过发送消息来请求对象改变其内部状态。对象可以根据请求的类型,通过特定的成员函数(get或者set)改变她们的内部状态,以做出相应的相应。
在Python中,封装(数据和方法的隐藏)的概念不是隐式的,因为他们没有提供封装所需的关键字(public private protected)。如果在变量或者函数名前面加上前缀__,就可以将其可访问性变为私有。

多态

对象根据输入参数提供方法的不同实现
不同类型的对象可以使用相同的接口
python本身就是多态的 由不同的类实例化得到的对象,调用同一个方法,执行的逻辑不同
指出了对象如何通过他们共同的属性和动作来操作及访问,而不需要考虑它们具体的类。
表明了动态绑定的存在,允许重载及运行时类型确定和验证。
体现在调用不同对象的共同方法时,才能展现出来。
a = 'bright'
b = (1,2,3)
c = [3,4,5,6,7]
print(a[1],b[0],c[2])
r 1 5
class H2O:
def __init__(self,name,temperature):
self.name=name
self.temperature=temperature
def turn_ice(self):
if self.temperature < 0:
print('[%s]温度太低结冰了' %self.name)
elif self.temperature > 0 and self.temperature < 100:
print('[%s]液化成水' %self.name)
elif self.temperature > 100:
print('[%s]温度太高变成了水蒸气' %self.name) class Water(H2O):
pass
class Ice(H2O):
pass
class Steam(H2O):
pass w1=Water('水',25)
i1=Ice('冰',-20)
s1=Steam('蒸汽',3000) # 下面三个对象调用了相同的方法,但是得到的结果却不一样。
w1.turn_ice()
i1.turn_ice()
s1.turn_ice()
[水]液化成水
[冰]温度太低结冰了
[蒸汽]温度太高变成了水蒸气

继承

继承可以表示一个类可以继承父类的大部分功能
继承被描述为一个重要基类中定义的功能并允许对原始软件的实现进行独立扩展的选项。
继承可以利用不同的对象之间的关系建立层次结构。

继承的方式

通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如白马是马,人是动物。

当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如老师是人,学生是人

class A:
def a1(self):
print('a1') class B(A):
def b(self):
print('b') b = B()
print(b.a1())
print(b.b())
a1
None
b
None
class Dad:
'这个是爸爸类'
money=10
def __init__(self,name):
print('父类')
self.name=name
def hit_son(self):
print('%s 正在打儿子' % self.name) class Son(Dad):
money = 1000000009
def __init__(self,name,age):
self.name=name
self.age=age def hit_son(self):
print('来自子类') s1 = Son('Jerry',12)
print(s1.money)
print(Dad.money) # 子类在自己里面定义了与父类同名的属性,并没有覆盖父类的属性
s1.hit_son()
print(s1.__dict__)
1000000009
10
来自子类
{'name': 'Jerry', 'age': 12}
class A:
def test(self):
print("A") class B(A): # 单继承
# def test(self):
# print("B")
pass class C(A):
def test(self):
print("C")
pass class D(B):
# def test(self):
# print("D")
pass class E(C):
# def test(self):
# print("E")
pass class F(D,E): # 多继承
# def test(self):
# print("F")
pass f1 = F()
f1.test()
# 新式类查找顺序 F >> D >> B >> E >> C >> A
# 经典类查找顺序 F >> D >> B >> A >> E >> C print(F.__mro__) ## 如果继承关系为菱形结构,那么属性的查找方式有两种,分别是:深度优先和广度优先
## 经典类时,要查找的属性不存在时,多继承会按照深度优先的方式查找
## 新式类时,要查找的属性不存在时,多继承会按照广度优先的方式查找,最后找到object
C
(<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
class Vehicle:
def __init__(self,name,speed,load,power):
self.name = name
self.speed = speed
self.load = load
self.power = power def run(self):
print("开动啦。") class Benz(Vehicle):
def __init__(self,name,speed,load,power,color):
# Vehicle.__init__(self,name,speed,load,power) # 使用指定类名方式调用了父类方法
# super(__class__.self).__init__(name,speed,load,power) # 使用super(__class__.self)方式
super().__init__(name,speed,load,power) # 采用super()不传参数的方法
self.color=color def show_info(self):
print(self.name,self.speed,self.load,self.power,self.color) def run(self):
# Vehicle.run(self) # 使用指定类名称的方式,调用了父类方法
super().run()
print("%s %s 出发啦." % (self.color,self.name)) car1 = Benz("GLK 300","120","5人","2.4T","black")
car1.show_info()
car1.run()
GLK 300 120 5人 2.4T black
开动啦。
black GLK 300 出发啦.

抽象

她提供了一个简单的客户端接口,客户端可以通过该接口与类的对象进行交互,并可以调用该接口中定义的各个方法。
她将内部类的复杂性抽象为一个接口,这样客户端就不需要知道内部实现了。
class Adder:
def __init__(self):
self.sum = 0
def add(self, value):
self.sum += value acc = Adder() for i in range(101):
acc.add(i) print(acc.sum)
5050

组合

他是一种将对象或类组合成更为复杂的数据结构或软件实现的方法
在组合中,一个对象可用于调用其它模块中的成员函数,这样一来,无需通过继承就可以实现基本功能的跨模块使用。

组合的方式

用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python和linux课程,教授有学生s1、s2、s3...

当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好

class A(object):
def a1(self):
print('a1')
class B(object):
def b(self):
print('b')
A().a1() # 实现跨类组合
objectB = B()
objectB.b()
b
a1

谈谈你对面向对象的理解?

  • 面向对象,首先我们要理解对象,什么是对象?对象是特征与技能的结合体。特征即变量,技能即函数,对象就是变量和函数的结合体,在python中既有面向对象编程,
  • 也有面向过程编程,在所做项目中需要用到哪种更加便捷就用那种编程方式,学面向对象的人,正常最常听到的一句话就是“万物皆对象”,我们编程就是将现实中的事物,
  • 抽象成程序中的对象,用特征和技能去表现出对象。

Python面向对象中的继承有什么特点?

  • 减少代码重用,可以多继承,缺点就是把子类与父类强耦合到一起

面向对象深度优先和广度优先是什么?

  • 深度优先主要体现在经典类在菱形继承的背景下,查找属性的方式
  • 广度优先主要体现在新式类在菱形继承的背景下,查找属性的方式,

面向对象中super的作用?

  • super在子类派生出新的方法中重用父类的功能
  • 注意:super()的返回值是一个特殊的随想,该对象专用用来调用父类的属性

列举面向对象中特殊成员(带双下划线的特殊方法)

__new__ 可以调用其他类的构造方法或者直接返回别的对象来作为本类的实例
__init__ 负责将类的实例化
__call__ 对象后面加括号,触发执行
__str__ print打印一个对象时 __unicode__
__repr__ 和__str__
__doc__ 类的注释,改属性是无法继承的
__getattr__ 在使用调用属性(方式.属性)不存在的时候触发
__setattr__ 添加/修改属性会触发它的执行
__delattr__ 删除属性的时候会触发
__delete__ 采用del删除属性时,触发

静态方法和类方法区别?

  • 静态方法: 相当于普通函数 staticmethod
  • 类方法: 通过类调用,第一个参数默认是类本身 classmethod

反射

通过字符串来操作类与对象的属性,这种操作称为反射
hasattr(obj,某种属性)
不知道有没有某种方法时,进行的判断
getattr(obj,某种属性,None)
查看某种属性,没有属性,可以设置为NONE,有就返回值
setattr(obj,某种属性,属性对应的值)
添加obj对象的某种属性,及其值
delattr(obj,某种属性,属性对应的值)
删除obj对象的某种属性,及其值

面向对象中方法的定义之函数讲解

什么是函数?

在程序中,函数就是具备某一功能的工具,事先将工具准备好即函数的定义;遇到应用场景拿来就用即函数的调用;函数必须遵循先定义后调用的原则

为什么要用函数

不用函数的问题是:程序冗长  程序扩展性查   程序的可读性查

函数的返回值

  1. 什么是返回值:返回值是一个函数的处理结果

  2. 为什么要有返回值:如果需要在程序中拿到函数的处理结果,做进一步的处理,则需要函数必须有返回值

  3. 函数返回值的应用:函数的返回值用return定义;格式: return x;

    【注意】:

    1. return是一个函数结束的标志,可有多个return,但只要执行一次,函数就会结束运行

    2. return的返回值五类型限制,可任意数据类型

    3. 返回值无个数限制,可用逗号分开多个任意类型的返回值

    4. 0个:返回None 1个:返回值就是值本身

    5. 多个:返回值为元组

    6. 不写return,默认会在最后return None

def max2(x,y): #x=3000,y=2000
if x > y:
return x #return 3000
else:
return y #reuturn 2000
res=max2(3000,2000)
annual_salary=res * 12
print(annual_salary)

调用函数

  1. 什么是调用函数

    函数名() 即调用,会执行函数体代码

  2. 为何要调用?

    执行函数的功能

  3. 函数调用的三种形式

def count(x):
return x
1.普通:count(x)
2.放在运算中:count(x) * 10
3.作为参数调用:count(count(x))

函数参数的应用:

形参:在函数定义阶段括号内定义的参数,称为形参,本质是变量名

实参:在函数调用阶段括号内传入的值,称为实参,本质是变量的值

详细分类

  1. 位置形参:在函数定义阶段,按从左到右的顺序依次定义的参数

    特点:必须被传值,不可多,不可少

    位置实参:在函数调用阶段,按从左到右的顺序依次定义的参数

    特点:按照位置为对应的形参依次传值

  2. 关键字实参:按key:value传值,称关键字实参

    特点:可以打破位置的限制,但仍能为指定的形参赋值

    注意:

    1.可以混用位置参数与关键字实参,但位置实参必须 在前面

    2.可以混用,但不能对一个形参重复赋值

  3. 默认参数:在函数定义阶段,就已经为形参赋值

    特点:在定义阶段已被赋值,意味着在调用时可以不为其赋值

    注意:

    1. 位置形参必须放在默认参数前面

    2. 默认参数的值只在定义阶段赋值一次,即定义时就固定写死了

    3. 默认参数的值通常应该定义不可变类型

      总结:实参的应用:可取决于个人的习惯
    
     形参的应用:
    大多数情况下调用值都一样:默认参数
    大多数情况下调用值不一样:位置参数
  4. 可变长参数:指的是在函数调用时:传入的参数个数可以不固定,而调用函数时,传值的方式无非两种,一种是位置实参,另一种是关键实参,所以对应着形参也必须有两种解决方案来分别接收溢出的位置实参(*)与关键字实参(**)

    位置参数(*)

    ①.形参中接收溢出的位置实数,然后存成元组的形式,赋值给后的变量

    ②.实参中的参数也可以带

    实参中带
    会将该参数的值循环取出,打散成位 置参数,但凡带实参,它就是位置实参,应该打散成位置实参看

    约定俗成:形参中的变量名的写法都是args

    关键字参数()**

    ①.形参中的会将溢出的关键字实参全部接收,然后存成字典的形式,赋值给后的变量名

    ②.实参中带会将该参数的值循环取出,打散成关键字实数,但凡带的实参, 它就是关键字实参,应该打散成位关键字参看。后必须是字典

    约定俗成:形参中的变量名的写法都是kwargs

如何用函数

del 函数名(参数1,参数2,...):
函数功能的描述信息
参数1描述
参数2描述
return:返回值
代码块
return:返回值

函数的定义和调用阶段

(1)函数的使用必须遵循先定义,后调用原则
(2)没有事先定义函数,而直接引用函数名,就相当于在引用一个不存在的变量名
(3)函数定义阶段:只检测函数体的语法,不执行函数体代码
(4)函数调用阶段执行代码

函数定义的三种形式

  • 定义函数时的参数就是函数体接收外部传值的一种媒介,其实就是一个变量名

无参函数

在函数定义阶段括号内没有参数

注意:定义无参,意味着调用时也无需传入参数

应用:如果函数体的代码逻辑不需要依赖外部传入的值,必须定义无参函数

def func():
print('hello world')
func()

有参函数

在函数定义阶段括号内有参数,称为有参函数

注意:定义时有参,意味着调用时也必须传入参数

应用:如果函数体代码逻辑需要依赖外部传入的值,必须定义成有参函数

def sum2(x,y):
x=10
y=20
res=x+y
print(res) sum2(10,20)
sum2(30,40)

空函数

def func():
pass

函数调用

 (1)什么是调用函数

    函数名即调用函数,会执行函数体代码,直到碰到return结束或者一直运行完毕所有代码

 (2)为何要调用函数

    用函数的功能

 (3)函数调用的三种方式
def max2(x,y):
if x > y:
return x
else:
return y #形式一:
max2(1,2) #形式二:
res=max2(3000,2000) * 12
print(res) #形式三:
res=max2(max2(1000,2000),3000)
print(res)

Python小知识点补充

  • enumerate 函数可以同时遍历元素及其序号
字母 = ["A", "B", "C", "D"]
for i, j in enumerate(字母):
print("Item {} is {}".format(i, j))
Item 0 is A
Item 1 is B
Item 2 is C
Item 3 is D
  • 自定义枚举类型
from enum import Enum
class Color(Enum):
red = 1
blue = 2
green = 3

自定义枚举的应用

Color.red
<Color.red: 1>
type(Color.green)
<enum 'Color'>
isinstance(Color.red, Color)
True
list(Color)
[<Color.red: 1>, <Color.blue: 2>, <Color.green: 3>]

引用文献:

[1]http://www.cnblogs.com/luck-L/p/9145073.html

[2]http://www.cnblogs.com/quqinchao/p/qqchanshu.html

[3]http://www.cnblogs.com/ManyQian/p/9146526.html

[4]http://www.cnblogs.com/frx9527/p/python_oop3attr.html

[5]《Python设计模式》

Python3面向对象基础的更多相关文章

  1. Python3 面向对象(基础篇)

    面向对象 关于面向对象的标准定义网上有很多,不再讲述,现在我们来通俗点理解: 面向对象编程相对于面向过程编程和函数式编程来说,看的更长远,实现功能相对更简单. 面向对象:对象就是物体,这种编程思想就是 ...

  2. 8.python笔记之面向对象基础

    title: 8.Python笔记之面向对象基础 date: 2016-02-21 15:10:35 tags: Python categories: Python --- 面向对象思维导图 (来自1 ...

  3. python 面向对象基础和高级复习

    面向对象基础 面向对象编程 面向过程编程:类似于工厂的流水线 优点:逻辑清晰 缺点:扩展性差 面向对象编程:核心是对象二字,对象属性和方法的集合体,面向对象编程就是一堆对象交互 优点:扩展性强 缺点: ...

  4. 了解JavaScript 面向对象基础 & 原型与对象

    面向对象语言中的对象 老是能听到什么基于对象, 面向对象. 什么是对象, 如果有面向对象基础的人可以无视了, 下面举个简单的例子给大家讲讲面向对象中, 对象的定义, 这个是比较通用的, 不过对于JS来 ...

  5. MYSQL、PHP基础、面向对象基础简单复习总结

    一.MYSQL         1.配置MySql                 第一步安装服务器(apache).                 第二部安装MySql界面程序         2 ...

  6. 从零开始学Python第六周:面向对象基础(需修改)

    标签(空格分隔): 面向对象 一,面向对象基础 (1)面向对象概述 面向过程:根据业务逻辑从上到下写代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类 ...

  7. python面向对象基础

    面向对象基础 1. 简述 编程方式: 面向过程: 根据代码在脚本的堆叠顺序,从上到下依次执行 函数式编程:将相同功能的代码封装到函数中,直接调用即可,减少代码重复性 面向对象:对函数进行分类和封装,将 ...

  8. java基础学习05(面向对象基础02)

    面向对象基础02 实现的目标 1.String类的使用2.掌握this关键字的使用3.掌握static关键字的使用4.了解内部类 String类 实例化String对象一个字符串就是一个String类 ...

  9. java基础学习05(面向对象基础01--类实例分析)

    面向对象基础01(类实例分析) 实现的目标 1.如何分析一个类(类的基本分析思路) 分析的思路 1.根据要求写出类所包含的属性2.所有的属性都必须进行封装(private)3.封装之后的属性通过set ...

随机推荐

  1. 【转】Python数据类型之“数字(numerics)”

    [转]Python数据类型之“数字(numerics)” 上一节内容说的是“Python基本语法”,本节主要讲下Python中的数据类型. 存储在内存中的数据通常有两个属性: 在内存中的存放位置:这个 ...

  2. 在Ubuntu中通过update-alternatives切换软件版本

    update-alternatives是ubuntu系统中专门维护系统命令链接符的工具,通过它可以很方便的设置系统默认使用哪个命令.哪个软件版本,比如,我们在系统中同时安装了open jdk和sun ...

  3. git安装及基础用法

    1.安装GitGit-2.9.3-64-bit.exe 2.打开Git Bash,设置用户名,Email $ git config --global user.name "Your Name ...

  4. 使用Navicat Premium对sqlserver 2008进行表、字段及用户权限的精细化管理

    在一些特殊的业务场景,我们需要对数据库进行精细化的管理,比如只能授权给某用户某个表的操作权限,最小权限法则可以保障数据库最大的安全.利用navicat这个轻量化的工具可以很轻松的解决这个问题 1.通过 ...

  5. Spark学习之Spark安装

    Spark安装 spark运行环境 spark是Scala写的,运行在jvm上,运行环境为java7+ 如果使用Python的API ,需要使用Python2.6+或者Python3.4+ Spark ...

  6. php获取POST数据的三种方法

    方法一,$_POST $_POST或$_REQUEST存放的是PHP以key=>value的形式格式化以后的数据. $_POST方式是通过 HTTP POST 方法传递的变量组成的数组,是自动全 ...

  7. Android 截屏与 WebView 长图分享经验总结

    最近在做新业务需求的同时,我们在 Android 上遇到了一些之前没有碰到过的问题,截屏分享. WebView 生成长图以及长图在各个分享渠道分享时图片模糊甚至分享失败等问题,在这过程中踩了很多坑,到 ...

  8. OCM_第二天课程:Section1 —》配置 Oracle 网络环境

    注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...

  9. linux POSIX 信号量介绍

    信号量一.什么是信号量信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)使用.多线程可以同时运行多个线程函数完成功能,但是对于共享数据如果不加以锁定,随意改变共享数据的值会发生 ...

  10. Windows环境selenium+Python环境配置

    1.安装Python 访问Python官方网站. 根据自己的操作系统32/64 位,选择相应的版本. 安装过程我就不详细描述了,动动手指头,Google一下,你就知道.我的安装目录为:C:\Pytho ...