[python笔记] python的封装,继承,多态

面向对象的三大特征:

  1. 封装:属性和方法放到类内部,通过对象访问属性或者方法,隐藏功能的实现细节.当然还可以设置访问权限;

  2. 继承:子类需要复用父类里面的属性或者方法,当然子类还可以提供自己的属性和方法;

  3. 多态:同一个方法不同对象调用同一个方法功能的表现形式不一样,例如:1.不同的两个对象,字符串的加法和整数的加法,同样是加法,实现的功能是不一样的;2.这两个对象之间没有任何直接继承关系,但是所有对象的最终父类都是元类;


  这是我之前遇到过的面试题,问的比较深入,直面面向对象思想的本质,其实不管是封装,继承还是多态,它们的本质都是为了让程序员快速开发,提高代码的复用性,当然,你想用面向过程的思想写代码也是完全ojbk的,只要你的寿命足够长(苟1s)和你的领导足够耐心,不会因为你的又长又臭的代码开除你(奸笑),好了,闲话不扯那么多,开始正题:


 - 问题1.封装是什么,为什么要封装?

   封装的本质是将事物相关的属性和方法封装在一个类里面,我们调用类创建实例的时候,不用关心类内部的代码细节,相当于一个黑箱子,我们只需要该实例(黑箱)能给出我们想要的结果就好了。
   面向过程和面向对象的对比,如图所示:

对比图

   面向过程的本质就像是一个开放的箱子,所有的变量和方法都是暴露在外面的,一个线程下,所有的方法共享全局变量,这个全局变量可以被所有的方法修改,这就带来一个问题:如果一个方法f1想要全局变量只被它所用,但是其他方法肯定也要用的,这样就会造成变量修改的冲突;
   这时候类的概念应运而生,所有的变量和方法封装在类(黑箱子)内部,类属性相当于类内部的全局变量,实例属性相当于方法内部的局部变量,这样,只需要通过类创建不同实例a,b,c,d,实例a,b,c,d就可以将这些属性,方法全部私有化,随便实例自己怎么折腾。


总结:
 类的本质:
   1. 是将属性(全局变量),方法(函数)都封装在一个黑盒子里面;
   2. 类里面的方法可以共享属性,属性的修改不会影响类的外部变量,这就是类的封装产生的优势;
   3. 同时类可以被继承,子类可以拥有和父类一样的属性和方法;
   4. 并且子类可以有新的属性,新的方法,


   这样我们就避免了重复创造函数,提高代码的复用性和扩展性;


 - 问题2.继承是什么,为什么要继承,什么是单继承,什么是多继承,继承链又是什么?

   段子:猫儿子:爸,我为什么长的和你不一样,我是黄白相间的,妈妈是白色的,为什么爸爸你是绿色的,我朋友都说我长得像隔壁猫叔叔老黄(王)。猫爸:….,儿子,你等下,我去找隔壁黄叔叔聊一聊人生(物理意义上的)。
   哈哈,其实继承就是指子类继承父类的属性和方法,单继承就是指单亲家庭,父类自我繁殖了一个子类,子类相当于copy了父类,但是子类是可以突变的,可以自我重构父类的方法和属性,变成和父类不一样的类;
   多继承就是指子类有很多爸爸妈妈(不止一对父母),继承了所有爸妈们的属性和方法,如果子类继承的父类中有好几个方法重名,都叫run,那么如果子类要用父类的run方法,肯定就会冲突,为了解决这个问题,自然而然就有了继承链,子类继承父类时是有顺序的,那么子类用的run方法就是根据继承链找到的第一个拥有该方法名run的父类的run方法;


 - 问题3.什么是多态,多态的例子,python的多态和java的多态的区别,什么是鸭子类型?

   多态,一句话概括:同一个方法,不同对象调用该方法,实现的功能不一样,最直观的例子就是python中的”+”运算方法,在数字相加时,1+2=3,是正常意义上的加法,但是,’a’ + ‘b’ = ‘ab’,就是字符串的拼接,用在列表上:[1] + [2] = [1, 2],就是列表拼接;
   同样的方法名,用在不同对象上,实现的功能完全不一样,这就是多态;
   多态在python很常见,只是我们很难去注意到它,例如乘法运算符*,正常乘法:1*2=2,字符串乘法:’-‘*5 => ‘—–’;模运算:10%3=1,字符串格式化:’hello %s’ % ‘python’。
   鸭子类型指的就是哪怕两个对象是继承不同的父类,只要对象a和b中都有同名的方法fly,a对象能调用fly做的事情,b也能做到,代码如下:
# 定义鸟类
class Bird(object):
    def fly(self):
        print('鸟飞起来')

class Swan(Bird):
    def fly(self):
        print('天鹅飞起来')

class Animal(object):
    def eat(self):
        print('吃')

class Duck(Animal):
    #提示:在其他语言多态是要区分类型的,是当前的类型或者当前类的子类的类型
    #在Python里面多态不关心类型,只关心对象是否有对应的方法,只关心fly()这个方法
    def fly(self):
        print('鸭子飞起来')

def flyTwice(Bird):
    Bird.fly()
    Bird.fly()

duck1 = Duck()
flyTwice(duck1)
# 结果
鸭子飞起来
鸭子飞起来

总结:

  封装,继承和多态的本质目的都是为了快速开发,提高代码复用性。
发布了26 篇原创文章 · 获赞 23 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/simuLeo/article/details/80067619