参考文档:

http://www.cnblogs.com/linhaifeng/articles/6182264.html#

类:把一类事物的相同的特征和动作整合到一起就是类,类是抽象的概练

对象:就是基于类而创建的具体存在的,也是特征和动作整合到一起

一,面向对象设计过程

  现实世界中先有对象有了明确的特征以及动作才有类,比如先有人,人有名字,有性别等特征,有吃饭睡觉等动作,有着这些相同的人统称为人类

  设计一个公司,公司有名称,有地址,有公司类型,有上班的动作

  面向对象设计1.py

c1 = {
'name':'bbc',
'addr':'ShenZhen',
'type':'big'
} def shangban(company):
print('[%s]公司在[%s]是一家[%s]正常上班' %(company['name'],company['addr'],company['type'])) shangban(c1) #[bbc]公司在[ShenZhen]是一家[big]正常上班

  这样设置假如有另外一家公司又需要定义一个新的字典比如c2,明显不合理。

  把公司定义为一个函数作为一个类来生成公司

  面向对象设计2.py

#定义公司的函数,参数为公司名称name公司地址addr公司类型type
def company(name,addr,type): def shangban(c):
print('[%s]公司在[%s]是一家[%s]正常上班' %(c['name'],c['addr'],c['type']))
#定义一个字典接收用户传递的公司信息,并且作为函数的返回值
c1 = {
'name': name,
'addr': addr,
'type': type,
'shangban': shangban
}
return c1 #通过定义的函数company相当于是定义的类生成一个公司
#返回的是一个字典
c1 = company('bbc','ShenZhen','big')
print(c1)
#{'shangban': <function company.<locals>.shangban at 0x000001F812336950>, 'addr': 'ShenZhen', 'name': 'bbc', 'type': 'big'}
#需要执行公司的一个特定动作,因为函数内部的动作函数上班需要传递的参数为一个字典及需要传递刚刚的公司返回值作为参数执行
c1['shangban'](c1)
#[bbc]公司在[ShenZhen]是一家[big]正常上班
#同理可以通过定义的公司类生成另外一个对象及另外一家公司
c2 = company('CCTV','BeiJing','litter')
c2['shangban'](c2)
#[CCTV]公司在[BeiJing]是一家[litter]正常上班

  这样定义还不够好,需要在内部在定义一个初始化函数init用于初始化公司信息

  面向对象设计3.py

# 定义公司的函数,参数为公司名称name公司地址addr公司类型type
def company(name, addr, type):
def shangban(c):
print('[%s]公司在[%s]是一家[%s]正常上班' % (c['name'], c['addr'], c['type'])) # 定义一个字典接收用户传递的公司信息,并且作为函数的返回值
def init(name,addr,type):
c1 = {
'name': name,
'addr': addr,
'type': type,
'shangban': shangban
}
return c1
#运行初始化公司的函数,运行的结果也就是一个字典作为返回值返回
ret = init(name,addr,type)
print(ret)
#{'type': 'big', 'addr': 'ShenZhen', 'shangban': <function company.<locals>.shangban at 0x0000016212AC6950>, 'name': 'bbc'}
return ret # 通过定义的函数company相当于是定义的类生成一个公司
# 返回的是一个字典
c1 = company('bbc', 'ShenZhen', 'big')
#print(c1)
# {'shangban': <function company.<locals>.shangban at 0x000001F812336950>, 'addr': 'ShenZhen', 'name': 'bbc', 'type': 'big'}
# 需要执行公司的一个特定动作,因为函数内部的动作函数上班需要传递的参数为一个字典及需要传递刚刚的公司返回值作为参数执行
c1['shangban'](c1)
# [bbc]公司在[ShenZhen]是一家[big]正常上班
# 同理可以通过定义的公司类生成另外一个对象及另外一家公司
#c2 = company('CCTV', 'BeiJing', 'litter')
#c2['shangban'](c2)
# [CCTV]公司在[BeiJing]是一家[litter]正常上班

  以上的编程思想就是面向对象的编程思想,虽然是使用函数的方式来实现的。

  下面使用python提供的类方法class实现

  面向对象设计4.py

