面向对象
- 类:用来描述具有相同的属性和方法的对象的集合,它定义了该集合中每个对象所共有的属性和方法。
- 属性:对象的静态特征。变量(类变量、实例变量)。
- 方法:对象的动态行为。函数。方法的第一个参数必须是 self,不能省略。
- 对象:是通过类定义的实例(Instance),也叫实例对象(Instance Objects)。创建对象也叫“类的实例化”。
类
class ClassName: # 类的名称大写字母开头
<statement-1>
……
<statement-N>
例:
# dog.py
class Dog:
"""关于类的一个简单例子"""
# 属性
color = 'yellow'
weight = 10
legs = 4
# 方法
def run(self):
print("跑来跑去")
def bite(self):
print("汪汪咬人")
def eat(self):
print("吃吃吃^_^")
创建实例对象(以上类的实例化):
# run module
>>> puppy = Dog()
>>> puppy.bite()
汪汪咬人
>>> puppy.run()
跑来跑去
>>> puppy.eat()
吃吃吃^_^
例:
# 定义类 People
class People:
def __init__(self, name, age, place): #属性,初始化方法
self.name = name # 姓名
self.age = age # 年龄
self.place = place # 出生地
def speak(self): # 方法
return (self.name + ' can speak.')
def walk(self):
return (self.name + ' can walk.')
def sing(self):
return (self.name + ' can sing.')
def info(self):
return ('%s is %d years old, and born in %s.' % (self.name, self.age, self.place))
# 创建 People 的对象 Roy
if __name__ == '__main__':
roy = People('Roy', 38, 'Jilin') # 创建对象,并赋值
print(roy.speak())
print(roy.walk())
print(roy.sing())
print(roy.info())
'''
Roy can speak.
Roy can walk.
Roy can sing.
Roy is 38 years old, and born in Jilin.
'''
方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。例:(子类Suv含方法重写案例)
# 父类 Car
class Car(): # class:类关键字;Car:类名
def __init__(self, color, doors, tires, type): #初始化,定义四个属性
self.color = color # 车的颜色
self.doors = doors # 车的门
self.tires = tires # 车轮胎
self.type = type # 车类型
def stop(self): # 方法,车的动作:停止
return '%s is stopping.' % self.type
def drive(self): # 方法,车的动作:开车
return 'I am driving the %s ' % self.type
# 子类 Suv
class Suv(Car): # Suv 类继承父类 Car 类所有属性和方法。
def drive(self): # 重写 drive 方法(称为:方法的覆盖、方法的重写)
return 'I am driving the awsome SUV, it is %s.' % self.type
if __name__ == '__main__':
suv = Suv('black', 4, 4, '卡宴') # 调用 Suv类,创建了一个suv对象:卡宴
print(suv.stop()) # 调用car的方法,停车
print(suv.drive()) # 调用car的方法,行驶
'''
卡宴 is stopping.
I am driving the awsome SUV, it is 卡宴.
'''
例:
### 第一步:定义一个类 ###
class Teacher:
'''老师类'''
teacherCount = 0 # 类变量,在这个类的所有实例之间共享。可在内部类和外部类被访问
# init方法是一种特殊的方法,被称为类的构造函数或初始化方法,
# 当创建了这个类的实例时就会调用该方法。
def __init__(self, name, salary):
self.name = name
self.salary = salary
Teacher.teacherCount += 1 # 访问类变量
# self代表类的实例,self在定义类的方法时必须要有,虽然在调用时不必传入相应的参数
# self不是Python关键字,我们可以把它换成任何名字
def displayCount(self):
print('Total Teachers: %d ' % Teacher.teacherCount)
def displayTeacher(self):
print('Name:', self.name, ', Salary', self.salary)
### 第二步:创建实例对象 ###
teacher1 = Teacher('John', 5000) # 创建Teacher类的第一个对象
teacher2 = Teacher('Marry', 6000) # 创建Teacher类的第一个对象
### 第三步:访问属性 ###
teacher1.displayCount() # 使用点号来访问对象的属性
teacher1.displayTeacher()
teacher2.displayTeacher()
'''
Total Teachers: 2
Name: John , Salary 5000
Name: Marry , Salary 6000
'''
面向对象(Object Oriented)的特征
封装:封装了属性和方法。信息隐蔽技术,隐藏具体实现过程。如:BIF
继承:子类自动共享父类之间数据和方法的机制。
>>> class Mylist(list): # 继承 list 列表
pass
>>> listabc = Mylist() # 实例化,赋值给变量
>>> listabc.append(5)
>>> listabc.append(3)
>>> listabc.append(9)
>>> listabc
[5, 3, 9]
>>> listabc.sort()
>>> listabc
[3, 5, 9]
多态:不同对象对同一方法相应不同的行动
>>> class A:
def fun(self):
print('我是A')
>>> class B:
def fun(self):
print('我是B')
>>> a = A()
>>> b = B()
>>> a.fun()
我是A
>>> b.fun()
我是B
self
相当于 C++ 的 this 指针。由同一个类可以生成无数个对象,当一个对象的方法被调用的时候,对象会将自身的引用作为第一个参数传给该方法,Python 就知道需要操作哪个对象的方法了。
class Ball:
def setName(self, name): # 方法
self.name = name
def kick(self): # 方法
print("我叫%s,该死的,谁踢我..." % self.name)
a = Ball() # 实例
a.setName('球A') # 第一个参数self告诉Python是a对象在调用方法,因为是隐藏的并且由Python自己传入,所以这里不需写进来。
b = Ball()
b.setName('球B')
c = Ball()
c.setName('土豆')
a.kick()
b.kick()
c.kick()
'''
我叫球A,该死的,谁踢我...
我叫球B,该死的,谁踢我...
我叫土豆,该死的,谁踢我...
'''
类的专有方法(魔法方法 Magic Method)
__init__
被称为:类的构造函数或初始化方法,在生成对象时调用。只要实例化一个对象,这个方法就会在对象被创建时自动调用。
class Ball:
def __init__(self, name):
self.name = name
def kick(self):
print("我叫%s,该死的,谁踢我..." % self.name)
b = Ball('土豆')
b.kick()
'''
我叫土豆,该死的,谁踢我...
'''
__del__
析构函数,释放对象时使用
__repr__
打印,转换
__setitem__
按照索引赋值
__getitem__
按照索引获取值
__len__
获得长度
__cmp__
比较运算
__call__
函数调用
__add__
加运算
__sub__
减运算
__mul__
乘运算
__truediv__
除运算
__mod__
求余运算
__pow__
乘方
公有和私有
class Person:
name = '小甲鱼'
p = Person()
print(p.name)
'''
小甲鱼
'''
采用名字改编(name mangling)的技术实现类似私有变量的特征,变量名或函数名前加上两个下划线“__”即成为私有。
class Person:
__name = '小甲鱼'
p = Person()
print(p.__name)
'''报错:
AttributeError: 'Person' object has no attribute '__name'
'''
在外部将变量名”隐藏“起来了。如果要访问,就需要从内部进行:
class Person:
__name = '小甲鱼'
def getName(self):
return self.__name
p = Person()
print(p.getName()) # 从内部
'''
小甲鱼
'''
Python 的私有机制是”伪私有“,类是没有权限控制的,所有变量都可以被外部调用。
在外部使用”_类名__变量名“即可访问私有变量:
class Person:
__name = '小甲鱼'
def getName(self):
return self.__name
p = Person()
print(p._Person__name)
'''
小甲鱼
'''
继承