1. 面向对象编程基础
把一组数据结构和处理它们的方法组成对象(object),把相同行为的对象归纳为类(class),通过类的封(encapsulation)隐藏内部细节,通过继承(inheritance)实现类的特化(specialization)和泛化(generalization),通过多态(polymorphism)实现基于对象类型的动态分派。
简而言之,面向对象在我看来,把一个实体的属性抽象出来,然后去操作这个抽象的实体,这个实体可以有种种行为(方法),而不在是简单的单一结果。
面向对象编程的2个非常重要的概念:类和对象
对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另外一个新的概念——类
类就相当于制造飞机时的图纸,用它来进行创建的飞机就相当于对象
类和对象之间的关系
面向对象有三大支柱:封装、继承和多态。
2. 定义类和创建对象
定义类:在Python中可以使用class
关键字定义类,然后在类中通过之前学习过的函数来定义方法
定义一个类
class Car:
# 方法
def getCarInfo(self):
print('车*个数:%d, 颜色%s'%(self.wheelNum, self.color))
def move(self):
print("车正在移动...")
创建一个对象
# -*- coding:utf-8 -*-
"""
定义一个类,再创建一个对象
version:0.1
author:coke
"""
#类
class Car:
#方法
def getCarInfo(self):
print('车*个数:%d,颜色%s'%(self.wheelNum,self.color))
def move(self):
print("车正在移动")
BMW = Car()
BMW.color = "黑色"
BMW.wheelNum = 4
BMW.getCarInfo()
BMW.move()
注:这里出现了 self
,所谓的self
,可以理解为自己 ,某个对象调用其方法时,python解释器会把这个对象作为第一个参数传递给self
,所以开发者只需要传递后面的参数即可
3. init() 方法
在上一小节的demo中,我们已经给BMW这个对象添加了2个属性,wheelNum(车的轮胎数量)以及color(车的颜色),试想如果再次创建一个对象的话,肯定也需要进行添加属性,显然这样做很费事,那么有没有办法能够在创建对象的时候,就顺便把车这个对象的属性给设置呢?
# -*- coding:utf-8 -*-
"""
_init_使用
version:0.1
author:coke
"""
#定义汽车类
class Car:
def __init__(self):
self.wheelNum = 4
self.color = '蓝色'
def move(self):
print('车在跑,目标:夏威夷')
# 创建对象
BMW = Car()
print('车的颜色为:%s'%BMW.color)
print('车轮胎数量为:%d'%BMW.wheelNum)
总结:当创建Car对象后,在没有调用__init__()
方法的前提下,BMW就默认拥有了2个属性wheelNum和color,原因是__init__()
方法是在创建对象后,就立刻被默认调用了
4. 魔法方法
在python中方法名如果是__xxxx__()
的,那么就有特殊的功能,因此叫做“魔法”方法
当使用print输出对象的时候,只要自己定义了__str__(self)
方法,那么就会打印从在这个方法中return的数据
# -*- coding:utf-8 -*-
"""
_init_使用
version:0.1
author:coke
"""
#定义汽车类
class Car:
def __init__(self,newWheelNum,newColor):
self.wheelNum = newWheelNum
self.color = newColor
def __str__(self):
msg = "车轮胎数:" + str(self.wheelNum) + " 车的颜色:" + self.color
return msg
def move(self):
print("车在跑,目标夏威夷")
BWM = Car(4,"green")
BWM.move()
print(BWM)
5. 访问可见性问题
在很多面向对象编程语言中,我们通常会将对象的属性设置为私有的(private)或受保护的(protected),简单的说就是不允许外界访问,而对象的方法通常都是公开的(public),因为公开的方法就是对象能够接受的消息。在Python中,属性和方法的访问权限只有两种,也就是公开的和私有的,如果希望属性是私有的,在给属性命名时可以用两个下划线作为开头,下面的代码可以验证这一点。
# -*- coding:utf-8 -*-
"""
测试可见性
version:0.1
author:coke
"""
class Test:
def __init__(self, foo):
self.__foo = foo
def __bar(self):
print(self.__foo)
print('__bar')
def main():
test = Test('hello')
# AttributeError: 'Test' object has no attribute '__bar'
test.__bar()
# AttributeError: 'Test' object has no attribute '__foo'
print(test.__foo)
if __name__ == "__main__":
main()
但是,Python并没有从语法上严格保证私有属性或方法的私密性,它只是给私有的属性和方法换了一个名字来“妨碍”对它们的访问,事实上如果你知道更换名字的规则仍然可以访问到它们,下面的代码就可以验证这一点。之所以这样设定,可以用这样一句名言加以解释,就是“We are all consenting adults here”。因为绝大多数程序员都认为开放比封闭要好,而且程序员要自己为自己的行为负责。
# -*- coding:utf-8 -*-
"""
测试可见性
version:0.2
author:coke
"""
class Test:
def __init__(self,foo):
self.__foo = foo
def __bar(self):
print(self.__foo);
print("__bar")
def __str__(self):
return self.__foo
def main():
test = Test("hello")
print(test)
#事实上还是可以在外部访问 __foo属性
print(test._Test__foo)
if __name__ == "__main__":
main()
在实际开发中,我们并不建议将属性设置为私有的,因为这会导致子类无法访问(后面会讲到)。所以大多数Python程序员会遵循一种命名惯例就是让属性名以单下划线开头来表示属性是受保护的,本类之外的代码在访问这样的属性时应该要保持慎重
5. 练习
为了更好的理解面向对象编程,下面以“烤地瓜”为案例,进行分析
示例属性如下:
- cookedLevel : 这是数字;0~3表示还是生的,超过3表示半生不熟,超过5表示已经烤好了,超过8表示已经烤成木炭了!我们的地瓜开始时时生的
- cookedString : 这是字符串;描述地瓜的生熟程度
- condiments : 这是地瓜的配料列表,比如番茄酱、芥末酱等
示例方法如下:
-
cook()
: 把地瓜烤一段时间 -
addCondiments()
: 给地瓜添加配料 -
__init__()
: 设置默认的属性 -
__str__()
: 让print的结果看起来更好一些
1、定义类,并且定义__init__()方法
#定义`地瓜`类
class SweetPotato:
'这是烤地瓜的类'
#定义初始化方法
def __init__(self):
self.cookedLevel = 0
self.cookedString = "生的"
self.condiments = []
2、添加"烤地瓜"方法
#烤地瓜方法
def cook(self, time):
self.cookedLevel += time
if self.cookedLevel > 8:
self.cookedString = "烤成灰了"
elif self.cookedLevel > 5:
self.cookedString = "烤好了"
elif self.cookedLevel > 3:
self.cookedString = "半生不熟"
else:
self.cookedString = "生的"
3、基本的功能已经有了一部分,赶紧测试一下
mySweetPotato = SweetPotato()
print(mySweetPotato.cookedLevel)
print(mySweetPotato.cookedString)
print(mySweetPotato.condiments)
4、定义addCondiments()方法和__str__()方法
def __str__(self):
msg = self.cookedString + " 地瓜"
if len(self.condiments) > 0:
msg = msg + "("
for temp in self.condiments:
msg = msg + temp + ", "
msg = msg.strip(", ")
msg = msg + ")"
return msg
def addCondiments(self, condiments):
self.condiments.append(condiments)
全部代码
# -*- coding:utf-8 -*-
"""
烤地瓜
"""
class SweetPotato:
"这是烤地瓜的类"
#定义初始化方法
def __init__(self):
self.cookedLevel = 0
self.cookedString = "生的"
self.condiments = []
#添加烤地瓜的方法
def cook(self,time):
self.cookedLevel += time
if self.cookedLevel > 10:
self.cookedString = "烤成灰了"
elif self.cookedLevel > 5:
self.cookedString = "烤好了"
elif self.cookedLevel > 3:
self.cookedString = "半生不熟"
else:
self.cookedString = "生的"
#添加配料
def addCondiments(self,condiment):
self.condiments.append(condiment)
def __str__(self):
msg = self.cookedString + "地瓜"
if len(self.condiments) > 0:
msg = msg + "("
for temp in self.condiments:
msg = msg + temp + ", "
msg = msg.strip(", ")
msg = msg + ")"
return msg
mySweetPotato = SweetPotato()
print("------有了一个地瓜,还没有烤--------")
print(mySweetPotato.cookedLevel)
print(mySweetPotato.cookedString)
print(mySweetPotato.condiments)
print("---------接下来进行烤地瓜------------")
print("---------地瓜烤了四分钟------------")
mySweetPotato.cook(4)
print(mySweetPotato)
print("---------地瓜又烤了分钟-----------")
mySweetPotato.cook(3)
print(mySweetPotato)
print("----------添加配料番茄酱------------")
mySweetPotato.addCondiments("番茄酱")
mySweetPotato.addCondiments("芥末酱")
mySweetPotato.cook(2)
print(mySweetPotato)
输出结果
Python基础 — 面向对象编程基础的更多相关文章
-
大数据技术之_16_Scala学习_04_函数式编程-基础+面向对象编程-基础
第五章 函数式编程-基础5.1 函数式编程内容说明5.1.1 函数式编程内容5.1.2 函数式编程授课顺序5.2 函数式编程介绍5.2.1 几个概念的说明5.2.2 方法.函数.函数式编程和面向对象编 ...
-
Python——11面向对象编程基础
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...
-
Python进阶(面向对象编程基础)(三)
6.类属性和实例属性名字冲突怎么办 修改类属性会导致所有实例访问到的类属性全部都受影响,但是,如果在实例变量上修改类属性会发生什么问题呢? class Person(object): address ...
-
Python进阶(面向对象编程基础)(二)
1.初始化实例属性 #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'ziv·chan' #定义Person类的__init__方法 ...
-
Python进阶(面向对象编程基础)(一)
鉴于昨天被类和函数折腾得晕头转向,今特把类的知识翻出来温习. 1.定义类并创建实力对象 #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ ...
-
Python进阶(面向对象编程基础)(四)
1.方法也是属性 我们在 class 中定义的实例方法其实也是属性,它实际上是一个函数对象: class Person(object): def __init__(self, name, score) ...
-
python基础——面向对象编程
python基础——面向对象编程 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的 ...
-
Python 面向对象编程基础
Python 面向对象编程基础 虽然Pthon是解释性语言,但是Pthon可以进行面向对象开发,小到 脚本程序,大到3D游戏,Python都可以做到. 一类: 语法: class 类名: 类属性,方法 ...
-
Python学习-第三天-面向对象编程基础
Python学习-第三天-面向对象编程基础 类和对象 简单的说,类是对象的蓝图和模板,而对象是类的实例.这个解释虽然有点像用概念在解释概念,但是从这句话我们至少可以看出,类是抽象的概念,而对象是具体的 ...
随机推荐
-
D3.js 更*的条形图
一.添加一个矩形 //Width and height var w = 500; var h = 100; var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, ...
-
UIView背景渐变三种方法
//此作品非原创 #import "ACViewController.h" @interface ACViewController () @end @implementation ...
-
夏令营提高班上午上机测试 Day 1 解题报告
Day 1的题难度上来说不算太高,但是T2和T3还是有一定的思维量的. 一个比较好的开始.虽然AK的人只有几个.. (懒得去翻result了..忘了当时拿了多少分了 (哦,前两天我们机房是没有成绩的, ...
-
《Jave并发编程的艺术》学习笔记(1-2章)
Jave并发的艺术 并发编程的挑战 上下文切换 CPU通过时间片分配算法来循环执行任务,当前时间片执行完之后会切换到下一个任务.但是,切换会保存上一个任务的状态,一遍下次切换回这个任务时,可以再次加载 ...
-
linux命令总结之tr命令
什么是tr命令?tr,translate的简写,translate的翻译: [trænsˈleit] vi. 翻译, 能被译出 vt. 翻译, 解释, 转化, 转变为, 调动 在这里用到的意思是转化, ...
-
Fiddler抓包5-接口测试(Composer)
前言 Fiddler最大的优势在于抓包,我们大部分使用的功能也在抓包的功能上,fiddler做接口测试也是非常方便的. 对应没有接口测试文档的时候,可以直接抓完包后,copy请求参数,修改下就可以了. ...
-
SharePoint 列表中增加列编辑功能菜单
需求描述 在企业的部署中,经常将SharePoint和TFS集成在一起,两个系统之间相互读取数据,展现开发进度.在TFS 2018之前版本中,由于TFS的门户定制功能有限,用户比较喜欢使用ShareP ...
-
Splash args 属性
args属性可以获取加载时配置的参数,一般我们只传入URL,如下,args.url 就相当于加载时配置的URL参数,我们把它赋值给 url 变量然后返回:
-
linux xargs 命令详解
xargs是给命令传递参数的一个过滤器,也是组合多个命令的一个工具.它把一个数据流分割为一些足够小的块,以方便过滤器和命令进行处理.通常情况下,xargs从管道或者stdin中读取数据,但是它也能够从 ...
-
Trie树【p2264】情书
Background 一封好的情书需要撰写人全身心的投入.CYY同学看上了可爱的c**想对她表白,但却不知道自己写的情书是否能感动她,现在他带着情书请你来帮助他. Description 为了帮助CY ...