41.md 7.7 KB
Newer Older
W
wizardforcel 已提交
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
# Python 面向对象编程

> 原文: [https://www.programiz.com/python-programming/object-oriented-programming](https://www.programiz.com/python-programming/object-oriented-programming)

#### 在本教程中,您将借助示例来学习 Python 中的面向对象编程(OOP)及其基本概念。

## 面向对象编程

Python 是一种多范式编程语言。 它支持不同的编程方法。

解决编程问题的一种流行方法是创建对象。 这就是所谓的面向对象编程(OOP)。

对象具有两个特征:

*   属性
*   行为

让我们举个例子:

鹦鹉可以是一个对象,因为它具有以下属性:

*   名称,年龄,颜色作为属性
*   唱歌,跳舞作为行为

Python 中的 OOP 概念专注于创建可重用的代码。 此概念也称为 DRY(不要重复自己)。

在 Python 中,OOP 的概念遵循一些基本原则:

* * *

## 类

类是对象的蓝图。

我们可以将类看作是带有标签的鹦鹉的素描。 它包含有关名称,颜色,大小等的所有详细信息。基于这些描述,我们可以研究鹦鹉。 在这里,鹦鹉是一个对象。

鹦鹉类的示例可以是:

```py
class Parrot:
    pass
```

W
wizardforcel 已提交
44
在这里,我们使用`class`关键字定义一个空类`Parrot`。 从类中,我们构造实例。 实例是从特定类创建的特定对象。
W
wizardforcel 已提交
45 46 47

* * *

W
wizardforcel 已提交
48
## 对象
W
wizardforcel 已提交
49 50 51 52 53 54 55 56 57

对象(实例)是类的实例。 定义类时,仅定义对象的描述。 因此,没有分配内存或存储。

鹦鹉类对象的示例可以是:

```py
obj = Parrot()
```

W
wizardforcel 已提交
58
在此,`obj`是类别`Parrot`的对象。
W
wizardforcel 已提交
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96

假设我们有鹦鹉的详细信息。 现在,我们将展示如何构建鹦鹉的类和对象。

### 示例 1:在 Python 中创建类和对象

```py
class Parrot:

    # class attribute
    species = "bird"

    # instance attribute
    def __init__(self, name, age):
        self.name = name
        self.age = age

# instantiate the Parrot class
blu = Parrot("Blu", 10)
woo = Parrot("Woo", 15)

# access the class attributes
print("Blu is a {}".format(blu.__class__.species))
print("Woo is also a {}".format(woo.__class__.species))

# access the instance attributes
print("{} is {} years old".format( blu.name, blu.age))
print("{} is {} years old".format( woo.name, woo.age))
```

**输出**

```py
Blu is a bird
Woo is also a bird
Blu is 10 years old
Woo is 15 years old
```

W
wizardforcel 已提交
97
在上面的程序中,我们创建了一个名为`Parrot`的类。 然后,我们定义属性。 属性是对象的特征。
W
wizardforcel 已提交
98 99 100

这些属性在类的`__init__`方法中定义。 创建对象后,首先运行的是初始化方法。

W
wizardforcel 已提交
101
然后,我们创建`Parrot`类的实例。 这里,`Blu``woo`是我们新对象的参考(值)。
W
wizardforcel 已提交
102

W
wizardforcel 已提交
103
我们可以使用`__class__.species`访问`class`属性。 类的所有实例的类属性都相同。 同样,我们使用`blu.name``blu.age`访问实例属性。 但是,类的每个实例的实例属性都不同。
W
wizardforcel 已提交
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137

要了解有关类和对象的更多信息,请转到 [Python 类和对象](/python-programming/class)

* * *

## 方法

方法是在类主体内定义的函数。 它们用于定义对象的行为。

### 示例 2:在 Python 中创建方法

```py
class Parrot:

    # instance attributes
    def __init__(self, name, age):
        self.name = name
        self.age = age

    # instance method
    def sing(self, song):
        return "{} sings {}".format(self.name, song)

    def dance(self):
        return "{} is now dancing".format(self.name)

# instantiate the object
blu = Parrot("Blu", 10)

# call our instance methods
print(blu.sing("'Happy'"))
print(blu.dance())
```

W
wizardforcel 已提交
138
**输出**
W
wizardforcel 已提交
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

```py
Blu sings 'Happy'
Blu is now dancing
```

在上面的程序中,我们定义了两种方法,即`sing()``dance()`。 这些称为实例方法,因为它们是在实例对象(即`blu`)上调用的。

* * *

## 遗产

继承是一种创建新类以使用现有类的详细信息而不进行修改的方法。 新形成的类是派生类(或子类)。 同样,现有类是基类(或父类)。

### 示例 3:在 Python 中使用继承

```py
# parent class
class Bird:

    def __init__(self):
        print("Bird is ready")

    def whoisThis(self):
        print("Bird")

    def swim(self):
        print("Swim faster")

# child class
class Penguin(Bird):

    def __init__(self):
        # call super() function
        super().__init__()
        print("Penguin is ready")

    def whoisThis(self):
        print("Penguin")

    def run(self):
        print("Run faster")

peggy = Penguin()
peggy.whoisThis()
peggy.swim()
peggy.run()
```

W
wizardforcel 已提交
188
**输出**
W
wizardforcel 已提交
189 190 191 192 193 194 195 196 197

```py
Bird is ready
Penguin is ready
Penguin
Swim faster
Run faster
```

W
wizardforcel 已提交
198
在以上程序中,我们创建了两个类,即`Bird`(父类)和`Penguin`(子类)。 子类继承父类的功能。 我们可以从`swim()`方法中看到这一点。
W
wizardforcel 已提交
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235

再次,子类修改了父类的行为。 我们可以从`whoisThis()`方法中看到这一点。 此外,我们通过创建新的`run()`方法来扩展父类的功能。

另外,我们在`__init__()`方法内使用`super()`函数。 这使我们可以在子类中运行父类的`__init__()`方法。

* * *

## 封装形式

在 Python 中使用 OOP,我们可以限制对方法和变量的访问。 这样可以防止数据直接修改(称为封装)。 在 Python 中,我们使用下划线作为前缀来表示私有属性,即单`_`或双`__`

### 示例 4:Python 中的数据封装

```py
class Computer:

    def __init__(self):
        self.__maxprice = 900

    def sell(self):
        print("Selling Price: {}".format(self.__maxprice))

    def setMaxPrice(self, price):
        self.__maxprice = price

c = Computer()
c.sell()

# change the price
c.__maxprice = 1000
c.sell()

# using setter function
c.setMaxPrice(1000)
c.sell()
```

W
wizardforcel 已提交
236
**输出**
W
wizardforcel 已提交
237 238 239 240 241 242 243

```py
Selling Price: 900
Selling Price: 900
Selling Price: 1000
```

W
wizardforcel 已提交
244
在上面的程序中,我们定义了`Computer`类。
W
wizardforcel 已提交
245

W
wizardforcel 已提交
246
我们使用`__init__()`方法存储`Computer`的最高售价。 我们试图修改价格。 但是,我们无法更改它,因为 Python 将`__maxprice`视为私有属性。
W
wizardforcel 已提交
247 248 249 250 251

如图所示,要更改该值,我们必须使用设置器功能,即`setMaxPrice()`,该功能将价格作为参数。

* * *

W
wizardforcel 已提交
252
## 多态
W
wizardforcel 已提交
253

W
wizardforcel 已提交
254
多态是一种功能(在 OOP 中),可以将公共接口用于多种形式(数据类型)。
W
wizardforcel 已提交
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289

假设我们需要为形状着色,有多个形状选项(矩形,正方形,圆形)。 但是,我们可以使用相同的方法为任何形状着色。 这个概念称为多态。

### 示例 5:在 Python 中使用多态

```py
class Parrot:

    def fly(self):
        print("Parrot can fly")

    def swim(self):
        print("Parrot can't swim")

class Penguin:

    def fly(self):
        print("Penguin can't fly")

    def swim(self):
        print("Penguin can swim")

# common interface
def flying_test(bird):
    bird.fly()

#instantiate objects
blu = Parrot()
peggy = Penguin()

# passing the object
flying_test(blu)
flying_test(peggy)
```

W
wizardforcel 已提交
290
**输出**
W
wizardforcel 已提交
291 292 293 294 295 296

```py
Parrot can fly
Penguin can't fly
```

W
wizardforcel 已提交
297
在上面的程序中,我们定义了两个类别`Parrot``Penguin`。 它们每个都有一个通用的`fly()`方法。 但是,它们的功能不同。
W
wizardforcel 已提交
298

W
wizardforcel 已提交
299
要使用多态,我们创建了一个通用接口,即`flying_test()`函数,该函数接受任何对象并调用该对象的`fly()`方法。 因此,当我们在`flying_test()`函数中传递`blu``peggy`对象时,它有效地运行了。
W
wizardforcel 已提交
300 301 302 303 304 305 306 307 308

* * *

## 要记住的要点:

*   面向对象的编程使程序易于理解并且高效。
*   由于该类是可共享的,因此可以重用该代码。
*   数据通过数据抽象是安全的。
*   多态允许相同的接口用于不同的对象,因此程序员可以编写高效的代码。