Python 面向对象编程
面向对象编程(OOP) Object Oriented Programming
Java和C#来说只支持面向对象编程,python即支持面向对象编程也支持函数式编程
面向对象编程其实就是对 “类” 和 “对象” 的使用。类就是一个模板,模板里可以包含多个函数,函数里实现一些功能,类中定义的函数叫做 “方法”。对象则是根据模板创建的实例,通过实例对象可以执行类中的函数
- 面向对象:【创建对象】【通过对象执行方法】
- 函数编程:【执行函数】 函数式编程适用于各个函数之间独立且无共用数据的场景
创建类
class Foo: def Func1(self): print('hello') def Func2(self, name): print('I am %s' %name)
obj=Foo() # 根据类Foo创建对象obj, 把一个抽象的类变成一个对象的过程叫实例化
obj.Func1() # 执行类中的方法,类中定义的函数叫做 “方法”
obj.Func2('Jack')
isinstance(obj, cls) # 查看obj是否是类 cls 的对象
面向对象三大特性
封装、继承和多态。
一、封装
封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。
在使用面向对象的封装特性时,需要:
- 将内容封装到某处
- 从某处调用被封装的内容
class Foo: def __init__(self,name,age) # __init__为构造方法,根据类创建对象时会自动执行该方法 self.Name=name self.Age=age
类中的函数第一个参数必须是self,self表示实例本身,谁调用该类,这个self就是谁
obj=Foo('test',18) # 将'test'和18封装到 obj的Name和Age属性中,相当于 Foo(obj,'test',18)
1、通过对象直接调用被封装的内容: 对象.属性名
print(obj.Name)
print(obj.Age)
2、通过self间接调用被封装的内容
class Foo:
def __init__(self,name,age)
self.Name=name
self.Age=age
def echo(self)
print(self.Name,self.Age)
obj=Foo('test',18)
obj.echo()
二、继承
继承,面向对象中的继承和现实生活中的继承相同,即:子类(派生类) 可以继承 父类(基类) 的内容。
class Parent: def func1(self): pass class Child(Parent): # 子类继承父类,即拥有了父类中所有方法 def func2(self): pass
obj=Child()
obj.func1()
看个例子:
学生和老师都有 名字,性别,年龄的属性,都有注册和个人介绍方法。
老师有自己的属性和方法如:教授的课程和薪水、教书
学生有自己的属性和方法如:学习的课程和学费、交学费
class schoolMember(object): Num=0 def __init__(self,name,sex,age): self.name=name self.sex=sex self.age=age self.enroll() def enroll(self): schoolMember.Num+=1 print('schoolMember [%s] is enrolled!' %(self.name,Num) def introduce(self): print('my name is %s' %self.name) class teacher(schoolMember): def __init__(self,name,sex,age,course,salary): super(teacher,self).__init__(name,age,sex) #先重写,再继承。新式类写法
self.course=course self.salary=salary #schoolMember.__init__(self,name,age,sex) #先重写,再继承。旧式类写法 def teaching(self): print('Teacher [%s] is teaching [%s]' %(self.name,course)) class student(schoolMember): def __init__(self,name,sex,age,course,tuition): super(student,self).__init__(name,age,sex) self.course=course self.tuition=tuition def pay_tuition(self): print('student [%s] paying tution [%s]' %(self.name,tuition)) t1=teacher('zhou','Male',27,'Python',1000) s1=student('wu','Female',22,'Python',500) t1.introduce() s1.pay_tuition()
对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。
多继承
Python的类可以继承多个类,Java和C#中则只能继承一个类
Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先
- 当类是经典类时,多继承情况下,会按照深度优先方式查找
- 当类是新式类时,多继承情况下,会按照广度优先方式查找(合理,距离较近)
Python3.x无论是经典类和新式类都是广度优先
经典类和新式类
新式类包含了更多的功能,是推荐的写法,从写法上区分的话,如果 当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类。
经典类
class D: def echo(self):
print('D')
class C:
def echo(self):
print('C')
class B(D):
def echo(self):
print('B')
class A(B,C):
def echo(self):
print('A')
x=A()
x.echo() # 查找顺序:A --> B --> D --> C,查找 echo 方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
新式类
class D(Object):
def echo(self):
print('D')
class C:
def echo(self):
print('C')
class B(D):
def echo(self):
print('B')
class A(B,C):
def echo(self):
print('A')
x=A()
x.echo() # 查找顺序:A --> B --> C --> D,查找 echo 方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
经典类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中没有,则继续去D类中找,如果D类中没有,则继续去C类中找,如果还是未找到,则报错
新式类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中没有,则继续去C类中找,如果C类中没有,则继续去D类中找,如果还是未找到,则报错
查找过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
issubclass(sub, super) # 查看sub类是否是 super 类的派生类
三、多态
封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。
多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,指一个基类中派生出了不同的子类,且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态。
多态允许将子类的对象当作父类的对象使用,某父类型的引用指向其子类型的对象,调用的方法是该子类型的方法。这里引用和调用方法的代码编译前就已经决定了,而引用所指向的对象可以在运行期间动态绑定。
python不直接支持Java和C#这一类强类型语言的多态语法
Python伪代码实现Java或C#的多态 class Parent: pass class Child1(Parent): def echo(self): print('C1') class Child2(Parent): def echo(self): print('C2')
def Func(Parent obj): # 其他语言中,Func函数必须定义一个Parent类型或者其子类的类型的参数
print(obj.echo())
obj1=Child1()
Func(obj1) # 在Func函数中传入Child2类的对象,执行Child1的echo方法
obj2=Child2()
Func(obj2) # 在Func函数中传入Child2类的对象,执行Child2的echo方法
Python 多态语法实例
class Animal(object): def __init__(self, name): self.name = name class Cat(Animal): def talk(self): print('%s: 喵!' %self.name) class Dog(Animal): def talk(self): print('%s: 汪!' %self.name) def func(obj): #一个接口,多种形态。python 多态传参数不指定类型 obj.talk() c1 = Cat('天猫') d1 = Dog('京东') func(c1) func(d1)
元类
Metaclass