class company:
def __init__(self,name,addr,type):
self.name=name
self.addr=addr
self.type=type
def shangban(self):
print('[%s]公司在[%s]是一家[%s]公司正常上班' %(self.name,self.addr,self.type))
c1=company('bbc','ShenZhen','big')
#使用内置方法可以打印出对应的字典
#与函数实现的面向对象的方法返回来的字典不同少了一个函数对应的对象,直接打印出字典
print(c1.__dict__)
#{'addr': 'ShenZhen', 'name': 'bbc', 'type': 'big'}
c1.shangban()
#[bbc]公司在[ShenZhen]是一家[big]公司正常上班

  

二,类的相关知识

  类的相关知识.py

class Chinese:
#这是一个中国人的类
dang='党'
def sui_di_tu_tan(self):
print('%s朝着墙上就是一口痰'%self)
def cha_dui(self):
print('插到了前面')
print(Chinese.dang)
Chinese.sui_di_tu_tan('asd')
#查看类的属性
print(dir(Chinese))
#查看类的属性字典
print(Chinese.__dict__)
#打印类名
print(Chinese.__name__)
#Chinese
#打印类的文档名
print(Chinese.__doc__)
#None
#打印类的祖先
print(Chinese.__base__)
#<class 'object'>
print(Chinese.__bases__)
#打印类的祖先(以元祖的形式)
#(<class 'object'>,)
#打印类的模块
print(Chinese.__module__)
#__main__
#打印实例对应的类
print(Chinese.__class__)
#<class 'type'>

  

  类的相关知识2.py

class Chinese:
#这是一个中国人的类
dang='党'
#定义初始化函数 必须用__init__这种定义方式才能接收参数
#不需要像函数一样写return
#必须有默认需要的self参数
def __init__(self,name,age,gender):
print('我是初始化函数 我开始运行了')
#dic = {
# 'name':name,
# 'age':age,
# 'gender':gender
# }
#return dic
self.mingzi=name
self.nianji=age
self.xingbie=gender
print('初始化函数运行完毕')
def sui_di_tu_tan(self):
print('朝着墙上就是一口痰')
def cha_dui(self):
print('%s插到了前面' %self.mingzi)
#return init(name,age,gender) #实例化
#其实就是调用了类里面__init__这个函数的运行
#返回的就是一个实例化以后的对象
#其实执行的过程是p1 = __init__(p1,name,age,genter)
p1 = Chinese('月明',18,'female')
#打印p1这个对象的字典属性
print(p1.__dict__)
#{'mingzi': '月明', 'nianji': 18, 'xingbie': 'female'} #调用字典对象的属性
#以下两种方法效果一样,第二种更加简洁高效
print(p1.__dict__['mingzi'])
print(p1.mingzi)
#月明 #调用类的属性(虽然这个属性不在字典里面)
#为什么可以打印出来,和函数的作用域有关
#在本作用域找不到就返回上一层寻找
print(p1.dang)
#党 #通过类调用里面的方法和实例无关
#因为函数需要一个参数把实例化以后的对象p1作为参数传递
Chinese.cha_dui(p1)
#p1.sui_di_tu_tan()
#默认已经把p1对象作为参数传递给函数cha_dui所以这里调用在()里面不需要加参数
p1.cha_dui()
#PS:类有数据属性和函数属性 实例(对象)只有数据属性没有函数属性需要使用函数属性去找类要

  PS:类里面定义的方法函数都需要带有self参数,调用方法默认把对象作为实参传递给形参self

  类属性的增删改查

  类属性的增删改查.py

