Python-面向对象编程(OOP)

面向对象三大特性

其实这些概念性的东西,你不用去刻意记住,我觉得这些概念的诞生只是为了让众多程序员应用新的编程模式:面向对象,
在思考问题,建模的时候都能按照面向对象的思维模式进行,这样设计的软件层次清楚,模块一目了然,便于理解维护

  1. 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。封装是面向对象的特征之一,是对象和类概念的主要特性。 简单的说,一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。

  2. 继承,是指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的可供子类使用的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。 通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。继承概念的实现方式有二类:实现继承与接口继承。实现继承是指直接使用基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力;

  3. 多态,就是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用

Python中面向对象的例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/env /usr/local/bin/python3
# encoding: utf-8

"""
python 面向对象编程
@version: 0.1
@author: Gamelfie
@contact: fudenglong1417@gmail.com
@software: PyCharm
@file: test3.py
@time: 2017/3/15 16:54
"""


from abc import ABCMeta, abstractmethod


class Animal(object):

"""
声明一个抽象类Animal,抽象类不可实例化
"""
__metaclass__ = ABCMeta

def __init__(self, age, category, name):

self.age = age
self.__category = category
self.__name = name

def show_base_info(self):
print("我叫:%s, 我今年:%s岁, 我是%s类动物" %
(self.__name, self.age, self.__category))

def custom(self):
print("我是父类")

def __getattr__(self, item):
item = "_Animal__%s" % item
if item in self.__dict__:
return self.__dict__[item]

@abstractmethod
def run(self):
self.show_base_info()
pass


class Cat(Animal):

def __init__(self, age, *args, **kwargs):
name = "猫咪"
category = "猫科动物"
super(Cat, self).__init__(age=age,
category=category,
name=name)

def custom(self):
super(Cat, self).custom()
print("我是猫咪")

def run(self):
super(Cat, self).run()
print("我四条腿跑")


class Bird(Animal):

def __init__(self, age, *args, **kwargs):
name = "麻雀"
category = "鸟类"
super(Bird, self).__init__(age=age,
category=category,
name=name)

def custom(self):
super(Bird, self).custom()
print("我是麻雀")

def run(self):
super(Bird, self).run()
print("我不跑我飞")


def view_animal(animal):
assert isinstance(animal, Animal)
animal.show_base_info()

if __name__ == '__main__':
cat = Cat(13)
bird = Bird(4)

cat.run()
bird.run()
cat.custom()
bird.custom()

view_animal(cat)
view_animal(bird)

print(cat.name)


# "C:\Program Files (x86)\Python35-32\python.exe" D:/web/python_test/test3.py
# 我叫:猫咪, 我今年:13岁, 我是猫科动物类动物
# 我四条腿跑
# 我叫:麻雀, 我今年:4岁, 我是鸟类类动物
# 我不跑我飞
# 我是父类
# 我是猫咪
# 我是父类
# 我是麻雀
# 我叫:猫咪, 我今年:13岁, 我是猫科动物类动物
# 我叫:麻雀, 我今年:4岁, 我是鸟类类动物
# 猫咪

程序解释如下:

  1. 封装特性的实现

    Cat,Bird抽象成一个类,并且继承自更为一般的类:Animal(虚类,不可实例化)
    并且为各个类定义了相关属性以及方法,

    有的属于继承,例如属性:`name`和`category`
    有的属于扩展,例如方法:`custom`
    有的属于实现,例如方法:`run`
    

    实行属性私有化,Python中以两个下划线__开头的属性或者方法都属于私有属性和方法,只能在本类内部使用

  2. 继承特性的实现

    Cat,Bird 继承自Animal,拥有了Animal类定义的公有属性和方法:ageshow_base_info

  3. 多态特性的实现

    我们定义了一个函数:view_animal,由于Python中函数变量不可声明变量类型,但是我们在函数内部开头使用
    assert 断言,断定参数:animal是类Animal或者其子类的实例
    但是当函数定义时,函数view_animal并不知道要使用Cat类还是Bird类的show_base_info方法,只有当
    程序运行时,才知道真正的对象属于哪个具体的类,不过我们却在调用时使用了同一个方法,简化操作,这其实
    就是多态的表现

面向对象五大基本原则
  1. 单一职责原则SRP(Single Responsibility Principle)

    是指一个类的功能要单一,不能包罗万象
    
  2. 开放封闭原则OCP(Open-Close Principle)

    一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的
    
  3. 替换原则(the Liskov Substitution Principle LSP)

    子类应当可以替换父类并出现在父类能够出现的任何地方
    
  4. 依赖原则(the Dependency Inversion Principle DIP) 具体依赖抽象,上层依赖下层

    例如,一个应用,抽象成App,这个对象依赖于缓存(Cache),数据库(DB),但是不应该在App中直接
    依赖Cache,DB,而是应该将Cache,DB的操作定义为一组接口,在App中依赖接口CacheInterface,DBInterface,
    这样就解除了App对DB和Cache的直接依赖,将App依赖Cache和DB转换为Cache和DB依赖于App为其定义的一组接口,
    实现依赖倒置
    
  5. 接口分离原则(the Interface Segregation Principle ISP)

    模块间要通过抽象接口隔离开,而不是通过具体的类强耦合起来