面向对象编程
面向对象编程-------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))