#类属性又称为静态变量,或者静态数据。这些数据与他们所属的类对象绑定,不依赖于任何类实例
class ChinesePeople:
country='China'
def __init__(self,name):
self.name=name #函数属性定义的原则是动词加名词(做什么事情)
def play_ball(self,ball):
print('%s 正在打 %s'%(self.name)) def say_word(self,word):
print('%s 说 %s' %(self.name,word)) #查看类属性
print(ChinesePeople.country)
#China
#修改类属性
ChinesePeople.country='CHINA'
#修改后查看
print(ChinesePeople.country)
#CHINA
#删除类属性
del ChinesePeople.country
#打印会报错因为没有这个属性了
#print(ChinesePeople.country)
#增加类属性
ChinesePeople.location='ASia'
p1=ChinesePeople('zhangsan') #增加函数方法
def eat_food(self,food):
print('%s正在吃%s'%(self.name,food)) ChinesePeople.eat=eat_food
print(ChinesePeople.__dict__)
p1.eat('米饭')
#zhangsan正在吃米饭 #修改函数方法是重新定义一个函数然后赋值给原函数方法
def test(self):
print('test') ChinesePeople.play_ball=test
p1.play_ball()

  实例属性的增删改查.py

#类属性又称为静态变量,或者静态数据。这些数据与他们所属的类对象绑定,不依赖于任何类实例
class ChinesePeople:
country='China'
def __init__(self,name):
self.name=name #函数属性定义的原则是动词加名词(做什么事情)
def play_ball(self,ball):
print('%s 正在打 %s'%(self.name,ball)) def say_word(self,word):
print('%s 说 %s' %(self.name,word)) p1=ChinesePeople('zhangsan')
#查看实例属性字典
print(p1.__dict__)
#{'name': 'zhangsan'} #查看实例的数据属性
print(p1.name)
#zhangsan
#查看实例的函数属性
print(p1.play_ball)
#<bound method ChinesePeople.play_ball of <__main__.ChinesePeople object at 0x000001FA7A8D72B0>>
#PS:可以看到这个一个绑定在类ChinesePeople的方法 #增加数据属性
p1.age=18
print(p1.__dict__)
#{'name': 'zhangsan', 'age': 18} def test(self):
print('我是来自实例的函数属性') #增加实例的函数属性
p1.test=test
print(p1.__dict__)
#{'age': 18, 'test': <function test at 0x00000155FE2A9048>, 'name': 'zhangsan'}
#调用不会传递默认参数需要手动加
p1.test(p1)
#PS:实例的函数属性增加几乎不用,知道即可
#需要增加函数属性直接在类里面定义这步纯属多余
#PS:实例只有数据属性,之所以能添加修改是因为是直接对字典进行修改,强烈不建议修改字典属性 #修改
p1.age=19
print(p1.__dict__)
#{'age': 19, 'name': 'zhangsan', 'test': <function test at 0x0000027325FF9048>} #删除
del p1.age
print(p1.__dict__)
#删除后就没有age了
#{'name': 'zhangsan', 'test': <function test at 0x000001F784489048>}

  

  类里面定义的数据属性及函数属性通过定义的对象加.调用,如果不使用对象加.的方式调用其实就相当于一个普通变量,看以下列子

  类里面数据属性及函数属性的调用方式.py

country='中国---'
class ChinesePeople:
country='中国'
def __init__(self,name):
self.name=name
print('不使用.的调用方式调用的就是一个普通的变量',country) #函数属性定义的原则是动词加名词(做什么事情)
def play_ball(self,ball):
print('%s 正在打 %s'%(self.name,ball)) #对象实例化会执行__init__函数 因为在里面定义了一个print打印country这里的country因为没有加.所以只是一个普通的全局变量
#在类里面也定义了country但是这个是在类里面的,需要通过加.调用
p1=ChinesePeople('张三')
#不使用.的调用方式调用的就是一个普通的变量 中国---
#使用.调用类的属性
print(ChinesePeople.country)
#中国
#实例对应的属性也是中国
print('实例的',p1.country)

  

  之前对对象及类的属性修改均是通过赋值的方式修改,假如类里面有个数据属性是一个列表通过append等方式直接修改列表情况又不一样

  对象属性补充.py

