> For the complete documentation index, see [llms.txt](https://gitbook.existorlive.cn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gitbook.existorlive.cn/kai-fa-yu-yan-xue-xi/python/15.-mian-xiang-dui-xiang.md).

# 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: ...

```

​

​
