类和对象
面向对象编程是一种编程方式,该编程方式需要靠类和对象实现,所以面向对象编程就是类和对象的实现。
类:就是一个模板,一个模板里面有很多函数,函数有很多功能。就相当于我们用的ppt一样,不同的ppt有不同的模板和不同的结构和功能。
对象:对象是根据模板创建的实例,通过实例对象可以执行类中的函数和方法。如果不新建一个ppt我们是没办法使用ppt的,简历ppt之后我们就可以根据ppt的样式完成我们需要做的报告和演示。
综上所述,对于面向对象的封装来说,其实就是使用构造方法将内容封装到 对象 中,然后通过对象直接或者self间接获取被封装的内容
注:除了子类和父类的称谓,你可能看到过 派生类 和 基类 ,他们与子类和父类只是叫法不同而已
多继承:
Python的类可以继承多个类,Java和C#中则只能继承一个类Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先经典类和新式类,从字面上可以看出一个老一个新,新的必然包含了跟多的功能,也是之后推荐的写法,从写法上区分的话,如果 当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类
当类是经典类时,多继承情况下,会按照深度优先方式查找 class D: def bar(self): print 'D.bar' class C(D): def bar(self): print 'C.bar' class B(D): def bar(self): print 'B.bar' class A(B, C): def bar(self): print 'A.bar' a = A() # 执行bar方法时 # 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错 # 所以,查找顺序:A --> B --> D --> C # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了 a.bar() 经典类多继承 当类是新式类时,多继承情况下,会按照广度优先方式查找 class D(object): def bar(self): print 'D.bar' class C(D): def bar(self): print 'C.bar' class B(D): def bar(self): print 'B.bar' class A(B, C): def bar(self): print 'A.bar' a = A() # 执行bar方法时 # 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错 # 所以,查找顺序:A --> B --> C --> D # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了 a.bar() 新式类多继承 新式类多继承鸭子类型:
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伪代码实现Java或C#的多态 Python伪代码实现Java或C#的多态鸭子类型的定义:
在程序设计中,鸭子类型(英语:ducktyping)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由"当前方法"方法(计算机科学)")和属性的集合"决定。这个概念的名字来源于由James WhitcombRiley提出的鸭子测试,“鸭子测试”可以这样表述:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”在鸭子类型中,关注点在于对象的行为,能作什么;而不是关注对象所属的类型。-- 摘自鸭子类型的维基百科简而言之就是:鸭子类型只关注能做什么,而不关注对象属于什么类型。只要走起路来像鸭子,那它就是鸭子。
如下:
class Animal(object): def run(self): print("The animal is running...") class Dog(Animal): def run(self): print('The dog is running...') class Cat(Animal): def run(self): print('The cat is running...') def makeRun(animalType): animalType.run() dog = Dog() cat = Cat() makeRun(dog) makeRun(cat)结果为:
The dog is running... The cat is running...我们可以使用一个函数 makeRun() 来访问不同 Animal 子类中的相同方法。但其实对于上面的 makeRun() 函数来说,传入的参数并不一定需要是 Animal 类型的,只需要保证传入的对象有一个 run() 方法即可,如下面代码所示。
class Person(object): def run(self): print("The person is running...") person = Person() makeRun(person) ---------------------------- The person is running...这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。 而在静态语言中,如 Java ,如果需要传入 Animal 类型,则传入的对象就必须是 Animal 类型或者它的子类,否则,将无法调用 run() 方法。