class ChinesePeople:
country='China'
l=['a','b']
def __init__(self,name):
self.name=name def play_ball(self,ball):
print('%s 正在打 %s'%(self.name,ball)) p1=ChinesePeople('zhangsan')
p1.country='Japan'
#修改p1的countr对应的值后类的对应值保持China不变
print(p1.country)
#Japan
print(ChinesePeople.country)
#China
#以上是通过赋值的方式修改,但是通过如下的方式修改其实是对类里面的列表进行修改所
#所以类和对象对应的属性均修改了
p1.l.append('c')
print(p1.l)
##['a', 'b', 'c']
print(ChinesePeople.l)
##['a', 'b', 'c']

 

PS:实例(对象)调用类的方法会自动传递参数,类调用类的方法需要手动输入参数

三,静态属性

  看以下列子

  静态属性1.py

class Room:
def __init__(self,name,owner,width,length,heigh):
self.name=name
self.owner=owner
self.width=width
self.length=length
self.heigh=heigh r1 = Room('厕所','zhangsan',100,100,10000) print('[%s] 住的 %s 总面积是%s'%(r1.owner,r1.name,r1.width*r1.length)) #[zhangsan] 住的 厕所 总面积是10000

  需要计算出住所面积,可以直接在类外面调用对应参数计算,假如需要计算多个人员的则最好把计算面积写在类里面定下一个方法

  静态属性2.py

class Room:
def __init__(self,name,owner,width,length,heigh):
self.name=name
self.owner=owner
self.width=width
self.length=length
self.heigh=heigh
#定义计算面积的函数方法
def cal_area(self):
print('[%s] 住的 %s 总面积是%s' % (self.owner, self.name, self.width * self.length)) r1 = Room('厕所','zhangsan',100,100,10000) #直接通过函数调用,减少重复代码
r1.cal_area()

  Python类提供一个装饰器的方法把该动态的函数属性转换成一个静态属性

  静态属性3.py

class Room:
def __init__(self,name,owner,width,length,heigh):
self.name=name
self.owner=owner
self.width=width
self.length=length
self.heigh=heigh # 定义计算面积的函数方法
# 并且使用property装饰成静态属性
@property
def cal_area(self):
print('[%s] 住的 %s 总面积是%s' % (self.owner, self.name, self.width * self.length)) r1 = Room('厕所','zhangsan',100,100,10000)
#调用不需要加()来执行函数
r1.cal_area
#[zhangsan] 住的 厕所 总面积是10000

  在类内部加了装饰器调用时候和调用数据属性一样,对于外部调用用户无感知,不知道在类里面定义的是数据类型还是函数类型

   

四,类方法

  一个类需要调用类里面的属性必须要通过一个实例(对象)调用或者通过类调用(也需要传递一个实例作为参数)

  以下列子需要获取到类的数据属性tag信息

  类方法1.py

class Room:
tag = 1
def __init__(self,name,owner,width,length,heigh):
self.name=name
self.owner=owner
self.width=width
self.length=length
self.heigh=heigh # def tell_info(cls):
# print('--->',cls.tag)
def tell_info(self):
print('---->',self.tag ) r1 = Room('WC','zhangsan',1,1,1)
#通过实例获取信息
r1.tell_info()
#----> 1
#就算是通过类来执行也需要传递一个实例参数才能获取信息
Room.tell_info(r1)
#----> 1

  Python类提供装饰器可以不通过实例(对象直接获取对应数据属性),不需要借助实例(对象)

  类方法2.py

class Room:
tag = 1
def __init__(self,name,owner,width,length,heigh):
self.name=name
self.owner=owner
self.width=width
self.length=length
self.heigh=heigh
#类方法装饰器
@classmethod
def tell_info(cls):
print('--->',cls.tag) #通过类方法调用对应数据属性
Room.tell_info()
#---> 1

  

  

