# 15.面向对象

### 1. 类的定义

**python**中的类通过 `class` 关键字来定义，类的成员有**属性**和**方法**​

```python
# 示例
class ClassName: 
    <statement-1>
    .
    .
    .
    <statement-N> 
```

#### 1.1 属性

类的属性可以显式地定义在类中, 同变量一样，属性的定义必须初始化

```python
class A:
    a = 14
    b = 12
    
print(A().a)
# 14
```

属性还可以隐式地通过构造方法来定义

```python
class A:
    # 在构造方法中隐式的定义属性：
    def __init__(self):
        self.a = 13
        self.b = 12
print(A().a)
# 13
```

#### 1.2 构造方法 \_**init**(self)

Python的构造方法是名为 `__init__` 的方法，第一个参数为 `self`, 指向当前对象。

```python
class A:
    def __init__(self,a,b):
        self.a = a
        self.b = b
print(A(11,12).a)
# 11
```

#### 1.3 类的方法

类的方法不同于函数，有一个默认参数 `self`

### 2. 继承

子类可以继承父类的属性和方法，支持多继承。

```swift
class DerivedClassName(Base1, Base2, Base3):
    <statement-1>
    .
    .
    .
    <statement-N>
```

方法的搜索规则：

需要注意圆括号中父类的顺序，若是父类中有相同的方法名，而在子类使用时未指定，python从左至右搜索 即方法在子类中未找到时，从左到右查找父类中是否包含方法。

#### 2.1 重写方法

* 在子类中定义与父类相同的方法，就会在子类中重写该方法。
* 在子类中调用父类方法，需要显示指定父类的名字（可能有多个父类）

```swift
#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(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 speak(self):
        print("%s 说: 我 %d 岁了，我在读 %d 年级"%(self.name,self.age,self.grade))
 
#另一个类，多重继承之前的准备
class speaker():
    topic = ''
    name = ''
    def __init__(self,n,t):
        self.name = n
        self.topic = t
    def speak(self):
        print("我叫 %s，我是一个演说家，我演讲的主题是 %s"%(self.name,self.topic))
 
#多重继承
class sample(speaker,student):
    a =''
    def __init__(self,n,a,w,g,t):
        student.__init__(self,n,a,w,g)
        speaker.__init__(self,n,t)
 
test = sample("Tim",25,80,4,"Python")
test.speak()   #方法名同，默认调用的是在括号中参数位置排前父类的方法
```

强制调用父类的方法：

```swift
s = student("Tim",12,180)

super(student,s).speak()
# Tim 说: 我 12 岁
```

### 3. 访问控制

#### 3.1 私有成员

* 类的私有属性 : `__private_attrs`：两个下划线开头，声明该属性为私有，不能在类的外部被使用或直接访问。在类内部的方法中使用时 `self.__private_attrs`。
* 类的私有方法 : `__private_method`：两个下划线开头，声明该方法为私有方法，只能在类的内部调用 ，不能在类的外部调用。`self.__private_methods`。

### 4. 专有方法

类的专有方法：

* `__init__` : 构造函数，在生成对象时调用
* `__del__` : 析构函数，释放对象时使用
* `__repr__` : 打印，转换
* `__setitem__` : 按照索引赋值
* `__getitem__`: 按照索引获取值
* `__len__` : 获得长度
* `__cmp__` : 比较运算
* `__call__` : 函数调用
* `__add__` : 加运算
* `__sub__` : 减运算
* `__mul__` : 乘运算
* `__truediv__` : 除运算
* `__mod__` : 求余运算
* `__pow__` : 乘方

```python
class object:
    __doc__: str | None
    __dict__: dict[str, Any]
    __module__: str
    __annotations__: dict[str, Any]
    @property
    def __class__(self: Self) -> type[Self]: ...
    # Ignore errors about type mismatch between property getter and setter
    @__class__.setter
    def __class__(self, __type: type[object]) -> None: ...  # type: ignore # noqa: F811
    def __init__(self) -> None: ...
    def __new__(cls: type[Self]) -> Self: ...
    # N.B. `object.__setattr__` and `object.__delattr__` are heavily special-cased by type checkers.
    # Overriding them in subclasses has different semantics, even if the override has an identical signature.
    def __setattr__(self, __name: str, __value: Any) -> None: ...
    def __delattr__(self, __name: str) -> None: ...
    def __eq__(self, __o: object) -> bool: ...
    def __ne__(self, __o: object) -> bool: ...
    def __str__(self) -> str: ...  # noqa Y029
    def __repr__(self) -> str: ...  # noqa Y029
    def __hash__(self) -> int: ...
    def __format__(self, __format_spec: str) -> str: ...
    def __getattribute__(self, __name: str) -> Any: ...
    def __sizeof__(self) -> int: ...
    # return type of pickle methods is rather hard to express in the current type system
    # see #6661 and https://docs.python.org/3/library/pickle.html#object.__reduce__
    def __reduce__(self) -> str | tuple[Any, ...]: ...
    if sys.version_info >= (3, 8):
        def __reduce_ex__(self, __protocol: SupportsIndex) -> str | tuple[Any, ...]: ...
    else:
        def __reduce_ex__(self, __protocol: int) -> str | tuple[Any, ...]: ...

    def __dir__(self) -> Iterable[str]: ...
    def __init_subclass__(cls) -> None: ...

```

​

​


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gitbook.existorlive.cn/kai-fa-yu-yan-xue-xi/python/15.-mian-xiang-dui-xiang.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
