1.面向对象概述
面向过程编程:根据操作数据的函数或语句块来设计程序的。
函数式编程:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
面向对象编程:数据和功能结合起来,用称为对象的东西包裹起来组织程序的方法;
在大多数时候你可以使用面向过程编程,但是有些时候当需要编写大型程序或是寻求一个更加合适的解决方案的时候,就需要面向对象的编程,Python既可以提供面向过程的编程,也可以面向对象的编程,归根到底,Python语言是面向对象的编程语言。
2.创建类和对象
__metaclass__=type #确定使用新式类,这句话可以不写,内部自动调用 class Person: #创建类 def setName(self,name):#self是特殊参数,必填 self.name=name def getName(self): return self.name def greet(self): print("Hello,%s"%self.name)
>>> foo=Person()#根据类Person创建对象foo,实例化这个类
>>> foo.setName('greg')#执行setName方法,此时的foo就是类Person的实例化对象
>>> foo.greet() #执行greet方法
Hello,greg
#实例化,其实就是以Person类为模版,在内存里开辟一块空间,存上数据,赋值成一个变量名
所有的对象都属于某一个类,称为类的实例(instance)
foo=Person()叫做类的“实例化”, 就是把一个虚拟的抽象的类,通过这个动作,变成了一个具体的对象了, 这个对象就叫做实例
类的执行逻辑
定义类时,所有位于class语句中的代码都在特殊的命名空间中执行——类命名空间(class namespace)。
这个命名空间可由类内所有成员访问,类的定义其实就是执行代码块,在类的定义区并不只限只能使用def语句。
>>>class C: print("Class C being defined") #运行 >>>Class C being defined
class Person(object): def __init__(self, name): self.name = name def hello(self): print("hello,%s" %self.name) obj=Person("greg") obj.hello() #hello,greg print(Person)#<class '__main__.Person'>
即使不实例化,这个Person类本身也是已经存在内存里了
3.对象的魔力
3.1 多态(Polymorphism):意味着可以对不同类的对象使用相同的操作。
def add(x,y): return x+y print(add(1,2)) print(add('Fish','license')) def length_message(x): print("长度:",repr(x),"是",len(x)) print(length_message('gregory')) print(length_message([1,2,3]))
python里的很多函数和运算符都是多态的,只要使用多态函数和运算符,就会与多态发生关联。
唯一能够毁掉多态的就是使用函数显式地检查类型,比如type,isinstance,issubclass函数等。
多态的形式在Python里也被称为鸭子类型duck typing
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)
3.2 封装(Encapsulation): 即对外部世界隐藏对象的工作细节。
封装是指向程序中的其他部分隐藏对象的具体实现细节的原则。和多态类似,也是使用对象而不用知道其内部细节。
区别在于:多态可以让用户对于不知道是什么类(对象类型)的对象进行方法调用,而封装是可以不用关心对象是如何构建的而直接进行使用。
class Person: def __init__(self,name,age): #构造方法,类名()自动执行构造方法 self.n=name self.a=age self.b='o型' def show(self): print('%s-%s-%s'%(self.n,self.a,self.b)) obj1=Person('greg',18)
#直接调用对象的属性
print(obj1.name)
#间接调用
Python默认会将obj1传给self参数,即:obj1.show(obj1)
obj1.show()
在使用面向对象的封装特性时,需要:
1)将内容封装到某处
2)从某处调用被封装的内容
对于面向对象的封装来说,其实就是使用构造方法将内容封装到 对象 中,然后通过对象直接或者self间接获取被封装的内容。
3.3 继承(Inheritance): 以通用的类为基础建立专门的类对象。
继承 class G: def g1(self): print('G.g1') class F(G): #父类,基类 def f1(self): print('F.f1') def f2(self): print('F.f2') class S(F): #子类,派生类 def s1(self): print('S.s1') def f2(self): super(S,self).f2() #固定写法,执行父类(基类)中的f2方法 print('S.s2') # F.f2(self) #执行父类(基类)中的f2方法 obj=S()#self执行当前方法的对象 # obj.s2()#s1中的self是形参,此时代指obj obj.f2()#self永远指调用方法的调用者 # obj.g1()
self永远是执行方法的调用者
supper(子类,self).父类中的方法 (...)
父类名.父类中的方法(self,...)
多继承
1、Python的类可以继承多个类,Java和C#中则只能继承一个类
2、Python的类如果继承了多个类,从做到右一次查找,找不到会报错
class Base: def a(self): print('Base.a') class F0(Base): def a1(self): print('F0.a') class F1(F0): def a1(self): print('F1.a') class F2(Base): def a(self): print('F2,a') class S(F1,F2): pass obj=S() obj.a() #从左到右找,查找顺序S-->F1-->F2