python入门(十四):面向对象(属性、方法、继承、多继承)
1)属性(特征:通常可以用数据来描述)
(类变量和实例变量)
2)可以做一些动作(方法)
类来管理对象的数据。
属性:类变量和实例变量(私有变量)
方法:
1)实例方法
2)类方法
3)静态方法
有专有数据(可以存储,和对外使用)
方法(用于操作专有数据的),实现操作数据的规则。
函数:
无专有数据,谁给他传值都可以处理,并返回
本身不能存储数据。
class compute: #定义了类compute
def __init__(self,a,b):
self.a = a
self.b = b
def add(self): #方法是对输入的数进行的操作,说明已经存储
return self.a+self.b
def add(a,b): #定义了函数add()
return a+b
#print(add(1,2))
c= compute(1,2) #类具备存储的功能
print(c.add())
print(c.a) #可以查看当时输入的数据,因为已经存储
print(c.b) #可以查看当时输入的数据,因为已经存储
print(c.a+1) #可以对输入的数据进行更改
print(c.b+1) #可以对输入的数据进行更改
c.a+=1 #可以对输入的数据进行赋值
print(c.a)
c.b+=1 #可以对输入的数据进行赋值
print(c.b)
运行结果:
E:\>python a.py
3
3
1
2
2
3
2
3
把一组相关数据放到类的实例里面,进行存储、计算等实现安全性、独立性,规则的操作统一。
def __init__(self,name,gender):
self.name = name
self.gender = gender
def get_name(self):#实例方法,必须要实例化
return
self.name
print(Person.get_name()) #不能直接通过类名调用实例方法。
原因:实例方法未经过实例化,仅仅通过类名找到了调用方法,但是执行该方法时,找self的值时,没有,所以找不到实例的数据。
#print(Person("吴老师","Male").get_name())#只能使用一次(连着写,没有存到变量里,使用一次就消失了)
wulaoshi = Person("吴老师","Male") #将实例化存到一个变量中
print(wulaoshi.get_name()) #调用变量中的实例方法
count = 0 #类变量
def __init__(self,name,gender):
self.name = name
self.gender = gender
Person.count +=1
def get_name(self):#实例方法,必须要实例化
return
self.name
#类方法:可以使用类变量,不能使用实例变量(参数没有self,找不到实例的地址,因此不能用实例变量。)
def get_instance_count(cls): #类方法,cls不必非得是cls,但建议用cls
return Person.count #类方法是可通过类名,直接调用该方法
#只能使用一次
#print(Person("吴老师","Male").get_name())
#wulaoshi = Person("吴老师","Male")#实例化
#print(wulaoshi.get_name())
#print(Person.count)
#Person("吴老师","Male")
#print(Person.count)
#print(Person.get_instance_count())
可以在类方法中创建实例:
class Person:
count=0
def __init__(self,name,gender):
self.name = name
self.gender = gender
Person.count += 1
def get_name(self):
return self.name
@classmethod #装饰器
def get_instance_count(cls): #类方法
return Person.count
@classmethod
def create_a_instance(cls):
return Person("zhang","male")
print(Person.create_a_instance())
运行结果:
E:\>python a.py
<__main__.Person object at 0x0000020602080588>
count = 0 #类变量
nation = "中国"
def __init__(self,name,gender): #构造方法
self.name = name
self.gender = gender
Person.count +=1
def get_name(self):#实例方法,必须要实例化
return
self.name
@classmethod #类方法
def get_instance_count(cls):
return Person.count
@classmethod #类方法
def create_a_instance(cls):
return Person("张","女")
@staticmethod #静态方法:不需要self和cls
def get_nation():
return Person.nation
def get_more():
Person.count +=100
return Person.count
#只能使用一次
#print(Person("吴老师","Male").get_name())
#wulaoshi = Person("吴老师","Male")#实例化
#print(wulaoshi.get_name())
#print(Person.count)
#Person("吴老师","Male")
#print(Person.count)
#print(Person.get_instance_count())
#print(Person.create_a_instance())
#print(Person("吴老师","Male").get_instance_count())
print(Person.get_nation())
print(Person("吴老师","Male").get_nation()) #通过实例调用静态方法
1 实例方法,参数要有self,必须通过实例化的对象去调用。
2 类方法,要加上@classmethod来声明,参数至少有一个,
一般定义为cls,只能使用类变量,不能使用实例变量。
通过类名或者实例对象调用。
3 静态方法,要加上@staticmethod来声明,可以没有参数,
使用类变量,不能使用实例变量。
通过类名或者实例对象调用。
不想做实例化,且只操作类变量的时候:类方法、静态方法
如果想使用实例变量,只能使用实例方法了。
1) 子类没有写构造方法:
count = 0 #类变量
nation = "中国"
def __init__(self,name,gender):
self.name = name
self.gender = gender
Person.count +=1
print("创建了一个新的人")
def get_name(self):#实例方法,必须要实例化
return
self.name
class ChinaPerson(Person): #子类什么都没有干
pass #如果子类没有定义__init__构造方法,会自动调用父类的。
cp = chinaPerson()
运行结果:
E:\>python a.py
Traceback (most recent call last):
File "a.py", line 18, in <module>
cp = chinaPerson()
TypeError: __init__() missing 2 required positional arguments: 'name' and 'gender'
#如果子类没有定义构造方法,会自动调用父类的。所以实例化时,需要两个参数
print(
cp.name) #子类中,沿用了父类的nameprint(cp.gender) #子类中,沿用了父类的gender
print(cp.get_name()) #子类中,沿用了父类的方法
print(cp.count)
"""
继承:子类具备所有父类的共有变量和共有方法
如果子类没有定义__init__构造方法,会自动调用父类的。
好处:站在老爸的肩膀上,增加属性,增加方法
在原有的基础上进行扩展。
"""
2) 子类自定义构造方法
class Person:
count = 0 #count是父类的类变量
nation = "中国"
def __init__(self,name,gender):
self.name = name
self.gender = gender
Person.count+=1
print("创建了一个新的人")
def get_name(self):
return self.name
class chinaPerson(Person):
def __init__(self,name,gender): #子类自定义的构造方法
self.name = name
self.gender = gender
def get_gender(self):
return self.gender
cp = chinaPerson("laoshi","男")
print(cp.count)
运行结果:
E:\>python a.py
0
#由于子类自定义了构造方法,而Person.count+=1的语句是在父类的构造方法中,所以在执行子类的实例中,不会进行Person.count+=1,所以输出结果为0
3) 子类写明调用父类构造方法
count = 0 #类变量
nation = "中国"
def __init__(self,name,gender):
self.name = name
self.gender = gender
Person.count +=1
print("创建了一个新的人")
def get_name(self):#实例方法,必须要实例化
return
self.name
class ChinaPerson(Person):
#如果子类没有定义__init__构造方法
#会自动调用父类的。
def __init__(self,name,gender):
Person.__init__(self,name,gender) #子类中写明调用父类的构造方法
def get_gender(self):
return self.gender
cp = ChinaPerson("吴老师","男")
print(cp.count) #父类的类变量会加一
class Person:
count = 0
nation = "中国"
def __init__(self,name,gender):
self.name = name
self.gender = gender
Person.count+=1
print("创建了一个新的人")
def get_name(self):
return self.name
class chinaPerson(Person):
def get_gender(self):
return self.gender
cp = chinaPerson("laoshi","男")
print(cp.name)
print(cp.gender)
print(cp.get_name)
print(cp.get_gender()) #可以调用子类自身的方法
运行结果:
E:\>python a.py
创建了一个新的人
laoshi
男
<bound method Person.get_name of <__main__.chinaPerson object at 0x0000023446930588>>
男
在括号里面写上多个基类(父类)
1)子类的构造函数,如果没有实现,则调用第一个基类的构造函数
count = 0 #类变量
nation = "中国"
def __init__(self,name,gender):
self.name = name
self.gender = gender
Person.count +=1
print("创建了一个新的人")
def get_name(self):#实例方法,必须要实例化
return
self.name
class Bird:
def __init__(self,color):
print("a bird is birthed!")
self.color = color
def fly(self):
print("I can fly in the sky!")
class ChinaBirdPerson(Person,Bird): #该子类()中有两个基类
#如果子类没有定义__init__构造方法,会自动调用父类的。
#该子类没有定义自己的构造函数
def get_gender(self):
return self.gender
cp = ChinaBirdPerson("吴老师","男")
print(cp.count)
运行结果:
E:\>python a.py
创建了一个新的人 #该子类的实例调用的是第一个父类的构造方法
1
-------------------------------------------------------------------------
print(cp.color) #打印第二个基类的参数color
运行结果:
E:\>python a.py
创建了一个新的人
Traceback (most recent call last):
File "a.py", line 32, in <module>
print(cp.color)
AttributeError: 'chinaBirdPerson' object has no attribute 'color' #子类没有color对象
原因:虽然子类能够继承过来Bird这个基类但是没有进行Bird的初始化,所以不会调用。
因为子类没有构造函数的情况下,则调用第一个基类的构造函数。
count = 0 #类变量
nation = "中国"
def __init__(self,name,gender):
self.name = name
self.gender = gender
Person.count +=1
print("创建了一个新的人")
def get_name(self):#实例方法,必须要实例化
return
self.name
class Bird:
def __init__(self,color):
print("a bird is birthed!")
self.color = color
def fly(self):
print("I can fly in the sky!")
class ChinaBirdPerson(Person,Bird):
#如果子类没有定义__init__构造方法
#会自动调用父类的。
def __init__(self,name,gender,color): #子类的构造函数的参数的数量可任意,不必与基类的参数数量保持一致
Person.__init__(self,name,gender) #子类中调用了第一个基类的构造方法
Bird.__init__(self,color) #子类中调用了第二个基类的构造方法
def get_gender(self):
return self.gender
cp = ChinaBirdPerson("吴老师","男","红色")
print(cp.color)
运行结果:
E:\>python a.py
创建了一个新的人 #初始化基类1
Bird is birthed #初始化基类2
red #可以打印基类2的变量
count = 0 #类变量
nation = "中国"
def __init__(self,name,gender):
self.name = name
self.gender = gender
Person.count +=1
print("创建了一个新的人")
class Bird:
def __init__(self,color):
print("a bird is birthed!")
self.color = color
def fly(self):
print("I can fly in the sky!")
def get_name(self):#实例方法,必须要实例化
return "bird has no name"
class ChinaBirdPerson(Person,Bird):
#如果子类没有定义__init__构造方法
#会自动调用父类的。
def __init__(self,name,gender,color):
Person.__init__(self,name,gender)
Bird.__init__(self,color)
def get_gender(self):
return self.gender
cp = ChinaBirdPerson("吴老师","男","红色")
print(cp.get_name())
E:\test_test_test>py -3 b.py
创建了一个新的人
a bird is birthed!
bird has no name
#如果子类没有定义__init__构造方法
#会自动调用父类的。
def __init__(self,name,gender):
Person.__init__(self,name,gender)
#Bird.__init__(self,color)
def get_gender(self):
return self.gender
cp = ChinaBirdPerson("吴老师","男")
print(cp.color)
E:\test_test_test>py -3 b.py
创建了一个新的人
Traceback (most recent call last):
File "b.py", line 36, in <module>
print(cp.color)
AttributeError: 'ChinaBirdPerson' object has no attribute 'color'
3) 子类的两个基类都有相同名字的方法时,调用该方法时,执行括号左面基类的方法,会进行深度优先的规则查找。
class Person:
count = 0
nation = "中国"
def __init__(self,name,gender):
self.name = name
self.gender = gender
Person.count+=1
print("创建了一个新的人")
def get_name(self): #基类1有get_name()方法
return self.name
class Bird:
def __init__(self,color):
print("Bird is birthed")
self.color = color
def fly(self):
print("I can fly in the sky")
def get_name(self): #基类2有get_name()方法
print("Bird has no name")
class chinaBirdPerson(Person,Bird):
def __init__(self,name,gender,color):
Person.__init__(self,name,gender)
Bird.__init__(self,color)
def get_gender(self):
return self.gender
cp = chinaBirdPerson("laoshi","男","红")
print(cp.get_name())
运行结果:
E:\>python a.py
创建了一个新的人 #初始化基类1
Bird is birthed #初始化基类2
laoshi #调用基类1的get_name()方法
4) 多继承时的深度优先
class P:
def get_name(self): #爷爷类P有get_name()方法
print("P name")
class Person(P): #父类Person继承了P
count = 0
nation = "中国"
def __init__(self,name,gender):
self.name = name
self.gender = gender
Person.count+=1
print("创建了一个新的人")
class Bird:
def __init__(self,color):
print("Bird is birthed")
self.color = color
def fly(self):
print("I can fly in the sky")
def get_name(self): #第二父类中有get_name()方法
print("Bird has no name")
class chinaBirdPerson(Person,Bird):
def __init__(self,name,gender,color):
Person.__init__(self,name,gender)
Bird.__init__(self,color)
def get_gender(self):
return self.gender
cp = chinaBirdPerson("laoshi","男","红")
print(cp.get_name())
运行结果;
E:\>python a.py
创建了一个新的人 #基类1初始化
Bird is birthed #基类2初始化
P name #深度优先,调用P的get_name()方法
None
当爷爷类有同名方法,并且第二个父类有同名方法时,子类调用方法时,按照深度优先的原则,而非广度优先的原则
从多继承的同级类去查找方法,叫做广度优先
Person(父类) Bird-->get_name(父类)
ChinaBirdPerson(孙类)
cp.get_name()
python入门(十四):面向对象(属性、方法、继承、多继承)的更多相关文章
- Python进阶(十五)----面向对象之~继承(单继承,多继承MRO算法)
Python进阶(十五)----面向对象之~继承 一丶面向对象的三大特性:封装,继承,多态 二丶什么是继承 # 什么是继承 # b 继承 a ,b是a的子类 派生类 , a是b的超类 基类 父类 # ...
- Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理)
Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理) 一丶封装 , 多态 封装: 将一些东西封装到一个地方,你还可以取出来( ...
- 孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘
孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天发现了python的类中隐藏着一些特殊的私有方法. 这些私有方法不管我 ...
- Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式
Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式 目录 Pycharm使用技巧(转载) Python第一天 安装 shell 文件 Py ...
- Python进阶(十四)----空间角度研究类,类与类之间的关系
Python进阶(十四)----空间角度研究类,类与类之间的关系 一丶从空间角度研究类 对象操作对象属性 class A(): address = '沙河' def __init__(self, na ...
- Python 入门 之 初识面向对象
Python 入门 之 初识面向对象 1.初识面向对象编程 (核心--对象) (1)观察以下代码: # 面向过程编程 s = "alexdsb" count = 0 for i i ...
- 孤荷凌寒自学python第十四天python代码的书写规范与条件语句及判断条件式
孤荷凌寒自学python第十四天python代码的书写规范与条件语句及判断条件式 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 在我学习过的所有语言中,对VB系的语言比较喜欢,而对C系和J系 ...
- 初学 Python(十四)——生成器
初学 Python(十四)--生成器 初学 Python,主要整理一些学习到的知识点,这次是生成器. # -*- coding:utf-8 -*- ''''' 生成式的作用: 减少内存占有,不用一次性 ...
- Python第二十四天 binascii模块
Python第二十四天 binascii模块 binascii用来进行进制和字符串之间的转换 import binascii s = 'abcde' h = binascii.b2a_hex(s) # ...
- Python 静态方法、类方法和属性方法
Python 静态方法.类方法和属性方法 静态方法(staticmethod) staticmethod不与类或者对象绑定,类和实例对象都可以调用,没有自动传值效果,Python内置函数staticm ...
随机推荐
- MySQL 设置root密码报错:mysqladmin: connect to server at 'localhost' failed
MySQL 设置root密码报错:mysqladmin: connect to server at 'localhost' failed 1.安装完MySQL设置root密码报错如下 [root@vm ...
- 管理mysql数据的两条sql tips
当从B表数据更新到A表时: update A inner join B on A.aid=B.aid set A.user_name=B.username,A.phone=B.telwhere A.a ...
- centos7远程安装oracle11g R2详细教程-解决一切问题
相关链接与资源: sqldevelper(各种操作系统的oracle客户端) http://www.oracle.com/technetwork/cn/developer-tools/sql-deve ...
- Linux下MySQL编码的修改
默认登录mysql之后可以通过SHOW VARIABLES语句查看系统变量及其值. mysql> show variables like '%character%'; 说明:以下是在Cent ...
- Ubuntu 16.04安装Docker-CE
系统环境 * Ubuntu: 16.04 * Docker: 17.09.0-ce 安装步骤 1.安装Docker-CE,具体参考:https://docs.docker.com/engine/ins ...
- CPU的概念
1.CPU的运算都是以纳秒为单位的,内存相比要慢百倍,硬盘要慢百万倍. 2.CPU的主要工作就是运行指令,指令全在内存里,第一条指令地址为0xFFFFFF0处(BIOS发出的跳转指令). 3.CPU工 ...
- (简单)华为M3青春 CPN-AL10的Usb调试模式在哪里打开的步骤
每次我们使用PC通过数据线连接到安卓手机的时候,如果手机没有开启usb开发者调试模式,PC则没能成功检测到我们的手机,有时候我们使用的一些功能比较强的的应用软件比如以前我们使用的一个应用软件引号精灵, ...
- python-web自动化:下拉列表操作
非select/option元素: 1.触发下拉列表出现 2.等待下拉列表中的元素出现,然后进行选择元素即可. select/option元素: 下拉框操作-Select类selenium提供Sele ...
- eShopOnContainers 看微服务⑤:消息通信
1.消息通信 传统的单体应用,组件间的调用都是使用代码级的方法函数.比如用户登录自动签到,增加积分.我们可以在登录函数调用积分模块的某个函数,为了解耦我们使用以来注入并放弃new Class()这种方 ...
- linux gcc 静态 动态链接库
静态链接库 首先生成依赖函数的目标文件 gcc -c source1.c source2.c; 然后归档目标文件到静态库 ar -rcs libYourID.a obj1.o obj2.o; 然后我们 ...