目录
1. 面向对象简介
- 面向对象与面向过程
2. 类定义及应用
- 类的组成
- self参数
- 特殊方法
3. 面向对象三大特征
- 封装
- 继承
- 多态
课堂笔记
1. 面向对象简介
1.1 面向对象与面向过程
- 面向对象:将现实中每一个实体抽象成对象,然后在对象的级别上进行操作
- 面向过程:关注每一个过程,直接将所需功能写成一个函数,对函数进行操作,故也可理解为面向函数的
class 类名([父类]):
代码块
2. 类定义及应用
2.1 类的组成
-
属性(数据)
- 实例属性 即实例化对象添加的私有属性
- 类属性 在类中直接定义的属性
-
方法(行为)
- 实例方法 以self为第一默认关键字的方法
- 类方法 以@classmethod修饰的方法,第一参数为默认cls参数,为类对象
- 静态方法 以@staticmethod修饰的方法,基本与当前类无关,只是保存在当前类的一个函数
- 区别:
- 均可通过实例对象和类调用,但实例方法被类调用时须自己传入self参数,即当前调用对象
-
类中可自定义属性和方法,该属性和方法都会成为该类的公共部分
-
可通过 对象.方法名() 或 对象.属性名 进行调用
# 定义一个类Person,父类为object
class Person(object):
# 定义一个属性 name
name = '钢铁侠'
# 定义一个方法 speak
def speak(self):
print('My name is', self.name)
if __name__ == '__main__':
# 实例化一个类
person = Person()
person.speak() # My name is 钢铁侠
2.2 self参数
- 类中定义的方法都默认自带一个参数self,表示当前调用该类的对象实例,调用时自动传入
- 每一个对象可创建自己的私有属性(方法),该属性(方法)为当前对象所私有,并不与其他对象共享,这与公共属性(方法)不同
class Person(object):
# 定义一个方法 speak
def speak(self): # self 为默认参数
print('My name is', self.name)
if __name__ == '__main__':
# 实例化3个Person对象
person = Person()
person2 = Person()
person3 = Person()
# 为后两个对象都定义一个私有属性 name
person2.name = '绿巨人'
person3.name = '美国队长'
person2.speak() # My name is 绿巨人
person3.speak() # My name is 美国队长
# 该对象下并无 name 属性
person.speak() # AttributeError: 'Person' object has no attribute 'name'
2.3 特殊方法
-
以--开头,以--结尾的方法,如__init__方法,用于属性初始化
-
特殊方法不需要我们调用,会在创建对象的时候自动调用
-
上面代码可更该为
class Person(object):
# 调用__init__方法
def __init__(self, name):
self.name = name
# 定义一个方法 speak
def speak(self):
print('My name is', self.name)
if __name__ == '__main__':
# 实例化2个Person对象
person2 = Person('绿巨人')
person3 = Person('美国队长')
person2.speak() # My name is 绿巨人
person3.speak() # My name is 美国队长
3. 面向对象三大特征
3.1 封装
- 作用:
- 对属性(方法)封装,防止被外界随意调用或修改
- 隐藏类的内部结构,提升安全性
- 使用get与set方法
class Person(object):
# 定义set方法
def set_Name(self, name):
self.name = name
# 定义get方法
def get_Name(self):
return self.name
if __name__ == '__main__':
# 实例化Person类
person = Person()
person.set_Name('钢铁侠')
print(person.get_Name()) # 钢铁侠
- 使用__属性名,只能以 对象._类名__属性名 的形式调用 或者 在类的内部使用
- 一般情况下,以__开头的属性代表私有属性,无特殊情况不要修改
class Person(object):
def __init__(self, name):
# 定义 __属性名 形式的属性
self.__name = name
if __name__ == '__main__':
# 实例化Person类
person = Person('钢铁侠')
# 该属性不存在
print(person.__name) # AttributeError: 'Person' object has no attribute '__name'
print(person._Person__name) # 钢铁侠
- 使用@property创建只读属性,会将方法转换成相同名称的只读属性
class Book(object):
# 定义__init__方法
def __init__(self, bName, isbn):
self.name = bName
self.ISBN = isbn
# 使用装饰器定义只读属性
@property
def read(self):
return 'name: ' + self.name + ' ISBN: ' + self.ISBN
if __name__ == '__main__':
book = Book('Python爬虫入门', '98532115')
print(book.read) # name: Python爬虫入门 ISBN: 98532115
3.2 继承
-
为什么有继承:
- 使各个类相联系起来,而不是各自独立的
- 对具有相同特性的对象使用公共属性,避免代码冗余,提高了类的复用性
-
特性:
- 每个类可继承多个类,具有顺序性
- 子类继承父类后,子类也继承了父类所有的属性与方法,即父类有的子类也有
- 子类可对父类方法进行重写,该方法会对父类同名方法进行覆盖
- 子类对象调用某个方法时,会优先查找离自己最近的,即自己有,调自己的,否则查找父类,直到找到或方法不存在(报错)
# 定义一个水果类
class Fruit(object):
def __init__(self, name):
# 定义一个name属性
self._name = name
# 定义一个方法,显示信息
def show(self):
print('My name is', self._name)
# 新建Apple,并继承Fruit类
class Apple(Fruit):
def __init__(self, name, color):
# 调用super()获取父类并调用父类初始化方法
super().__init__(name)
# 定义新属性
self._color = color
# 重写方法
def show(self):
print('My name is', self._name, ', my color is', self._color)
if __name__ == '__main__':
# 实例化一个Fruit对象
f = Fruit('Apple')
f.show() # My name is Apple
# 实例化Apple对象
a = Apple('Apple', 'red')
a.show() # My name is Apple , my color is red
3.3 多态
-
让多个不同对象的方法具有相同方法名,调用时就可以根据具体需求实现不同的功能
-
特点:
- 增加了代码外部调用的灵活性,让代码更加通用
- 对象所属的类之间,继承关系可有可无
# 定义一个Plane类
class Plane(object):
# 定义fly方法
def fly(self):
print('看, 有飞机...')
# 定义一个Bird类
class Bird(object):
# 定义fly方法
def fly(self):
print('看, 有鸟...')
# 定义一个fly函数,可根据具体类对象调用方法
def fly(cls):
cls.fly()
if __name__ == '__main__':
p = Plane()
fly(p) # 看, 有飞机...
b = Bird()
fly(b) # 看, 有鸟...