五,静态方法

  静态方法1.py

class Room:
tag = 1
def __init__(self,name,owner,width,length,heigh):
self.name=name
self.owner=owner
self.width=width
self.length=length
self.heigh=heigh
@property
def cal_area(self):
print('[%s] 住的 %s 总面积是%s' % (self.owner, self.name, self.width * self.length)) @classmethod
def tell_info(cls):
print('--->',cls.tag) #静态方法装饰器
#类的工具包,与类和实例是剥离的
#静态方法只是名义上归属类管理,不能使用类变量和实例变量,只是类的工具包
@staticmethod
def wash_body(a,b,c):
print('%s %s %s正在洗澡'%(a,b,c)) def test(x,y):
print(x,y)
#使用类可以调用静态方法
Room.wash_body('zhangsan','lisi','wangwu')
#zhangsan lisi wangwu正在洗澡
#使用实例(对象)也可以调用静态方法
r1=Room('WC','zhangsan',1,1,1)
r1.wash_body('zhangsan','lisi','wangwu')
#zhangsan lisi wangwu正在洗澡
#PS:静态方法其实就相当于一个普通的函数,只不过是定义在类里面

 

  小结:

    静态属性是把函数封装成数据属性的形式,外面调用感受不到内部的逻辑

    类方法定义时候自动加参数cls,可以不通过实例访问类的数据属性和函数属性,不能访问实例的属性

    静态方法参数不是self和cls,不能访问类的属性和实例属性,只是类的工具包

六,组合

  组合.py

