19.python面向对象编程(二)——三大特性

1)封装

接着上面讲的,我们之前提过,类里面不光有数据还有方法。这种将数据通过方法直接在类内部操作的形式叫做封装。这里的封装是把数据封装在类内部。这样对类形成了一种“黑盒”状态,我们不需要知道类内部是什么样的。只要对对象进行操作就可以。

再回到上篇讲的数据访问限制,我们讲到既想将数据保护起来,又想在一定程度上对数据进行操作。这里就可以用到这个特性,我们可以在类中,设定一个方法,get_eyes()来得到数据,modify_eyes()来修改数据。示例如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
class Animal(object):
    def __init__(self,legs,eyes):
        self.__legs=legs
        self.__eyes=eyes
    def get_eyes(self):
        return self.__eyes
    def modify_eyes(self,eyes):
        self.__eyes=eyes
wolf=Animal(4,2)
print (wolf.get_eyes())

这样我们就又可以访问,得到数据了。我们这里再想一下,我们还可以对数据进行筛选操作,防止错误数据传入对朝鲜造成破坏。示例代码如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
class Animal(object):
    def __init__(self,legs,eyes):
        self.__legs=legs
        self.__eyes=eyes
    def get_eyes(self):
        return self.__eyes
    def modify_eyes(self,eyes):
        if 0<=eyes<=4:
             self.__eyes=eyes
        else:
             raise ValueError('Bad Data')
wolf=Animal(4,2)
wolf.modify_eyes(5)
print(wolf.get_eyes())
输出结果如下:
raise ValueError('Bad Data')
ValueError: Bad Data
这里起到了保护程序的作用,你可能已经注意到。
0<=eyes<=4:

这是允许的。python大法好。/撒花

最后要注意一点。可能有人想这么修改:

wolf=Animal(4,2)
wolf.__eyes=3
print(wolf.get_eyes())

但实际上,是修改不了的。

输出结果:

2
2)继承

继承这个概念是用来描述类与类之间的关系的。顾名思义,子类可以从父类继承内容。比如我们已经定义了一个Animal类,代码如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
class Animal(object):
      def eat(self):
          print ("animal can eat")
      def sleep(self):
          print ("animal can sleep")
      def birth(self):
          print ("animal can birth")
class Dog(Animal):
     pass
black_dog=Dog()
black_dog.eat()
black_dog.sleep()
black_dog.birth()

输出结果:

animal can eat
animal can sleep
animal can birth

这就是继承,什么都不用干,实例black_dog()就有了animal的所有方法。这就是继承的好处,我们也可以对子类增加一些方法:

class Dog(Animal):
     def bark(self):
         print("Wow Wow")

但是美中不足的是,我们可以从上面看到,输出依然是:animal can....。这是很不舒服的,我们是否可以对子类进行改进呢?答案是可以的。示例代码如下:

class Dog(Animal):
     def bark(self):
         print("Wow Wow")
     def eat(self):
         print("Dog can eat")

     def sleep(self):
         print("Dog can sleep")

     def birth(self):
         print("Dog can birth")

输出结果是:

Dog can eat
Dog can sleep
Dog can birth
Wow Wow

很高兴,我们成功了。这就是面向对象的第三个特性——多态。

3)多态

要了解多态,我们先再定义一个函数:

def eat_twice(Animal):
    Animal.eat()
    Animal.eat()
eat_twice(Dog())

输出结果:

Dog can eat
Dog can eat

我们可能感觉没什么?但是在继承一个新的类,cat。

class Cat(Animal):
     def eat(self):
         print("Cat can eat")
def eat_twice(Animal):
    Animal.eat()
    Animal.eat()
eat_twice(Dog())
eat_twice(Cat())
Dog can eat
Dog can eat
Cat can eat
Cat can eat

我们发现不必对eat_twice做修改就可以用,所定义的语句,直接变成了;

Dog.eat()
Dog.eat()
Cat.eat()
Cat.eat()

注意:

这就是多态的好处。我们不必再在意所调用的子类型具体是什么,也不用在意子类型的方法有什么修改。只要子类型与父类型有同样的方法,就可以调用该子类型变量。具体方法由当时使用的情况(即,这个实例是什么子类)决定。这就是多态的强大之处,以及精华之处。

同理:

如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来就不行。

子可以看成父,但父不可以看成子

希望有志同道合的小伙伴关注我的公众平台,欢迎您的批评指正。








没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试

关闭