python面向对象编程
1. 编程方式分类:
- 面向过程:根据业务逻辑从上到下写垒代码,初学者容易接受
- 面向函数:将某功能代码封装到函数中,日后便无需重复编写,使用时仅调用函数即可。
- 面向对象:对函数进行分类和封装,让开发“更快更好更强…”
2.创建类和对象
-
面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。
类就是一个模板,模板里可以包含多个函数,函数里实现一些功能
对象则是根据模板创建的实例,通过实例对象可以执行类中的函数
来一段代码感受下先
##class people: ## 经典类
class People(object): ## 创建类,该类为新式类,object类是所有类的基类/父类
def __init__(self,name,age): # 构造函数,当实例化对象时自动调用;
self.name = name # 属性
self.age = age
def run(self): # 方法
print "running...."
def __del__(self):
print "deleteing......" # 析构函数,删除实例化对象时自动调用;
class Student(People): # Student是子类,继承People这个父类;
def study(self): # 方法
print "study...."
p1 = People("zhangsan",18) ##根据类People创建对象p1
s1 = Student("lisi",16)
p1.run() ##执行run方法
s1.study()
- class是关键字,表示类
- 创建对象,类名称后加括号即可
- 类中的函数第一个参数必须是self
- 类中定义的函数叫做 “方法”
面向对象的三大特性
1.封装
封装:把内容统一放在一个地方,看成一个整体,(实例化对象self和类的属性绑定在一起),以后再去调用被封装在某处的内容;
- 访问封装内容的两种方式:
- 通过self去访问封装的内容;(self.name)
- 通过实例化的对象名去访问封装的内容;
p1 = People(“zhangsan”,18)
p1.age
2. 继承
继承:子承父业
- 对于面向对象的继承来说,其实就是将多个类共有的属性和方法提取到父类中,子类仅需继承父类,而不必每个子类中去一一实现每个方法或者定每个属性,上面的代码中 name,age是人共有的属性,run()是人共有的方法,我们把它提取到类People中,类Student只需继承People类,就拥有了name,age属性和run()方法,而不必在Student类中重新定义这些属性和方法
- 新名词:基类/派生类, 父类/子类, 新式类和经典类
- 派生类 和 基类 ,他们与子类和父类只是叫法不同而已
-
多继承:
- Python的类可以继承多个类,Java和C#中则只能继承一个类
-
如果继承的多个类每个类中都定了相同的函数,那么那一个会被使用呢
- Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先
- 当类是经典类时,多继承情况下,会按照深度优先方式查找
- 当类是新式类时,多继承情况下,会按照广度优先方式查找
新式类: 广度优先继承;(python2.x和python3.x均支持)
- 经典类:深度优先继承;(python2.x支持,python3.x没有经典类)
class C1: ##经典类
pass
class C2(C1): ##C2是经典类
pass
class N1(object): ##新式类
pass
class N2(N1): ##N2是新式类
pass
- 注意:
类的方法中可以传递一个对象;
class D: ##经典类
def show(self):
print 'D.show'
class C(D):
def show(self):
print 'C.show'
class B(D):
def show(self):
print 'B.show'
class A(B, C):
def show(self):
print 'A.show'
a = A()
a.show()
# 执行show方法时
# 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错
# 所以,查找顺序:A --> B --> D --> C
# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
class D(object): ##新式类
def show(self):
print 'D.show'
class C(D):
def show(self):
print 'C.show'
class B(D):
def show(self):
print 'B.show'
class A(B, C):
def show(self):
print 'A.show'
a = A()
a.show()
# 执行show方法时
# 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错
# 所以,查找顺序:A --> B --> C --> D
# 在上述查找show方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
3. 多态
- 类具有继承关系,并且子类类型可以向上转型看做父类类型,如果我们从 Person 派生出 Student和Teacher ,并都写了一个 whoAmI() 方法:
class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
def whoAmI(self):
return 'I am a Person, my name is %s' % self.name
class Student(Person):
def __init__(self, name, gender, score):
super(Student, self).__init__(name, gender)
self.score = score
def whoAmI(self):
return 'I am a Student, my name is %s' % self.name
class Teacher(Person):
def __init__(self, name, gender, course):
super(Teacher, self).__init__(name, gender)
self.course = course
def whoAmI(self):
return 'I am a Teacher, my name is %s' % self.name
在一个函数中,如果我们接收一个变量 people,则无论该 x 是 Person、Student还是 Teacher,都可以正确打印出结果:
def Who_Am_I(people):
print people.whoAmI()
p = Person('Tom', 'Male')
s = Student('Tim', 'feMale', 98)
t = Teacher('Laoli', 'Male', 'linux')
Who_Am_I(p)
Who_Am_I(s)
Who_Am_I(t)
运行结果:
I am a Person, my name is Tom
I am a Student, my name is Tim
I am a Teacher, my name is Laoli
这种行为称为多态。也就是说,方法调用将作用在 people的实际类型上。s 是Student类型,它实际上拥有自己的 whoAmI()方法以及从 Person继承的 whoAmI方法,但调用 s.whoAmI()总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止。
- 如果子类调用的方法,子类没有,父类有,运行父类;
- 如果子类调用的方法,子类有,父类也有,只运行子类的;
=======================未完待续=======================
面向对象进阶
- 类变量,全局变量,在内存中只存储一份;
- 普通的对象属性,每个对象中都需要存储一份;
方法
- 实例化方法:第一个参数为self(实例化本身);
- 类方法:第一个参数是cls(类本身);通过@classmethod装饰器实现;
- 静态方法:第一个参数既不是self也不是cls;通过@staticmethod方法实现;