面向对象基础¶
python编程方式
- 面向过程编程
- 面向函数编程
- 面向对象编程
各种定义
- 如果函数没有在类中,称之为
函数
- 如果函数在类中,称之为
方法
类¶
创建类
# 创建一个类,类名是 Class_basis
>>> class Class_basis:
# 在类里面创建了一个方法ret,类里面的方法必须加一个self关键字
... def ret(self):
# 当调动方法的时候输出ret
... print("ret")
...
使用类
# 通过 Class_basis 类创建一个对象obj(创建一个 Class_basis实例),类名后面加括号
>>> obj = Class_basis()
# 通过对象调用类中的ret方法
>>> obj.ret()
ret
类的内存地址对应关系
方法¶
- 构造方法
- 析构方法
- 私有方法
属性¶
- 实例变量
- 类变量
- 私有属性
__var
对象¶
对象: 实例化一个类之后得到的对象
面向对象之self¶
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
# 创建一个类,类名是 Class_basis
class Class_basis:
# 在类里面创建了一个方法ret
def ret(self,):
# 输出self的内存地址
print("方法ret的self内存地址",id(self))
# 创建一个对象obj,类名后面加括号
obj = Class_basis()
# 输出对象obj的内存地址
print("obj对象内存地址",id(obj))
# 通过对象调用类中的ret方法
obj.ret()
执行结果
➜ python_test python3 021-exercise-1-self.py
obj对象内存地址 4321835888
方法ret的self内存地址 4321835888
通过上面的测试可以很清楚的看到obj
对象和类的方法中self
内存地址是一样的,那么方法中的self
就等于obj
self
是形式参数,由python自行传递
面向对象之封装¶
把一些功能的实现细节不对外暴露
封装就是将内容封装到某个地方,以后再去调用被封装在某处的内容,在使用面向对象的封装特性时,需要:
- 将内容封装到某处
- 从某处调用被封装的内容
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
class Foo:
def ret(self):
# 输出backend变量的内容
print(self.backend)
obj = Foo()
# 在对象中创建一个backend变量
obj.backend = "as"
obj.ret()
执行结果
➜ python_test python3 021-exercise-2.py
as
上面的封装是一种非主流的封装方式,下面的__init__构造函数
封装方式是主流的封装方式
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
class Foo:
# 进入类的时候首先执行 __init__方法
def __init__(self,name):
"""
__init__称之为构造方法
:param name: Foo传递过来的参数
"""
# 在类中创建一个成员Name,它的值是传过来的形参name
self.Name = name
# 类的方法
def user(self):
# 输出Name的值
print(self.Name)
# 创建对象,并且将"yang"封装到对象中,类+括号的时候会自动执行__init__方法
obj = Foo("yang")
# 执行user方法
obj.user()
执行结果
➜ python_test python3 021-exercise-3.py
yang
__del__解释器销毁对象时自动调用,特殊名称:析构方法
封装的应用场景之一就是当同一类型的方法具有相同参数时,直接封装到对象即可.
实例¶
通过用户输入年龄和姓名输出用户的个人信息
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
class Foo:
def __init__(self,name,age):
self.Name = name
self.Age = age
def info(self):
print("""
My name is: %s
My age is: %d
""" % (self.Name,self.Age))
yang = Foo("Yang",18)
yang.info()
xiaoming = Foo("xiaoming",30)
xiaoming.info()
执行结果
➜ python_test python3 021-exercise-4.py
My name is: Yang
My age is: 18
My name is: xiaoming
My age is: 30
封装的应用场景之二就是把类当作模块,创建多个对象(对象内封装的数据可以不一样)
面向对象之继承基础¶
继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容
- 代码的重用
- 单继承
- 多继承
- 2.7 经典类:深度优先 新式类: 广度优先
- 3.x 均是广度优先
# 继承自object
class Foo(object)
def __init__(self,name,age,sex,salary,course):
self.salary = salary
self.course = course
实例:
创建一个人
信息相关的类,比如说人拥有四肢
,头发
,眼
,耳朵
等信息,再创建一个中国人和非洲黑人的类,中国人的语言是中文,皮肤是黄色,非洲黑人的语言是英文,皮肤是黑色.
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
class People:
def __init__(self):
print("""
相同特征: 四肢,头发,眼睛,耳朵
""")
class China(People):
def info(self):
print("""
你是中国人,你的语言是中文,皮肤是黄色
""")
class Africa(People):
def info(self):
print("""
你是非洲黑人,你的语言是英语,皮肤是黑色
""")
c = China()
c.info()
a = Africa()
a.info()
➜ python_test python3 021-exercise-5.py
相同特征: 四肢,头发,眼睛,耳朵
你是中国人,你的语言是中文,皮肤是黄色
相同特征: 四肢,头发,眼睛,耳朵
你是非洲黑人,你的语言是英语,皮肤是黑色
People
-> 父类
or 基类
China
and Africa
-> 子类
or 派生类
- 派生类可以集成基类中所有的功能
- 派生类和基类同时存在,优先找派生类
- python类可以同时继承多个类
面向对象之继承之多继承(新式类)¶
多继承就是在class My(China,Africa):
括号内放入多个父类名
多继承顺序
当My(China,Africa)
时,因为My
类中有info
这个方法,所以输出的结果是我就是我
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
class China:
def info(self):
print("你是中国人")
class Africa:
def info(self):
print("你是非洲人")
class My(China,Africa):
def info(self):
print("我就是我")
c = My()
c.info()
执行结果
➜ python_test python3 021-exercise-6.py
我就是我
当My(China,Africa)
时,My
类中没有info
这个方法,输出的结果就是你是中国人
,默认括号内左边的类优先
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
class China:
def info(self):
print("你是中国人")
class Africa:
def info(self):
print("你是非洲人")
class My(China,Africa):
pass
c = My()
c.info()
执行结果
➜ python_test python3 021-exercise-7.py
你是中国人
当My(China,Africa)
时,My
类中没有info
这个方法,China
类中也没有info
这个方法,输出的结果是你是非洲人
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
class China:
pass
class Africa:
def info(self):
print("你是非洲人")
class My(China,Africa):
pass
c = My()
c.info()
执行结果
➜ python_test python3 021-exercise-8.py
你是非洲人
多态¶
接口重用,一种接口,多种实现