6-Python-面向对象
来源:互联网 发布:南风知我意琰阙 编辑:程序博客网 时间:2024/05/18 01:28
- 知识点
知识点
--Python-面向对象
- 类
定义类
定义一个类,格式如下:
class 类名:
属性列表
方法列表
创建对象的格式为:
对象名 = 类名()
注意点:
提示找不到该属性,因为私有属性是不能够在类外通过对象名来进行访问的。在Python中没有像C++中public和private这些关键字来区别公有属性和私有属性,它是以属性命名方式来区分,如果在属性名前面加了2个下划线'__',则表明该属性是私有属性,否则为公有属性(方法也是一样,方法名前面加了2个下划线的话表示该方法是私有的,否则为公有的)。
- self
小总结
所谓的self,可以理解为自己
可以把它当做C++中类里面的this指针一样理解,就是对象自身的意思,在用某个对象调用该方法时,就将该对象作为第一个参数传递给self。
- 构造器
<1>构造器方法的格式
"构造器"方法,的格式如下:
def __init__():
<2>构造器方法调用
在Car类中添加 "构造器"方法:
# 定义类
class Car:
# 构造器方法
def __init__(self):
self.wheelNum = 4
self.color = 'blue'
# 方法
def run(self):
print '车在跑,目标:夏威夷'
# 创建对象
BMW = Car()
print('车的颜色为:%s'%BMW.color)
print('车轮子数量为:%d'%BMW.wheelNum)
小总结
通过上面的列子能够看到,当创建完Car类型的对象后,对象BMW对象的成员变量wheelNum和color都发生了变化,因此__init__()方法是在创建对象后,被默认执行了
想一想:
既然在创建完对象后__init__()方法已经被默认的执行了,那么能否让对象在默认调用__init__()方法的时候传递一些参数呢?如果可以,那怎样传递呢?
# 定义类
class Car:
# 构造器方法
def __init__(self, newWheelNum, newColor):
self.wheelNum = newWheelNum
self.color = newColor
# 方法
def run(self):
print '车在跑,目标:夏威夷'
# 创建对象
BMW = Car(4, 'green')
print '车的颜色为:',BMW.color
print '车轮子数量为:',BMW.wheelNum
<3>总结
构造器方法,在创建一个对象时默认被调用,不需要手动调用
- 析构&继承
析构
创建对象时,默认调用构造方法;当删除一个对象时,同样也会默认调用一个方法,这个方法为析构方法
<1>析构方法(__del__())
demo:
class Animal():
# 构造方法
def __init__(self):
print '---构造方法被调用---'
# 析构方法
def __del__(self):
print '---析构方法被调用---'
# 创建对象
dog = Animal()
# 删除对象
del dog
结果:<2>继承示例
# 定义一个父类,如下:
class Cat:
name = '猫'
color = 'white'
def run(self):
print self.name,'--在跑'
# 定义一个子类,如下:
class Bosi(Cat):
def setName(self, newName):
self.name = newName
def eat(self):
print self.name,'--在吃'
bs = Bosi()
print 'bs的名字为:',bs.name
print 'bs的颜色为:',bs.color
bs.eat()
bs.setName('波斯')
bs.run()
运行结果:
说明:
虽然子类,没有构造方法,但是父类有,所以在子类继承父类的时候,其构造方法也会被继承,所以只要创建Bosi的实例对象,就默认执行了那个继承过来的构造方法
小总结:
子类在继承的时候,在定义类时,小括号()中为父类的名字
父类的属性、方法,会被继承给子类
- 多继承
Python中多继承的格式如下:
# 定义一个父类
class A:
def printA(self):
print '----A----'
# 定义一个父类
class B:
def printB(self):
print '----B----'
# 定义一个子类,继承自A、B
class C(A,B):
def printC(self):
print '----C----'
obj_C = C()
obj_C.printA()
obj_C.printB()
运行结果:
----A----
----B----
*说明
python中是可以多继承的
父类中的方法、属性,子类会继承
<2>注意点
想一想:
如果在上面的多继承例子中,如果父类A和父类B中,有一个同名的方法,那么通过子类去调用的时候,调用哪个?
答:
- 重载
1. 重载
所谓重载,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法
#coding=utf-8
class Cat:
def sayHello(self):
print("halou-----1")
class Bosi(Cat):
def sayHello(self):
print("halou-----2")
bosi = Bosi()
bosi.sayHello()
2. 调用父类的方法
#coding=utf-8
class Cat:
def __init__(self,name):
self.name = name
self.color = 'yellow'
class Bosi(Cat):
def __init__(self,name):
Cat.__init__(self,name) # 调用父类的__init__方法
def getName(self):
return self.name
bosi = Bosi('xiaohua')
print(bosi.name)
print(bosi.color)
- 多态
多态
多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”。
所谓多态:定义时的类型和运行时的类型不一样,此时就成为多态
Python伪代码实现Java或C#的多态
class F1:
pass
class S1(F1):
def show(self):
print 'S1.show'
class S2(F1):
def show(self):
print 'S2.show'
# 由于在Java或C#中定义函数参数时,必须指定参数的类型
# 为了让Func函数既可以执行S1对象的show方法,又可以执行S2对象的show方法,所以,定义了一个S1和S2类的父类
# 而实际传入的参数是:S1对象和S2对象
def Func(F1 obj):
"""Func函数需要接收一个F1类型或者F1子类的类型"""
print obj.show()
s1_obj = S1()
Func(s1_obj) # 在Func函数中传入S1类的对象 s1_obj,执行 S1 的show方法,结果:S1.show
s2_obj = S2()
Func(s2_obj) # 在Func函数中传入Ss类的对象 ss_obj,执行 Ss 的show方法,结果:S2.show
Python “鸭子类型”
class F1:
pass
class S1(F1):
def show(self):
print 'S1.show'
class S2(F1):
def show(self):
print 'S2.show'
def Func(obj):
print obj.show()
s1_obj = S1()
Func(s1_obj)
s2_obj = S2()
Func(s2_obj)
- 类属性、实例属性
类属性、实例属性
在了解了类基本的东西之后,下面看一下python中这几个概念的区别
先来谈一下类属性和实例属性
在前面的例子中我们接触到的就是类属性,顾名思义,类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,这个和C++中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象和实例对象访问
类属性
class people:
name = 'Tom' #公有的类属性
__age = 12 #私有的类属性
p = people()
print p.name #正确
print people.name #正确
print p.__age #错误,不能在类外通过实例对象访问私有的类属性
print people.__age #错误,不能在类外通过类对象访问私有的类属性
实例属性
实例属性是不需要在类中显示定义的,比如:
class people:
name = 'Tom'
p = people()
p.age =12
print p.name #正确
print p.age #正确
print people.name #正确
print people.age #错误
在类外对类对象people进行实例化之后,产生了一个实例对象p,然后p.age = 12这句给p添加了一个实例属性age,赋值为12。这个实例属性是实例对象p所特有的,注意,类对象people并不拥有它(所以不能通过类对象来访问这个age属性)。当然还可以在实例化对象的时候给age赋值。
class people:
name = 'Tom'
#__init__()是内置的构造方法,在实例化对象时自动调用
def __init__(self,age):
self.age = age
p = people(12)
print p.name #正确
print p.age #正确
print people.name #正确
print people.age #错误
如果需要在类外修改类属性,必须通过类对象去引用然后进行修改。如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性。
class people:
country = 'china'
print people.country
p = people()
print p.country
p.country = 'japan'
print p.country #实例属性会屏蔽掉同名的类属性
print people.country
del p.country #删除实例属性
print p.country
总结
对于类属性和实例属性,如果在类方法中引用某个属性,该属性必定是类属性,而如果在实例方法中引用某个属性(不作更改),并且存在同名的类属性,此时若实例对象有该名称的实例属性,则实例属性会屏蔽类属性,即引用的是实例属性,若实例对象没有该名称的实例属性,则引用的是类属性;如果在实例方法更改某个属性,并且存在同名的类属性,此时若实例对象有该名称的实例属性,则修改的是实例属性,若实例对象没有该名称的实例属性,则会创建一个同名称的实例属性。想要修改类属性,如果在类外,可以通过类对象修改,如果在类里面,只有在类方法中进行修改。
- 静态方法和类方法
静态方法和类方法
1. 类方法
是类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以'cls'作为第一个参数的名字,就最好用'cls'了),能够通过实例对象和类对象去访问。
class people:
country = 'china'
#类方法,用classmethod来进行修饰
@classmethod
def getCountry(cls):
return cls.country
p = people()
print p.getCountry() #可以用过实例对象引用
print people.getCountry() #可以通过类对象引用
类方法还有一个用途就是可以对类属性进行修改:
class people:
country = 'china'
#类方法,用classmethod来进行修饰
@classmethod
def getCountry(cls):
return cls.country
@classmethod
def setCountry(cls,country):
cls.country = country
p = people()
print p.getCountry() #可以用过实例对象引用
print people.getCountry() #可以通过类对象引用
p.setCountry('japan')
print p.getCountry()
print people.getCountry()
结果显示在用类方法对类属性修改之后,通过类对象和实例对象访问都发生了改变
2. 静态方法
需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数
class people:
country = 'china'
@staticmethod
#静态方法
def getCountry():
return people.country
print people.getCountry()
总结
从类方法和实例方法以及静态方法的定义形式就可以看出来,
类方法的第一个参数是类对象cls,那么通过cls引用的必定是类对象的属性和方法;
而实例方法的第一个参数是实例对象self,那么通过self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。
静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用
阅读全文
1 0
- 6-Python-面向对象
- python编程(6):面向对象
- python面向对象编程(6)
- python入门6面向对象高级编程
- python基础6:面向对象1
- python 面向对象
- python面向对象初步
- python面向对象
- Python面向对象详解
- python面向对象编程
- python面向对象
- python 面向对象
- python 面向对象编程
- python面向对象编程
- python面向对象编程
- python 面向对象笔记
- Python 面向对象编程
- Python面向对象编程
- LeetCode 38 Count and Say
- ES6 Object.assign()
- HTML标签速查列表
- Java实现在线预览附件 office转换PDF
- 查询函数在哪些存储过程中使用
- 6-Python-面向对象
- 全面掌握 Node 命令选项
- iOS Pointer is missing a nullability type specifier (__nonnull or __nullable)
- 51nod 1120 机器人走方格 V3(卡特兰数,lucas定理)
- Nginx 504 Gateway Time-out
- CSS3的Media Query来实现实现响应式开发
- Django Tutorial Part1
- Android Studio开启DDMS查看手机文件
- Nodejs 进阶:Express 常用中间件 body-parser 实现解析