python3.x 基础六:面向对象
面向对象特性
- class 类
一个类是对一类拥有相同属性的对象的描述,在类中定义了这些对象都具备的属性/共同方法
- object对象
一个对象指一个类实例化后的实例,一个类必须经过实例化后才能在程序中调用,一个类可以实例化多个对象,每个对象也可以有不同的属性
- Encapsulation封装
在类中对数据的赋值/内部调用对外部用户是透明的,这使得类成为一个胶囊或者容器,里面包含着类的数据和方法
- Inheritance继承
一个类可以派生出子类,在这个父类里面定义的属性/方法自动被子类继承
- Polymorphism多态
多态是面向对象的重要特性,表现为:一个接口,多种实现,指一个基类(父类)中派生出了不同的子类,且每个子类在继承了同样的方法名的同时有队父类的方法做了不同的实现
变成其实就是一个将具体世界进行抽象化的过程,多态就是抽象化的一种体现,把一系列具体事物的共同点抽象出来,再通过这个抽象的事物,与其他不同的具体事物进行对话
多态允许将子类的对象当做父类的对象使用,某父类型的引用只想其子类型的对象,调用的方法是该子类的方法。这里引用和调用方法的代码在编译前就已经决定了,而引用所指向的对象可以在运行期间动态绑定
类的定义
- # /usr/bin/env python
- # -*- coding: utf-8 -*-
- # Author:Jenvid.yang
- class dog(object):
- nationality = 'CN' # 这是公有属性,在类里直接定义的属性
- def __init__(self,name): # 构造函数、构造方法、个初始化方法
- self.NAME = name # 这是属性、成员变量
- self.__life_value=100 # 这是私有属性,只能在类的内部中访问,外部无法直接调用
- def sayhi(self): # 类的方法,self是把实例本身传进来 这是方法、动态属性
- print('hello, my name is ', self.NAME)
- def get_life_value(self):
- return self.__life_value #将私有属性通过函数返回方法暴露给外界,达到只能查看不能更改效果
- d1=dog('wangcai') # 实例化类,类的实例,self也就相当于实例本身
- # 1.相当于dog(d1,'wangcai')
- # 2.d1传给了init的self
- # 3.self.NAME等同于d1.NAME self.NAME=d1.NAME
- d1.sayhi()
- # 4.相当于d1.sayhi(d1),d1传给了sayhi的self
- # 5.之前d1.NAME已经赋值,此时相当于将赋值后的d1传给了sayhi的self,self里保存了NAME变量
- # 6.最后的self.NAME相当于d1.NAME
- d1.nationality='US' #通过实例更改自己的属性,但是默认值预先存在于内存中,仅仅进行引用,重新赋值后在本地占用新一块内存存储
- dog.nationality='US' #通过类名更改全局属性
d1._dog__life_value #强制访问私有属性 实例名._类名__私有属性名
def sayhi(self)
print('goodbye',self.name)
d1.sayhi=sayhi
d1.sayhi(d1) # 重写公有方法
理解:self 实例 私有属性 公有属性 引用 重写公有方法
- class Role(object):
- def __init__(self,name,role,weapon,life_value=100,money=15000):
- self.name = name
- self.role = role
- self.weapon = weapon
- self.life_value = life_value
- self.money = money
- def shot(self):
- print('%s is shooting...'% self.name)
- def got_shot(self):
- print('i got shot...SOS')
- def buy_gun(self,gun_name):
- print("%s had buy gun %s" %(self.name,gun_name))
- r1=Role('alex','policeman','b46')
- r2=Role('oldboy','terrise','B22')
- r1.shot()
- r2.got_shot()
- r2.buy_gun('b51')
- def buy_gun1(self):
- print("%s had buy gun xxx" %(self.name))
- r2.buy_gun=buy_gun1
- r2.buy_gun(r2)
- alex is shooting...
- i got shot...SOS
- oldboy had buy gun b51
- oldboy had buy gun xxx
课堂源码
析构方法
- def __del__(self):
- print('del is running ..')
- #只要数据(引用关系)被清空,就会执行
继承
- 实现继承,使用基类的属性和方法而无需额外编码的能力
- 接口继承,仅使用属性和方法的名称,但是子类必须提供实现的能力,子类重构父类方法
1.继承父类
- class Persion(object):
- def talk(self):
- print("persion is talking")
- class BlackPersion(Persion):
- def walk(self):
- print('black persion is walking..')
- b=BlackPersion()
- b.walk()
- b.talk()
- output:
- black persion is walking..
- persion is talkin
2.重写父类方法
- class Persion(object):
- def talk(self):
- print("persion is talking")
- class BlackPersion(Persion):
- def talk(self):
- print("speak balalala")
- def walk(self):
- print('black persion is walking..')
- b=BlackPersion()
- b.walk()
- b.talk()
- output:
- black persion is walking..
- speak balalal
3.父类带有构造函数
- class Persion(object):
- def __init__(self,name,age):
- self.name=name
- self.age=age
- def talk(self):
- print("persion is talking")
- class WhitePersion(Persion):
- pass
- class BlackPersion(Persion):
- def talk(self):
- print("speak balalala")
- def walk(self):
- print('black persion is walking..')
- b=BlackPersion('blackone',30) # 1. 如果子类没有自己的构造函数,将调用父类构造函数,否则报错,因此实例化时要传入实参
- b.walk()
- b.talk()
- output:
- black persion is walking..
- speak balalala
4.子类有自己的构造函数并且有新的属性
- # /usr/bin/env python
- # -*- coding: utf-8 -*-
- # Author:Jenvid.yang
- class Persion(object):
- def __init__(self,name,age):
- self.name=name
- self.age=age
- self.plant='earth'
- def talk(self):
- print("persion is talking")
- class WhitePersion(Persion):
- pass
- class BlackPersion(Persion):
- def __init__(self,name,age,strength): # 2.先继承,后重构,增加子类自己的属性
- Persion.__init__(self,name,age) # 3.调用父类构造函数,将子类的self,name,age传给父类,获取父类原有的属性
- print(self.name,self.age,self.plant)
- self.strength=strength
- def talk(self):
- Persion.talk(self) # 4.调用父类方法,没用,不这么干,一般只是调用父类构造函数
- print("speak balalala")
- def walk(self):
- print('black persion is walking..')
- b=BlackPersion('blackone',30,'strong') # 1. 如果子类传参,并且没有自己的构造函数,将调用父类构造函数,否则报错
- b.walk()
- b.talk()
- output:
- blackone 30 earth
- black persion is walking..
- speak balalala
5.课堂类继承例子
- #/usr/bin/env python
- #-*- coding: utf-8 -*-
- #Author:jenvid.yang
- class SchoolMember(object):
- '''学校父类'''
- member = 0
- def __init__(self,name,age,sex):
- self.name=name
- self.age=age
- self.sex=sex
- self.enroll() # 每次实例化对象的时候调用一次
- def enroll(self):
- '''注册'''
- print("%s just enrolled a new shcool member"%self.name)
- SchoolMember.member+=1 # 全局加1
- def tell(self):
- for k,v in self.__dict__.items(): # 用__dict__方法遍历不同实例的属性
- print(k,v)
- def __del__(self):
- print('删除%s'%self.name) # 垃圾回收,程序结束的时候也会自动执行
- SchoolMember.member-=1
- class Teacher(SchoolMember):
- '''讲师类'''
- def __init__(self,name,age,sex,salary,course): # 扩展自己的属性
- SchoolMember.__init__(self,name,age,sex) #继承父类属性 # 经典类写法
#super(Teacher,self).__init__(name,age,sex) # 新式类写法- self.salary=salary
- self.course=course
- def teaching(self):
- print("teacher %s is teaching course %s" %(self.name,self.course))
- class Studen(SchoolMember):
- '''学生类'''
- def __init__(self,name,age,sex,course,tution):
- SchoolMember.__init__(self,name,age,sex)
- self.course=course
- self.tution=tution
- self.amount=0
- def pay_tutition(self,amount):
- print("student %s has just paied %s" %(self.name,self.amount))
- self.amount+=amount
- t1 = Teacher('alex',18,'M',3000,'py')
- print(SchoolMember.member)
- # print(t1.__dict__)
- s1 = Studen('stu1',18,'F','py',3000)
- print(SchoolMember.member)
- s2 = Studen('stu2',18,'M','lnx',4000)
- print(SchoolMember.member)
- t1.tell()
- s1.tell()
- del s1
- print(SchoolMember.member)
- alex just enrolled a new shcool member
- 1
- {'name': 'alex', 'course': 'py', 'salary': 3000, 'sex': 'M', 'age': 18}
- stu1 just enrolled a new shcool member
- 2
- stu2 just enrolled a new shcool member
- 3
- name alex
- course py
- salary 3000
- sex M
- age 18
- amount 0
- name stu1
- course py
- tution 3000
- sex F
- age 18
- 删除stu1
- 2
- 删除stu2
- 删除alex
输出结果
经典类与新式类
新式类:
- 定义语法:
- class 类名(object):
- 继承父类构造函数语法
- super(父类名.self).__init__(变量1,2..)
经典类
- 定义语法:
- class 类名:
- 继承父类构造函数语法
- 类名.__init__(self,变量1,2..)
多继承
3.0是广度继承路径
2.0新式继承是广度路径,经典继承是纵向路径
什么时候使用面向对象编程
- 如果存在多个函数需要传入多个共同的参数时
- 根据一个模板创建多个东西
- 重复方法封装起来
self--就是当前调用方法的对象
静态字段使用场景,每个对象中保存相同的东西时,可以使用静态字段
封装--
类中封装了字段/方法
对象中封装了普通字段的值
对象中封装对象,再封装对象
- class F1:
- def __init__(self,n):
- self.N=n
- print('F1')
- class F2:
- def __init__(self,arg1):
- self.a=arg1
- print('F2')
- class F3:
- def __init__(self,arg2):
- self.b=arg2
- print('F3')
- o1=F1('alex') # 4.o3.b.a=F1('alex') 5.self==o3.b.a 6. alex==o3.b.a.N
- o2=F2(o1) # 2.arg1==o1 o2.a==o1 3. o3.b.a==o1
- o3=F3(o2) # 1.arg2==o2 o3.b==o2
- #通过o3如何输出alex
- #o3=F3(F2(o1) == F3(F2(F1('alex')))
- print(o3.b.a.N)
继承注意:
- class F1:
- def __init__(self):
- print('F1')
- def a1(self):
- print('F1a1')
- def a2(self):
- print('F1a2')
- class F2(F1):
- def __init__(self):
- print('F2')
- def a1(self):
- self.a2()
- print('F2a1')
- def a2(self):
- print('F2a2')
- class F3(F2):
- def __init__(self):
- print('F3')
- def a2(self):
- print('F3a2')
- # def a1(self):
- # print('F3a1')
- obj=F3()
- obj.a1()
- # 1.实例化F3,调用F3中的a1方法
- # 2.F3中没有a1方法,到父类F2中找到a1方法
- # 3.self.a2()方法回到类F3中调用自己的a2,打印F3a2,self代表的是obj,因此回到F3找
- # 4.打印F2中的F2a1
直接调用类中的方法:
字段:
普通字段-保存在对象中
静态字段-保存在类中
方法:
普通方法-保存在类中,调用者是对象
- class F1:
- def __init__(self,name):
- self.name=name
- def a1(self):
- print(self.name)
- obj=F1('alex')
- obj.a1()
- class F1:
- def a1(self):
- print('alex')
- obj=F1()
- obj.a1()
- # 没有封装任何东西,会浪费内存空间,使用静态方法
- #静态方法,可以有任意个参数
- #完成函数一样的功能
- #调用这是类(无需创建对象)
- class F1:
- @staticmethod
- def a1():
- print('alex')
- F1.a1()
python3.x 基础六:面向对象的更多相关文章
- Python 基础 四 面向对象杂谈
Python 基础 四 面向对象杂谈 一.isinstance(obj,cls) 与issubcalss(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls ...
- 自学Python之路-Python基础+模块+面向对象+函数
自学Python之路-Python基础+模块+面向对象+函数 自学Python之路[第一回]:初识Python 1.1 自学Python1.1-简介 1.2 自学Python1.2-环境的 ...
- (转)Python成长之路【第九篇】:Python基础之面向对象
一.三大编程范式 正本清源一:有人说,函数式编程就是用函数编程-->错误1 编程范式即编程的方法论,标识一种编程风格 大家学习了基本的Python语法后,大家就可以写Python代码了,然后每个 ...
- 从零开始学习PYTHON3讲义(六)for循环跟斐波那契数列
<从零开始PYTHON3>第六讲 几乎但凡接触过一点编程的人都知道for循环,在大多数语言的学习中,这也是第一个要学习的循环模式. 但是在Python中,我们把for循环放到了while循 ...
- Java基础-初识面向对象编程(Object-Oriented-Programming)
Java基础-初识面向对象编程(Object-Oriented-Programming) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Java是一门面向对象的程序设计语言.那么什 ...
- python基础,函数,面向对象,模块练习
---恢复内容开始--- python基础,函数,面向对象,模块练习 1,简述python中基本数据类型中表示False的数据有哪些? # [] {} () None 0 2,位和字节的关系? # ...
- Bootstrap<基础六> 表单
Bootstrap 通过一些简单的 HTML 标签和扩展的类即可创建出不同样式的表单. 表单布局 Bootstrap 提供了下列类型的表单布局: 垂直表单(默认) 内联表单 水平表单 垂直或基本表单 ...
- [.net 面向对象编程基础] (11) 面向对象三大特性——封装
[.net 面向对象编程基础] (11) 面向对象三大特性——封装 我们的课题是面向对象编程,前面主要介绍了面向对象的基础知识,而从这里开始才是面向对象的核心部分,即 面向对象的三大特性:封装.继承. ...
- [.net 面向对象编程基础] (12) 面向对象三大特性——继承
[.net 面向对象编程基础] (12) 面向对象三大特性——继承 上节我们说了面向对象的三大特性之一的封装,解决了将对同一对象所能操作的所有信息放在一起,实现统一对外调用,实现了同一对象的复用,降低 ...
随机推荐
- 文件上传漏洞(pikachu)
文件上传漏洞 文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像,附件等等.当用户点击上传按钮后,后台会对上传的文件进行判断,比如是否是指定的类型.后缀名.大小等等,然后将其按照设 ...
- (转)如何学好C++语言
原文:http://coolshell.cn/articles/4119.html 作者:陈皓 昨天写了一篇如何学好C语言,就有人回复问我如何学好C++,所以,我把我个人的一些学习经验写在这里,希 ...
- mysql不同端口的连接
连接mysql3306端口命令 mysql -h58.64.217.120 -ushop -p123456 连接非3306端口(指定其他端口) 的命令 mysql -h58.64.217.120 -P ...
- 刚听完CSDN总裁蒋涛先生的学术报告
主题: 二十年程序人生和我的人才观 第一次参加所谓的"学术报告", 但感觉更多的是蒋总在跟我们分享他个人的成长经验. 按蒋总的话说, 他已经从2000年开始不碰怎么技术了, 所以个 ...
- Web全栈AngularJS
百度云盘下载 AngularJS是人类首个大规模使用的MVC框架,能够帮助程序员将绝大部分精力集中在核心业务逻辑上,从而大幅提高开发效率. 阶段2:Controller Controller是Angu ...
- webpack4.x下babel的安装、配置及使用
前言 目前,ES6(ES2015)这样的语法已经得到很大规模的应用,它具有更加简洁.功能更加强大的特点,实际项目中很可能会使用采用了ES6语法的模块,但浏览器对于ES6语法的支持并不完善.为了实现兼容 ...
- Longest XXX
Longest Common Substring Brute Force 遍历a和b所有位置的组合,向后延伸,直到遇到两个不同的字符,复杂度是\(n^3\)级别. class Solution { p ...
- HDU2937 YAPTCHA(威尔逊定理)
YAPTCHA Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...
- Kafka平滑滚动升级2.4.0指南
今天测试了下kafka从2.0.0滚动升级至2.4.0,下面做一下记录.这个链接是Kafka官网对升级2.4.0的指南,可以参考 http://kafka.apache.org/24/documen ...
- C/S程序设计范式
在socket编程之并发回射服务器3篇文章中,提到了3种设计范式: 多进程 父进程阻塞于accept调用,然后为每个连接创建一个子进程. 多线程 主线程阻塞于accept调用,然后为每个连接创建一个子 ...