面向对象编程

面向对象编程

参考廖雪峰的Python教程

面向对象编程-------Object Oriented Programming(OOP)

Python面向对象编程三大特点:

  • 数据封装
  • 继承
  • 多态
  • 鸭子类型

1、数据封装

这里我们定义一个Cat类,每个实例都可以拥有name和age属性,我们可以调用内部方法来访问这些数据,这样就把数据封装起来了,这些封装数据的函数本身是与Cat类相关联的,我们称之为“类的方法”

# -*- coding:utf-8 -*-
class Cat(object):
    """数据封装
    1、每个Cat实例都有name、age属性,我们可以通过函数来访问这些数据
    2、__init__()方法:根据Cat类创建实例时都会调用它,并初始化实例的属性
    3、self就是实例本身
    """
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def play(self):
        print('%s is %s years old and he is playing with another cat!' % (self.name, self.age))


# 创建实例
c = Cat('fat', 2)
# 实例调用play方法
c.play()



>>> fat is 2 years old and he is playing with another cat!


封装的另外一个好处就是可以给Cat类再增加一个新的方法


  def sleep(self):
        print('%s is tired, he want to sleep!' % (self.name.title(),))



>>> Fat is tired, he want to sleep!

2、继承

继承的好处时子类获得父类所有的功能,这里先定义一个Animal类

# -*- coding:utf-8 -*-
class Animal(object):
    def run(self):
        print('Animal is running!')


a = Animal()
a.run()

>>> Animal is running!

这里再定义Cat类和Dog类,它们都继承自Animal,Animal是Cat和Dog的父类(超类或基类),而Cat和Dog是Animal的子类。Cat和Dog继承Animal后自动获得了Animal类的run方法

# -*- coding:utf-8 -*-
class Animal(object):
    def run(self):
        print('Animal is running!')


class Cat(Animal):
    pass


class Dog(Animal):
    pass


c = Cat()
d = Dog()
c.run()
d.run()

这里我们给子类增加run方法,当子类和父类都存在run方法时,子类覆盖掉父类方法,所以输出是
Cat is running!
Dog is running!

# -*- coding:utf-8 -*-
class Animal(object):
    def run(self):
        print('Animal is running!')


class Cat(Animal):
    def run(self):
        print('Cat is running!')


class Dog(Animal):
    def run(self):
        print('Dog is running!')


c = Cat()
d = Dog()
c.run()
d.run()

>>> Cat is running!
    Dog is running!


3、多态

当我们定义class的时候就定义了一种数据类型,这里用isinstance()函数来判断对象是否是已知的类型


a = list()
b = Animal()
c = Cat()

print(isinstance(a, list))
print(isinstance(b, Animal))
print(isinstance(c, Cat))


>>> True
    True
    True

判断都为True,这里可以试下isinstance(c, Animal)是什么结果,Cat的实例c继承自Animal,所以c也是Animal类型


print(isinstance(c, Animal))

>>> True

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

Cat可以被看成Animal,但Animal不能被看成Cat

isinstance(c, Cat)


b = Animal()

print(isinstance(b, Cat))

>>> False


再编写一个函数来来理解多态,每当我们传入实例,就打印出各个类相应的结果


def run_twice(animal):
    animal.run()
    animal.run()


run_twice(Animal())
run_twice(Cat())
run_twice(Dog())



>>> Animal is running!
    Animal is running!
    Cat is running!
    Cat is running!
    Dog is running!
    Dog is running!


这里我们再增加Lion子类

class Lion(Animal):
    def run(self):
        print('Lion is running!')


>>> Lion is running!
    Lion is running!

Animal类型有run方法,只要传入的任意类型是animal类或者子类就会自动调用自己的run方法

鸭子类型

  • 一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。也可以这样理解,并不关心对象是什么类型,到底是不是鸭子,只关心行为

我们再增加一个子类,它不是animal类型,只要它有一个run()方法就可以了(只关心它的行为,而不关心它到底是不是animal)

class Timer(object):
    def run(self):
        print('Start........')

>>> Start........
    Start........

完整代码


# -*- coding:utf-8 -*-
class Animal(object):
    def run(self):
        print('Animal is running!')


class Cat(Animal):
    def run(self):
        print('Cat is running!')


class Dog(Animal):
    def run(self):
        print('Dog is running!')


class Lion(Animal):
    def run(self):
        print('Lion is running!')


class Timer(object):
    def run(self):
        print('Start........')


a = list()
b = Animal()
c = Cat()


def run_twice(fish):
    fish.run()
    fish.run()


run_twice(Animal())
run_twice(Cat())
run_twice(Dog())
run_twice(Lion())
run_twice(Timer())


print(isinstance(a, list))
print(isinstance(b, Animal))
print(isinstance(c, Cat))

print(isinstance(c, Animal))

print(isinstance(b, Cat))


欢迎访问Treehl的博客
Github

你可能感兴趣的:(面向对象编程)