Day 18 :面向对象[基础,继承,组合]类的增删改查
有的人说,编程有3种范式:
1、面向过程:就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
2、面向函数:面向函数是面向过程的升级版,也就是把每个解决问题的代码写成一个函数,需要的时候调用函数就好了
3、面向对象:把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
面向对象编程:是利用“类”和“对象”来创建各种模型来实现对真实世界的描述,使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容
面向对象5个特性:
1、Class类:一个类即是一类拥有相同属性的对象的描述,在类中定义了这些对象的都具备的属性(variables(data))、共同的方法(函数)。
2、Object对象:一个对象即是对一个类实例化的后的实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性,就像人类是指所有人,每个人是指具体的对象,每个人都有相同点,又有不同点。
3、Encapsulation 封装:在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法
4、Inheritance 继承:一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承、
5、Polymorphism 多态:多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,指一个基类中派生出了不同的子类,且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态
在说类之前,我们先用函数写个代码:
我们要实现类似面向对象的一个代码:【把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。】
- #写面向对象之前,先将个别的
- #我们定义个妈妈的函数,
- #特征:名字,身高,体重(一般写面向对象的时候,想到他们有什么数据,有什么动作)
- #动作:会做饭,唠叨
- def Mom(name,height,weight):
- def init(name,height,weight):#这个相当于初始化函数
- xian_mom = {
- "name":name,
- "height":height,
- "weight":weight,
- "cook_dinner":cook_dinner#把动作和初始化函数相关联
- }
- #把所有的特征写进一个函数,然后返回这个函数
- return xian_mom
- def cook_dinner(xian_mom):#妈妈的动作
- print(" %s 今天做个,蛋糕" % (xian_mom['name']))
- return init(name,height,weight)#给函数返回这个函数
- obj = Mom("xfd","165cm","52kg")#给函数传入参数
- print(obj)#obj是个字典
- #{'name': 'xfb', 'height': '164cm', 'weight': '58kg',
- # 'cook_dinner': <function Mom.<locals>.cook_dinner at 0x000001CD5D4F3598>}
- print(obj['name'])
- #xfd
那上面我们完成了这个函数,但是调用妈妈这个会做饭的动作,怎么调用呢?
- print(obj["cook_dinner"])
- #返回了一个对象,缺少一个参数<function Mom.<locals>.cook_dinner at 0x0000023635E93950>
- print(obj["cook_dinner"](obj))#把自己传进去【动作和初始化函数绑定了】
- # xfd 今天做个,蛋糕
- #None
上面函数返回了个none 因为cook_dinner这个函数没有返回值,是打印出来的
那我们把函数的数据都结构化了,现在就可以写我们的面向对象的代码了。
- # 一个类里面一般都有2个属性
- # 1、数据属性:也就是变量
- # 2、函数属性:也就是函数,在面向对象里面叫方法
- # 类的数据属性,和函数属性都用用【。】的方式来运行
- class Mom:#类名 :一般首字母是大写,或者使用驼峰式
- '这是一个妈妈类' #类的描述文档
- gender = "woman" #妈妈都有个共同的属性,那就是女性咯
- #这里一般都定义共有的属性【数据属性】
- def __init__(self,name,height,weight):
- #init方法是,只要运行函数自动加载init方法
- self.name = name
- self.height = height
- self.weight = weight
- #这样写就相当于我们定义了一个数据属性字典
- def cook_dinner(self):
- #self: obj["cook_dinner"](obj) 就相当于把自己传入进去
- print(" %s 今天做个,蛋糕" % (self.name))
- print(Mom.__dict__)#查看类的属性字典包含数据属性和函数属性的字典
- #{'__module__': '__main__', '__doc__': '这是一个妈妈类',
- # 'gender': 'woman', '__init__': <function Mom.__init__ at 0x0000019C233D39D8>,
- # 'cook_dinner': <function Mom.cook_dinner at 0x0000019C233D3950>,
- # '__dict__': <attribute '__dict__' of 'Mom' objects>,
- # '__weakref__': <attribute '__weakref__' of 'Mom' objects>}
- #是不是感觉上面的是个字典?
- #怎么取出gender的值呢?
- print(Mom.__dict__["gender"])#woman
- obj = Mom("xfd","165cm","52kg")#实例化,产生对象
- print(obj.__dict__)#这个查看你额类里面包含哪些字典
- #{'name': 'xfd', 'height': '165cm', 'weight': '52kg'}
- obj.cook_dinner()
- # xfd 今天做个,蛋糕
类属性的增删改查
- class Mom:
- gender = "woman"
- def __init__(self,name):
- self.name = name
- def cook_dinner(self):
- print(" %s 今天做个,蛋糕" % (self.name))
- #查询类有那些属性(数据属性,函数属性)
- print(Mom.__dict__)
- print(Mom.__dir__)
- #查询gender的值
- print(Mom.gender)#woman
- #修改类数据属性
- Mom.gender = 'man'
- #增加类的数据属性
- Mom.hair = 'curly hair'
- #删除类数据属性
- del Mom.gender
- #函数属性的增删改查是上面的一样
- #增加函数属性
- def lao_dao(self):
- print("%s 这么还不起床" %self.name)
- Mom.laodao = lao_dao#不能带括号,不然执行了
- #'laodao': <function lao_dao at 0x00000266CE11C268>}
- #查询函数属性
- m1= Mom("sjc")
- m1.laodao()#增加的函数属性可以调用
- #修改 cook_dinner
- def cook(self):
- print('今天不听话,不给做饭')
- Mom.cook_dinner = cook#重新赋值
- m1.cook_dinner()#今天不听话,不给做饭
实例的增删改查
- class Mom:
- gender = "woman"
- def __init__(self,name):
- self.name = name
- def cook_dinner(self):
- print(" %s 今天做个,蛋糕" % (self.name))
- #生成实例
- m1 = Mom('sjc')
- #查看实例的属性字典
- print(m1.__dict__)#{'name': 'sjc'}
- #查看
- print(m1.name)#sjc
- print(m1.cook_dinner)#<bound method Mom.cook_dinner of <__main__.Mom object at 0x00000264ED9B8400>>
- print(m1.cook_dinner())#自己没有访问类的
- #增加
- m1.age = 28
- #删除
- del m1.age
- #实例化的过程,就是执行init方法
实例增删改查
类的继承
1、单继承于多继承
- class Father:
- money = 1000
- def __init__(self,name):
- self.name = name
- print('执行了Father')
- def Make_Money(self):
- print("%s 正在给儿子挣钱" % self.name)
- class Son(Father):#这是单继承,多继承就是, class Son(Father,Mom)
- pass
- # print(Son.money)#输出1000 ,儿子可以调用爸爸的类的数据属性
- # Son.Make_Money()#可以调用,但是报错
- print(Father.__dict__)
- print(Son.__dict__)#{'__module__': '__main__', '__doc__': None}没有方法是这么调用的呢?
- ret = Son("sjc")#输出:执行了Father(由于继承的关系执行了Father的init方法)
- print(ret.name)#输出:sjc
- print(ret.money)#输出:1000
- ret.Make_Money()#输出sjc 正在给儿子挣钱
- #结果显示继承关系中,儿子不仅可以调用类的数据属性,也可以调用类的方法
2、如果儿子属性和爸爸属性重名了呢?
- class Father:
- money = 1000
- def __init__(self,name):
- self.name = name
- print('执行了Father')
- def Make_Money(self):
- print("%s 正在给儿子挣钱" % self.name)
- class Son(Father):
- money = 5000
- def __init__(self,name,age):
- self.name = name
- self.age = age
- def Make_Money(self):
- print('执行儿子方法 %s' % self.age)
- print(Son.money)#5000 ,子类和父类的数据重名了,那优先找自己,不是覆盖
- ret = Son("jsc",'')
- ret.Make_Money()#输出:执行儿子方法 3,方法也是用自己,没有被覆盖,
什么时候用继承呢?代码如果大量重复的时候可以使用继承
- 猫可以:喵喵叫、吃、喝、拉、撒
- 狗可以:汪汪叫、吃、喝、拉、撒
- 如果我们要分别为猫和狗创建一个类,那么就需要为猫/狗
- 实现他们所有的功能,伪代码如下:
- # 猫和狗有大量相同的内容
- class 猫:
- def 喵喵叫(self):
- '喵喵叫'
- def 吃(self):
- # do something
- def 喝(self):
- # do something
- def 拉(self):
- # do something
- def 撒(self):
- # do something
- class 狗:
- def 汪汪叫(self):
- '喵喵叫'
- def 吃(self):
- # do something
- def 喝(self):
- # do something
- def 拉(self):
- # do something
- def 撒(self):
- # do something
伪代码
使用继承
- 上述代码不难看出,吃、喝、拉、撒是猫和狗都具有的功能,而我们却分别的猫和狗的类中编写了两次。
- 如果使用继承的思想,如下实现:
- 动物:吃、喝、拉、撒
- 猫:喵喵叫(猫继承动物的功能)
- 狗:汪汪叫(狗继承动物的功能)
- 伪代码如下:
- class 动物:
- def 吃(self):
- # do something
- def 喝(self):
- # do something
- def 拉(self):
- # do something
- def 撒(self):
- # 在类后面括号中写入另外一个类名,表示当前类继承另外一个类
- class 猫(动物):
- def 喵喵叫(self):
- '喵喵叫'
- # 在类后面括号中写入另外一个类名,表示当前类继承另外一个类
- class 狗(动物):
- def 汪汪叫(self):
- '汪汪叫'
伪代码
(1)派升:比如上述代码中,现在动物类里面只有“吃喝拉撒”,但是子类里面,定义了父类没有的 “喵喵叫” 这就是派升。 父类无,子类有了,那这就是派升了。
注意:以上方法就是个例子,但是现实中,少用,因为这种方式把2个程序耦合起来了。一般设计程序的时候,需要程序经量解耦。
(2)接口继承
例:比如我们要写一个程序,这个程序必须要有读与写得功能。(比如,硬盘,光盘,都有读写功能),但是硬盘的读写和光盘的读写的方法是不一样的。
- import abc
- #导入这个模块来限制,不然就无法限制
- class All_file(metaclass=abc.ABCMeta):#metaclass 记得这个
- #我们限制所有的文件都有一个读和写得方法
- #定义一个父类,规定所有的子类必须实现父类的功能,这就是接口继承
- #父类不实现此方法,但是子类必须实现。
- @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')
- m1=Cdrom()
- m1.read()
- m1.write()
例
类的继承顺序
python3 类都是新式类,所以都是按照广度优先
在子类里面怎么调用父类的方法
- 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('开动啦')
- print('开动啦')
- #父类正常定义
- class Subway(Vehicle):#地铁
- def __init__(self,name,speed,load,power,line):#派升下,多一个参数
- Vehicle.__init__(self.name,speed,load,power)
- #实例化和对象的才会自动传参的时候,这里不是实例化,或者对象,所以要写self.传的是子类的
- #在定义子类的时候,要把父类的init方法在放置在子类加载
- self.line=line
- def show_info(self):#
- print(self.name,self.speed,self.load,self.power,self.line)
- def run(self):
- Vehicle.run(self)#调用父类的run方法
- print('%s %s 线,开动啦' %(self.name,self.line))
- line1=Subway('西安地铁','10km/s',888,'电',1)
- line1.show_info() #调用自己方法
- #北京地铁 10km/s 888 电 13
- line1.run()#开动啦,开动啦,西安地铁 1 线,开动啦
子类调用父类方法
上面的方法并不完美,如果因某些原因,类名变量,或者什么原因,就会导致整个子类都要修改。所有用到了super函数
- 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('开动啦')
- print('开动啦')
- #父类正常定义
- class Subway(Vehicle):#地铁
- def __init__(self,name,speed,load,power,line):
- super().__init__(name,speed,load,power)
- #用super可以调用到父类的方法
- self.line=line
- def show_info(self):#
- print(self.name,self.speed,self.load,self.power,self.line)
- def run(self):
- super().run()#调用父类的run方法 :开动啦,开动啦
- print('%s %s 线,开动啦' %(self.name,self.line))
- line1=Subway('西安地铁','10km/s',888,'电',1)
- line1.show_info() #调用自己方法
- #北京地铁 10km/s 888 电 13
- line1.run()#开动啦,开动啦,西安地铁 1 线,开动啦
Super方法
#特点,好处之一,不用传self参数,不用传类名了。
类的组合
当一个类的功能,自己没有别人有,但是他需要别的类的方法或者数据属性时,可以用组合
- class Equip: #装备
- def fire(self,name):
- print('%s 购买了暴风大剑'% name)
- class Hero: #英雄类,一个英雄需要购买装备,因而需要组合Equip类
- camp='Noxus'
- def __init__(self):
- self.equip=Equip() #用Equip类产生一个装备,赋值给实例的equip属性
- r1=Hero()
- r1.equip.fire('盖伦') #可以使用组合的类产生的对象所持有的方法
- #盖伦 购买了暴风大剑
Day 18 :面向对象[基础,继承,组合]类的增删改查的更多相关文章
- Hadoop基础-HDFS的API实现增删改查
Hadoop基础-HDFS的API实现增删改查 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客开发IDE使用的是Idea,如果没有安装Idea软件的可以去下载安装,如何安装 ...
- Vc数据库编程基础MySql数据库的表增删改查数据
Vc数据库编程基础MySql数据库的表增删改查数据 一丶表操作命令 1.查看表中所有数据 select * from 表名 2.为表中所有的字段添加数据 insert into 表名( 字段1,字段2 ...
- ES6学习笔记(三):教你用js面向对象思维来实现 tab栏增删改查功能
前两篇文章主要介绍了类和对象.类的继承,如果想了解更多理论请查阅<ES6学习笔记(一):轻松搞懂面向对象编程.类和对象>.<ES6学习笔记(二):教你玩转类的继承和类的对象>, ...
- 用泛型创建SqlServerHelper类实现增删改查(一)
使用泛型,可以构建对数据库单表的基本增删改查. 首先有一数据库 Test_SqlServerHelper ,有2表 接下来创建项目,对数据库进行增删改查. 直接贴代码:(SqlServerHelper ...
- Java数据库连接--JDBC基础知识(操作数据库:增删改查)
一.JDBC简介 JDBC是连接java应用程序和数据库之间的桥梁. 什么是JDBC? Java语言访问数据库的一种规范,是一套API. JDBC (Java Database Connectivit ...
- JDBC基础学习(一)—JDBC的增删改查
一.数据的持久化 持久化(persistence): 把数据保存到可掉电式存储设备中以供之后使用.大多数情况下,数据持久化意味着将内存中的数据保存到硬盘上加以固化,而持久化的实现过程大多通过各 ...
- python基础学习之类的属性 增删改查
类中的属性如何在类外部使用代码进行增删改查呢 增加.改变: setattr内置函数以及 __setattr__魔法方法 class A: aaa = '疏楼龙宿' a = A() setattr(a, ...
- StringBuffer类(增删改查及长度可变原理)
1 package cn.itcast.p2.stringbuffer.demo; 2 3 public class StringBufferDemo { 4 5 public static void ...
- Ado.net中简单的DBHelper类(增删改查)
private static string connString = "server=.;database=hotel;uid=aa;pwd=123";//最好从配置文件中取出 p ...
随机推荐
- freemark 语法
我们通过后端model. addAttribute() 传递到前端的值来进行界面渲染 它的循环语句 和其他的有点不同: if 循环 <#if 条件语句> </#if> if ...
- Windows 08 R2_NLB负载均衡(图文详解)
目录 目录 Load Balance 使用NLB来部署Web Farm集群 环境准备 在Win08r2pc1中配置DNS服务 在Win08r2pc1中部署File Service文件服务 在Win08 ...
- Java中深度克隆和浅度克隆
一:使用目的: 就是为了快速构造一个和已有对象相同的副本.如果需要克隆对象,一般需要先创建一个对象,然后将原对象中的数据导入到新创建的对象中去,而不用根据已有对象进行手动赋值操作. 二:Object中 ...
- python3_列表排序简介
说明:以下是以整数排列为例,其它数据类型读者自行思考即可知. 1.使用方法sort()对列表排序 使用格式:(注:说到方法,在列表中都是列表名.方法名()的使用格式,之后不在赘述.) 列表名.sort ...
- Cocos2d之运行Test项目
| 版权声明:本文为博主原创文章,未经博主允许不得转载. 1. 打开Test项目 路径为 C:\Dev\cocos2d-x-3.8.1\build 2.设定cpp-tests为启动项(当cpp ...
- 关于原生js中ie的attacheEvent事件用匿名函数改变this指向后,不能用detachEvent删除绑定事件的解决办法?
博客搬迁,给你带来的不便,敬请谅解! http://www.suanliutudousi.com/2017/11/28/%e5%85%b3%e4%ba%8e%e5%8e%9f%e7%94%9fjs%e ...
- MOV EAX,DWORD PTR SS:[EBP+8]
nasm来写可以写成mov eax,dword ptr [ebp + 8]理由:ebp和esp默认是ss段,所以根本不用显式说明. eax,ebx,ecx,edx,edi,esi默认 ...
- Codeforces New Year and Arbitrary Arrangement
New Year and Arbitrary Arrangement time limit per test2 seconds You are given three integers k, pa a ...
- Ubuntu16.04+cuda9.0安装教程
1.安装NVIDIA驱动 首先去官网(http://www.nvidia.cn/Download/index.aspx?lang=cn)查找适配自己电脑GPU的驱动,我的电脑驱动版本如下: 执行如下语 ...
- [python3]未配置locale的主机出现UnicodeDecodeError: 'ascii' codec can't decode byte 0x....的解决
之前写的发邮件的程序部署到vps的时候出现了 UnicodeDecodeError: 'ascii' codec can't decode byte 0x.... 的错误. 按理说UnicodeDec ...