命令式

  1. Python 的命令式语言是图灵完备的 - 即理论上可以做到其它任何语言能够做到的所有事情
    • 仅依靠汇编语言的 MOV 指令,就能实现图灵完备编程
  2. 传统的命令式语言有着无数重复性代码,虽然函数的诞生减缓了许多重复性
    • 但只有函数是不够的,需要把更加抽象的概念引入计算机才能缓解OOP

基本概念

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
class Document():
def __init__(self, title, author, context):
print('init function called')
self.title = title
self.author = author
self.__context = context # __context is private

def get_context_length(self):
return len(self.__context)

def intercept_context(self, length):
self.__context = self.__context[:length]


harry_potter_book = Document('Harry Potter', 'J. K. Rowling',
'... Forever Do not believe any thing is capable of thinking independently ...')

print(harry_potter_book.title)
print(harry_potter_book.author)

print(harry_potter_book.get_context_length())
harry_potter_book.intercept_context(10)
print(harry_potter_book.get_context_length())

print(harry_potter_book.__context) # AttributeError: 'Document' object has no attribute '__context'
Concept Desc
class 一群有着相同属性函数对象的集合
object 集合中的一个事物,由 class 生成 object
attribute 对象的某个静态特征
method 对象的某个动态能力
  1. __init__ 表示构造函数,即一个对象生成时会被自动调用的函数
  2. 属性以 __ 开头,表示该属性是私有属性

常量

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
class Document():
WELCOME_STR = 'Welcome! The context for this book is {}.'

def __init__(self, title, author, context):
print('init function called')
self.title = title
self.author = author
self.__context = context

def get_context_length(self):
return len(self.__context)

@classmethod
def create_empty_book(cls, title, author):
return cls(title=title, author=author, context='nothing')

@staticmethod
def get_welcome(context):
return Document.WELCOME_STR.format(context)


empty_book = Document.create_empty_book('What Every Man Thinks About Apart from Sex', 'Professor Sheridan Simove')

print(empty_book.get_context_length()) # 7
print(empty_book.get_welcome('indeed nothing')) # Welcome! The context for this book is indeed nothing.
  1. 在 Python 中,用全大写来表示常量
    • 类中,使用 self.WELCOME_STR;在类外,使用 Entity.WELCOME_STR
  2. 成员函数、类函数、静态函数 - 在 Java 中,类函数 ≈ 静态函数
    • 静态函数与类没有关联 - 第一个参数没有任何特殊性
    • 成员函数的第一个参数 - self - 当前对象的引用
    • 类函数的第一个参数 - cls - 类对象
  3. 静态函数 - @staticmethod - 装饰器
    • 一般用来处理简单独立的任务
  4. 类函数 - @classmethod - 装饰器
    • 一般用来实现不同的 init 构造函数,类似于工厂模式

继承

  1. 子类拥有父类的特征,同时拥有自己独特的特征
  2. 特征 - 类的属性函数
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
class Entity:
def __init__(self, object_type):
print('parent class init called')
self.object_type = object_type

def get_context_length(self):
raise Exception('get_context_length not implemented')

def print_title(self):
print(self.title)


class Document(Entity):
def __init__(self, title, author, context):
print('Document class init called')
Entity.__init__(self, 'document')
self.title = title
self.author = author
self.__context = context

def get_context_length(self):
return len(self.__context)


class Video(Entity):
def __init__(self, title, author, video_length):
print('Video class init called')
Entity.__init__(self, 'video')
self.title = title
self.author = author
self.__video_length = video_length

def get_context_length(self):
return self.__video_length


harry_potter_book = Document('Harry Potter(Book)', 'J. K. Rowling',
'... Forever Do not believe any thing is capable of thinking independently ...')
harry_potter_movie = Video('Harry Potter(Movie)', 'J. K. Rowling', 120)

print(harry_potter_book.object_type) # document
print(harry_potter_movie.object_type) # video

harry_potter_book.print_title() # Harry Potter(Book)
harry_potter_movie.print_title() # Harry Potter(Movie)

print(harry_potter_book.get_context_length()) # 77
print(harry_potter_movie.get_context_length()) # 120
  1. 每个都有构造函数
  2. 继承类生成对象的时候,是不会自动调用父类的构造函数 - 与 Java 不同
    • 必须在 init() 函数中显式调用父类的构造函数
    • 执行顺序:子类的构造函数 -> 父类的构造函数

抽象类 + 抽象函数

与 Java 一致

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
from abc import ABCMeta, abstractmethod


# ABC = Abstract Base Classes
class Entity(metaclass=ABCMeta):
@abstractmethod
def get_title(self):
pass

@abstractmethod
def set_title(self, title):
pass


class Document(Entity):
def __init__(self):
self.title = None

# def get_title(self):
# return self.title

def set_title(self, title):
self.title = title


document = Document() # TypeError: Can't instantiate abstract class Document with abstract methods get_title
document.set_title('Harry Potter')
print(document.get_title()) # Harry Potter

entity = Entity() # TypeError: Can't instantiate abstract class Entity with abstract methods get_title, set_title
  1. 抽象类是一种特殊的类,不能实例化
  2. 抽象函数定义在抽象类中,子类必须重写抽象函数
    • 如果子类继承了抽象类,只要没有完全实现抽象函数,那该子类也是抽象类,同样不能实例化
  3. 抽象函数使用 @abstractmethod 来表示
  4. 自上而下 - 先定义好规约