面向对象编程(Object-oriented Programming,简称 OOP),是一种封装代码的方法。其实,在前面章节的学习中,我们已经接触了封装,比如说,将乱七八糟的数据扔进列表中,这就是一种简单的封装,是数据层面的封装;把常用的代码块打包成一个函数,这也是一种封装,是语句层面的封装。
Python OOP简介
Python是一种多范式编程语言。意思是说,它支持不同的编程方法。
解决编程问题的一种流行方法是创建对象。也就是所谓的面向对象编程(OOP)。
一个对象具有两个特征:
属性
行为
让我们举个示例:
鹦鹉是一个物体,
名称,年龄,颜色是属性
唱歌,跳舞都是行为
Python中的OOP概念专注于创建可重用的代码。此概念也称为DRY(Don't Repeat Yourself)不要重复自己。
在Python中,OOP的概念遵循一些基本原则:
继承 | 使用新类的详细信息而不修改现有类的过程。 |
封装 | 对其他对象隐藏类的私有细节。 |
多态 | 对不同的数据输入以不同的方式使用通用操作的概念。 |
类(class)
类是对象的蓝图。
我们可以将类看作是带有标签的鹦鹉的素描。它包含有关名称,颜色,大小等的所有详细信息。基于这些描述,我们可以研究鹦鹉。在这里,鹦鹉是一个对象。
鹦鹉类的示例可以是:
class Parrot:
pass
在这里,我们使用class关键字来定义一个空类Parrot。我们从类中构造示例。示例是由特定类创建的特定对象。
对象(Object)
对象(示例)是类的示例。定义类时,仅定义对象的描述。因此,没有分配内存或存储。
鹦鹉类对象的示例可以是:
obj = Parrot()
在这里,obj是Parrot类的对象。
假设我们有鹦鹉的详细信息。下面,我们将展示如何构建鹦鹉的类和对象。
示例:在Python中创建类和对象
class Parrot:
# 类属性
species = "鸟"
# 示例属性
def __init__(self, name, age):
self.name = name
self.age = age
# 示例化Parrot类
blu = Parrot("麻雀", 10)
woo = Parrot("鹦鹉", 15)
# 访问类属性
print("麻雀是 {}".format(blu.__class__.species))
print("鹦鹉也是 {}".format(woo.__class__.species))
# 访问示例属性
print("{} 有 {} 岁".format( blu.name, blu.age))
print("{} 有 {} 岁".format( woo.name, woo.age))
当我们运行程序时,输出将是:
麻雀是 鸟
鹦鹉也是 鸟
麻雀 有 10 岁
鹦鹉 有 15 岁
在上面的程序中,我们创建一个名为Parrot的类。然后,我们定义属性。属性是对象的特征。
然后,我们创建Parrot类的示例。在这里,blu和woo是我们新对象的引用(值)。
然后,我们使用class .species访问class属性。类的所有示例的类属性都是相同的。类似地,我们使用blu.name和blu.age访问示例属性。但是,对于类的每个示例,示例属性都是不同的。
要了解有关类和对象的更多信息,请转到Python类和对象。
方法
方法是在类主体内定义的函数。它们用于定义对象的行为。
示例:在Python中创建方法
class Parrot:
# 示例属性
def __init__(self, name, age):
self.name = name
self.age = age
# 示例方法
def sing(self, song):
return "{} sings {}".format(self.name, song)
def dance(self):
return "{} is now dancing".format(self.name)
# 示例化对象
blu = Parrot("Blu", 10)
# 调用我们的示例方法
print(blu.sing("'Happy'"))
print(blu.dance())
当我们运行程序时,输出将是:
Blu sings 'Happy'
Blu is now dancing
在上面的程序中,我们定义了两种方法,即sing()和dance()。 这些之所以称为示例方法,是因为它们是在示例对象(即blu)上调用的。
继承性
继承是一种创建新类的方法,用于在不修改现有类的细节的情况下使用它。新形成的类是一个派生类(或子类)。类似地,现有类是基类(或父类)。
示例:在Python中使用继承
# 基类
class Bird:
def __init__(self):
print("鸟准备好了")
def whoisThis(self):
print("鸟")
def swim(self):
print("游得更快")
# 子类
class Penguin(Bird):
def __init__(self):
# call super() function
super().__init__()
print("企鹅准备好了")
def whoisThis(self):
print("企鹅")
def run(self):
print("跑得更快")
peggy = Penguin()
peggy.whoisThis()
peggy.swim()
peggy.run()
当我们运行该程序时,输出将是:
鸟准备好了
企鹅准备好了
企鹅
游得更快
跑得更快
在上面的程序中,我们创建了两个类,即Bird(父类)和Penguin(子类)。子类继承父类的功能。我们可以从swim()方法中看到这一点。子类再次修改了父类的行为。我们可以从whoisThis()方法中看到这一点。此外,我们通过创建新run()方法来扩展父类的功能。
另外,我们在init()方法之前使用super()函数。这是因为我们希望将init()方法的内容从父类拉到子类中。
可封装性
在Python中使用OOP,我们可以限制对方法和变量的访问。这样可以防止数据直接修改(称为封装)。在Python中,我们使用下划线作为前缀来表示私有属性,即单“ _”或双“ __”。
示例:Python中的数据封装
class Computer:
def __init__(self):
self.__maxprice = 900
def sell(self):
print("售价: {}".format(self.__maxprice))
def setMaxPrice(self, price):
self.__maxprice = price
c = Computer()
c.sell()
# 改变价格
c.__maxprice = 1000
c.sell()
# 使用setter函数
c.setMaxPrice(1000)
c.sell()
当我们运行该程序时,输出将是:
售价: 900
售价: 900
售价: 1000
在上面的程序中,我们定义了Computer类。我们使用__init__()方法存储计算机的最高售价。我们试图修改价格。但是,我们无法更改它,因为Python将__maxprice视为私有属性。要更改该值,我们使用了setter函数,即setMaxPrice(),它以price为参数。
多态性
多态性是一种功能(在OOP中),可以将公共接口用于多种形式(数据类型)。
假设我们需要给一个形状上色,有多个形状选项(矩形,正方形,圆形)。但是,我们可以使用相同的方法为任何形状着色。这个概念称为多态。
示例5:在Python中使用多态
class Parrot:
def fly(self):
print("鹦鹉会飞")
def swim(self):
print("鹦鹉不会游泳")
class Penguin:
def fly(self):
print("企鹅不会飞")
def swim(self):
print("企鹅会游泳")
# 通用接口
def flying_test(bird):
bird.fly()
#示例化对象
blu = Parrot()
peggy = Penguin()
# 传递对象
flying_test(blu)
flying_test(peggy)
当我们运行上面的程序时,输出将是:
鹦鹉会飞
企鹅不会飞
在上面的程序中,我们定义了两个类Parrot和Penguin。它们每个都有通用的fly()方法。但是,它们的功能不同。为了允许多态,我们创建了通用接口,即flying_test()可以接受任何对象的函数。然后,我们在flying_test()函数中传递了blu和peggy对象,它有效地运行了。
面向对象编程的要点:
让编程变得简单而有效。
类是可共享的,因此可以重复使用代码。
让编程人员的生产力提高
通过数据抽象,数据是安全的。