# class Hand:
# pass
#
# class Foot:
# pass
#
# class Trunk:
# pass
#
# class Head:
# pass
#
# class Person:
# def __init__(self,id_num,name):
# self.id_num=id_num
# self.name=name
# self.hand=Hand()
# self.foot=Foot()
# self.trunk=Trunk()
# self.head=Head()
# p1 = Person('1111','zhangs')
#
# print(p1.__dict__) #定义学校类,有名字,地址
class School:
def __init__(self,name,addr):
self.name=name
self.addr=addr def zhao_sheng(self):
print('%s正在招生'%self.name) #定义课程类,有名字,价格,周期,学校
class Course:
def __init__(self,name,price,period,school):
self.name=name
self.price=price
self.period=period
self.school=school #实例化出3个校区
s1=School('oldboy','北京')
s2=School('oldboy','南京')
s3=School('oldboy','东京') #实例化出1个课程
#学校传递一个实例化出来的学校
c1=Course('linux',10,'1h',s1)
print(c1.__dict__)
#{'period': '1h', 'school': <__main__.School object at 0x000002BB732E8080>, 'price': 10, 'name': 'linux'}
print(c1.school.name)
#oldboy msg='''
1,老男孩 北京校区
2,老男孩 南京校区
3,老男孩 东京校区
'''
while True:
print(msg)
menu={
'1':s1,
'2':s2,
'3':s3
}
choice=input('选择学校>>:')
school_boj=menu[choice] name=input('课程名>>:')
price=input('课程费用>>:')
period=input('课程周期>>:') new_course=Course(name,price,period,school_boj)
print('课程[%s]属于[%s]学校[%s]校区' %(new_course.name,new_course.school.name,menu[choice].addr))

  

七,面向对象的三大特性

  1,继承

  类的继承类似于现实生活中的父子等关系

  继承1.py

class Dad:
money=10
def __init__(self,name):
print('爸爸')
self.name=name def hit_son(self):
print('%s正在打儿子'%self.name) #定义一个类继承Dad
class Son(Dad):
pass s1 = Son('zhangsan')
print(s1.name)
#zhangsan
#子类继承父类的数据属性
print(s1.money)
#子类继承父类的方法
s1.hit_son()
#zhangsan正在打儿子

  什么时候用继承

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

  例如:描述一个机器人了,机器人这个大类是由很多互不相关的小类组成,比如机械胳膊类,腿类,身体类

  当类之间有很多相同的功能,提取这些共同的功能组成基类,用继承比较好

  例如

  猫可以:喵喵叫,吃喝拉撒

  狗可以:汪汪叫,吃喝拉撒

  单独定义

  继承2

class 猫:

    def 喵喵叫(self):
print('喵喵叫') def 吃(self):
pass def 喝(self):
pass def 拉(self):
pass def 撒(self):
pass class 狗: def 汪汪叫(self):
print('汪汪叫') def 吃(self):
pass def 喝(self):
pass def 拉(self):
pass def 撒(self):
pass

   定义一个动物父类用于继承

   继承3.py 

class 动物:
def 吃(self):
pass def 喝(self):
pass def 拉(self):
pass def 撒(self):
pass class 猫(动物): def 喵喵叫(self):
print('喵喵叫') class 狗(动物): def 汪汪叫(self):
print('汪汪叫')

  概念:继承和衍生

  子类继承了父类的方法,子类衍生出自己的方法

  以上的代码实现

  继承4.py

class Animal:
def eat(self):
print('%s 吃' %self.name) def drink(self):
print('%s 喝' %self.name) def shit(self):
print('%s 拉' %self.name) def pee(self):
print('%s 撒' %self.name) class Cat(Animal):
def __init__(self,name):
self.name=name
self.breed='猫' def cry(self):
print('喵喵叫') class Dog(Animal):
def __init__(self, name):
self.name = name
self.breed = '狗' def cry(self):
print('汪汪叫') # ######## 执行 ########
c1=Cat('小白家的小黑猫')
c1.eat()
#小白家的小黑猫 吃 c2=Cat('小黑家的小白猫')
c2.drink()
#小黑家的小白猫 喝

  继承同时具有两种含义

  含义一,继承基类的方法,并且做出自己的改变或者扩展(代码重用)

  含义二,声明某个子类兼容于某基类,定义一个接口类,子类继承接口类,并且实现接口中定义的方法

  接口继承.py

import abc
#接口继承定义的方式与普通的有不同看以下代码
class All_file(metaclass=abc.ABCMeta):
@abc.abstractmethod
def read(self):
pass @abc.abstractmethod
def write(self):
pass class Disk(All_file):
def read(self):
print('disk read') def write(self):
print('disk write') class Cdrom(All_file):
def read(self):
print('cdrom read') def write(self):
print('cdrom write') class Mem(All_file):
def read(self):
print('mem read') def write(self):
print('mem write') m1=Mem()
m1.read()
#mem read
m1.write()
#mem write

  接口继承需要在子类中分别定义父类中有的方法,并且必须定义,否则调用的时候报错

  PS:接口基类只是一个规范,不需要实例化

  

  继承顺序

  按如下图示写继承

  继承顺序.py

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()
print(F.__mro__)
#(<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

  对于定义的每一个类,python会计算出一个方法解析顺序(MRO)列表

  MRO列表遵循如下三条准则

  •   子类会先于父类被检查
  •   多个父类会根据他们在列表中的顺序被检查
  •   如果对下一个类存在两个合法的选择,选择第一个父类

  

  在子类中调用父类的方法

  在子类中调用父类的方法.py

#定义交通工具类
class Vehicle:
Country='China'
def __init__(self,name,speed,load,power):
self.name=name
self.speed=speed
self.load=load
self.power=power def run(self):
print('开动了...') #定义地铁类
class Subway(Vehicle):
def __init__(self,name,speed,load,power,line):
# self.name=name
# self.speed = speed
# self.load = load
# self.power = power
#减少代码重复在子类中调用父类的方法
#需要和父类中一样传递对应参数
Vehicle.__init__(self,name,speed,load,power)
self.line = line
def show_info(self):
print(self.name,self.line) def run(self):
Vehicle.run(self)
print('%s %s 线,开动了'%(self.name,self.line))
line13=Subway('北京地铁','10km/s',100000000,'电',13)
line13.show_info()
line13.run()

    PS:在子类中调用父类为了减少代码重复可以使用以上方法,多余的参数再另外定义    

    假如父类名称有变改,可以使用super方法

    super方法的使用.py

#定义交通工具类
class Vehicle:
Country='China'
def __init__(self,name,speed,load,power):
self.name=name
self.speed=speed
self.load=load
self.power=power def run(self):
print('开动了...') #定义地铁类
class Subway(Vehicle):
def __init__(self,name,speed,load,power,line):
#Vehicle.__init__(self,name,speed,load,power)
#使用super方法代替以上方法,不需要写父类名
#不需要传递参数self
super().__init__(name,speed,load,power)
self.line = line
def show_info(self):
print(self.name,self.line) def run(self):
#Vehicle.run(self)
super().run()
print('%s %s 线,开动了'%(self.name,self.line))
line13=Subway('北京地铁','10km/s',100000000,'电',13)
line13.show_info()
line13.run()

   

  2,多态

  多态1

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()
#[蒸汽]温度太高变成了水蒸气 #改成一个函数形式
def func(obj):
obj.turn_ice() func(w1)
func(i1)
func(s1)

  3,封装

  封装1.py

class People:
#前面加_代表私有属性或者私有方法
_star='earth'
def __init__(self,id,name,age,salary):
self.id=id
self.name=name
self._age=age
self._salary=salary def _get_id(self):
print('我是私有方法,我找到的id是[%s]' %self.id) print(People._star)
p1=People('362426199001011111','zhangsan',18,10) print(p1._age,p1._salary)
p1._get_id()

  以上只是加了一个_进行封装

  封装2.py

class People:
#前面加_代表私有属性或者私有方法
__star='earth'
def __init__(self,id,name,age,salary):
self.id=id
self.name=name
self._age=age
self._salary=salary def _get_id(self):
print('我是私有方法,我找到的id是[%s]' %self.id) #print(People._star)
p1=People('362426199001011111','zhangsan',18,10) print(p1._age,p1._salary)
p1._get_id()
#加两个_的需要通过类名来调用
print(p1._People__star)

  封装属性虽然可以在外部使用方法调用但是一般不这样调用,可以在内部定义接口函数来访问内部的私有变量 

  这种封装才是真正意义的封装

  封装3.py

class Room:
def __init__(self,name,owner,width,length,high):
self.name=name
self.owner=owner
self.__width=width
self.__length=length
self.__high=high #在内部定义函数可以访问私有变量计算面积
#该函数是接口函数
def tell_arer(self):
return self.__width * self.__length #如果在编写程序之初就被封装了,但是在使用过程中被频繁调用
#可能需要再另外开接口函数来放开
#所以在设计之初就要确定哪些参数需要隐藏
def tell_width(self):
return self.__width r1 = Room('卫生间','zhangsan',100,100,10000) area=r1.tell_arer()
print(area)

  

  面向对象概念总结

  面向对象是一种更高级的结构化编程方式,它的好处就两点

  1,通过封装明确了内外

  2,通过继承+多态在语言层面支持了归一化设计

Python全栈day24-25(面向对象编程)的更多相关文章

  1. Python全栈day24(面向对象编程作业作业_定义学校老师课程班级学生类)

    面向对象作业 作业_定义学校老师课程班级学生类.py #面向对象编程作业,定义学校老师课程班级学生类 #定义几个类,尽可能定义多的数据属性及函数属性 class School: def __init_ ...

  2. Python全栈开发【面向对象】

    Python全栈开发[面向对象] 本节内容: 三大编程范式 面向对象设计与面向对象编程 类和对象 静态属性.类方法.静态方法 类组合 继承 多态 封装 三大编程范式 三大编程范式: 1.面向过程编程 ...

  3. Python全栈【Socket网络编程】

    Python全栈[socket网络编程] 本章内容: Socket 基于TCP的套接字 基于UDP的套接字 TCP粘包 SocketServer 模块(ThreadingTCPServer源码剖析) ...

  4. Python全栈开发【面向对象进阶】

    Python全栈开发[面向对象进阶] 本节内容: isinstance(obj,cls)和issubclass(sub,super) 反射 __setattr__,__delattr__,__geta ...

  5. Python全栈day26-27(面向对象进阶)

    参考 http://www.cnblogs.com/linhaifeng/articles/6204014.html 1,什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访 ...

  6. Python全栈工程师(面向对象)

    ParisGabriel                每天坚持手写  一天一篇  决定坚持几年 为了梦想为了信仰    开局一张图 Python人工智能从入门到精通 day16补充: 异常处理 文件 ...

  7. Python 全栈开发七 面向对象

    一.编程范式 编程是程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程 , 一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,正所谓条条大路通罗马,实现一个任务的方式 ...

  8. python全栈开发 * 23 面向对象 知识点汇总 * 180704

    23 面向对象 -----特殊方法 1. isinstance(obj,类名) 判断对象是否是此类实例化或者此类的子类实例化出来的class A:passclass B(A):passb1=B()pr ...

  9. python全栈开发 * 22 面向对象 知识点汇总 * 180703

    22 面向对象 -----属性,类方法,静态方法,反射一.属性1.属性的定义:将方法伪装成属性,虽然在代码层面上没有任何高深之处,但让其看起来更合理. (类似于属性的方法)class Person: ...

随机推荐

  1. Mac Xcode下配置OpenGL

    暂时搁置一下iOS,又要去弄一些杂七杂八的东西了,毕竟是学校的作业,还是要完成的. 作业是让我们用OpenGL做一个茶壶- -.而且要三维立体能旋转的那种. 好吧这些都不是重点,重点是我最终决定在Ma ...

  2. mysql导入慢

    MySQL导出的SQL语句在导入时有可能会非常非常慢,经历过导入仅45万条记录,竟用了近3个小时.在导出时合理使用几个参数,可以大大加快导 入的速度. -e 使用包括几个VALUES列表的多行INSE ...

  3. C 语言 mmap

    /* *@author cody *@date 2014-08-12 *@description */ /* #include <sys/mman.h> void *mmap(void * ...

  4. 面试、笔试中常用的SQL语句(数据库知识必杀)一共50个!!!

    Student(S#,Sname,Sage,Ssex) 学生表  Course(C#,Cname,T#) 课程表  SC(S#,C#,score) 成绩表  Teacher(T#,Tname) 教师表 ...

  5. flex 伸缩盒子

    flex 的学习地址: http://caibaojian.com/demo/flexbox/align-content.html

  6. redis 服务相关

    一 什么是redis Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开 ...

  7. 0046 @Transactional注解的几个参数--事务传播控制--事务隔离级别--异常与回滚

    @Transactianal注解有一些属性,见Spring-Framework-Reference Table17.3 Transactional-settings @Transactional(pr ...

  8. CCNA2.0笔记_ipv6的EIGRP

    IPv6的eigrp特征: 邻居发现 增量更新 快速收敛 负载均衡 三个表 -邻居表 -拓扑表 -路由表 配置ipv6的eigrp Router(config)#ipv6 unicast-routin ...

  9. UITextField/UITextView限制字数

    一,UITextFild限制字数(三步) 1,给textfild添加响应事件,类型为:UIControlEventEditingChanged [self.nickNameFild addTarget ...

  10. 获取真实的IE版本(转)

    IE 的浏览器模式和文本模式(二) 发表于 2013-09-07 Author: Jerry Qu 文章目录 判断真正的 IE 版本 JScript 引擎版本号 文本模式对 JScript 没影响? ...