[Python] (Day-17) - 面向对象
面向对象编程(Object-Oriented Programming
)介绍
OOP
编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述,使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率;
基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容。
面向对象的几个核心特性:
类 - Class
一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的都具备的属性(variables(data))、共同的方法
对象 - Object
一个对象即是一个类的实例化后实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性,就像人类是指所有人,每个人是指具体的对象,人与人之前有共性,亦有不同
封装 - Encapsulation
在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法
继承 - Inheritance
一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承
多态 - Polymorphism
多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,指一个基类中派生出了不同的子类,且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态。
Python就是一门面向对象的语言
类定义
格式:
class ClassName(object):
.
.
.
实例:
class Dog(object):
print("it's a Dog class")
类对象
实例:
class MyClass(object):
"""一个简单的类实例"""
# 属性
num = 666
# 方法
def sayHello(self):
return 'hello world'
# 实例化类
x = MyClass()
# 访问类的属性和方法
print(x.i) # 666
print(x.f()) # hello world
构造方法
很多类都倾向于将对象创建为有初始状态的。因此类可能会定义一个名为
__init__()
的特殊方法
class MyClass(object):
"""一个简单的类实例"""
def __init__(self):
self.name = "Mazy"
# 实例化类
x = MyClass()
print(x.name) # Mazy
__init__()
方法可以有参数,参数通过__init__()
传递到类的实例化操作上
class ComplexClass(object):
def __init__(self, a, b):
self._a = a
self._b = b
x = ComplexClass("Mazy", 666)
print(x._a, x._b) # 输出结果:Mazy 666
self
代表类的实例,而非类
class Test:
def iprint(self):
print(self)
print(self.__class__)
t = Test()
t.iprint()
打印结果:
<__main__.Test object at 0x1022439e8>
<class '__main__.Test'>
类的方法
在类的内部,使用
def
关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数self
, 且为第一个参数,self
代表的是类的实例
实例:
# 类定义
class people(object):
# 定义基本属性
name = ""
age = 0
# 定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
# 定义构造方法
def __init__(self, n, a, w):
self.name = n
self.age = a
self.__weight = w
def talk(self):
print("%s 说: 我 %d 岁。" % (self.name, self.age))
# 实例化类
p = people('Vivian', 21, 48)
p.talk() # Vivian 说: 我 21 岁。
单继承
格式:
class DerivedClassName(BaseClassName):
.
.
.
基类定义在另一个模块中时这一点非常有用:
class DerivedClassName(modname.BaseClassName):
实例:
# 类定义
class people(object):
# 定义基本属性
name = ""
age = 0
# 定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
# 定义构造方法
def __init__(self, n, a, w):
self.name = n
self.age = a
self.__weight = w
def talk(self):
print("%s 说: 我 %d 岁。" % (self.name, self.age))
# 单继承示例
class student(people):
grade = ''
# 重写构造函数,添加参数
def __init__(self, n, a, w, g):
# 调用父类的构函
people.__init__(self, n, a, w)
self.grade = g
# 覆写父类的方法
def talk(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级" % (self.name, self.age, self.grade))
s = student("Eric", 8, 68, 3)
s.talk() # Eric 说: 我 8 岁了,我在读 3 年级
多继承
格式:
class DerivedClassName(Base1, Base2, Base3):
.
.
.
实例:
class baseClassA(object):
name = ""
def __init__(self, n):
self.name = n
def sayHi(self):
print("Hi ", self.name)
class baseClassB(object):
song = ""
def __init__(self, s):
self.song = s
def sing(self):
print("sing ", self.song)
class baseClassC(baseClassA, baseClassB):
hobby = ""
def __init__(self, n, s, h):
baseClassA.__init__(self, n)
baseClassB.__init__(self, s)
self.hobby = h
robot = baseClassC("Joy", "God is friend", "dance")
robot.sing() # sing God is friend
robot.sayHi() # Hi Joy
方法重写
如果父类方法的功能不能满足子类的需求,可在子类重写你父类的方法
class Parent: # 定义父类
def myMethod(self):
print ('调用父类方法')
class Child(Parent): # 定义子类
def myMethod(self):
print ('调用子类方法')
c = Child() # 子类实例
c.myMethod() # 子类调用重写方法
类属性与方法
类的私有属性
__private_attrs
:两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs
。
类的方法
在类地内部,使用def
关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self
,且为第一个参数,self
代表的是类的实例。
self
的名字并不是规定死的,也可以使用 this
,但是最好还是按照约定是用 self
。
类的私有方法
__private_method
:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类地外部调用。self.__private_methods
。
实例:
class Site:
__secretCount = 0 # 私有变量
publicCount = 0 # 公开变量
def __init__(self, name, url):
self.name = name # 公开属性
self.__url = url # 私有属性
def __foo(self): # 私有方法
print('这是私有方法')
def foo(self): # 公共方法
print('这是公共方法')
self.__foo()
类的专有方法总结:
方法名 | 介绍 |
---|---|
__init__ |
构造函数,在生成对象时调用 |
__del__ |
析构函数,释放对象时使用 |
__repr__ |
打印,转换 |
__setitem__ |
按照索引赋值 |
__getitem__ |
按照索引获取值 |
__len__ |
获得长度 |
__cmp__ |
比较运算 |
__call__ |
函数调用 |
__add__ |
加运算 |
__sub__ |
减运算 |
__mul__ |
乘运算 |
__div__ |
除运算 |
__mod__ |
求余运算 |
__pow__ |
乘方 |
运算符重载
对类的专有方法进行重载
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self,other):
return Vector(self.a + other.a, self.b + other.b)
v1 = Vector(2, 10) # 等效于:v1.a = 2, v1.b = 10
v2 = Vector(5, -2) # 等效于:v2.a = 5, v2.b = -2)
print (v1 + v2) # 等效于: v1.1 + v2.1, v1.b + b2.b
打印结果:
Vector (7, 8)