Python – 面向对象
类的声明
类的定义
声明一个类,其成员变量可以通过以下格式定义
class Student:
name = None # 学生姓名
sex = None # 学生性别
age = None # 学生年龄
def method(self, arg1, arg2, ... argn):
- self 是每一个成员方法必须存在的,在每一次调用时,成员方法都会把对象传到self中
类的创建
可以通过调用类的名称来实例化类
s = Student()
s.name = "TZMing"
s.sex = "男"
s.age = 18
s.method() # 在调用时无需理会形参“self”
构造方法
在Py中,支持类的构造方法,但是并非使用类的名称作为方法,而是使用 __init__ 关键字作为方法名定义构造方法
class Student:
name = None
age = None
sex = None
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
- 在调用类时, __init__ 方法会默认被执行
- 在调用类时,所提供的参数,都会被转到 __init__ 方法中
- 若定义了 __init__ 方法后,理论上成员变量可以忽略不定义,因为在 __init__ 方法中已经声明了成员变量了
字符串方法 __str__
__str__ 方法是需要Py的内置方法,它用于打印类对象时输出的方法
class Student:
name = None
age = None
sex = None
def __str__(self):
return "Student"
使用 print() 方法或 str(class对象)时会被调用该方法
大于、小于符号比较方法 __lt__
小于符号魔术方法
class Student:
name = None
age = None
sex = None
# 小于符号使用时触发
def __lt__(self, other):
return self.age < other.age
大于符号魔术方法
class Student:
name = None
age = None
sex = None
# 大于符号使用时触发
def __gt__(self, other):
return self.age > other.age
小于等于、大于等于符号比较方法 __le__
大于等于符号魔术方法
class Student:
name = None
age = None
sex = None
# 大于等于符号使用时触发
def __ge__(self, other):
return self.age >= other.age
小于等于符号魔术方法
class Student:
name = None
age = None
sex = None
# 小于等于符号使用时触发
def __le__(self, other):
return self.age <= other.age
== 符号比较方法 __eq__
class Student:
name = None
age = None
sex = None
# 使用 == 符号时触发
def __eq__(self, other):
return self.name == other.name and self.age == other.age
面向对象特性
封装
类的私有成员
Py 支持私有成员变量模式,要定义私有变量,我们只需要把成员变量名称前加上【__】做开头即可
class Student:
name = None # 公共成员
age = None # 公共成员
sex = None # 公共成员
__money = None # 私有成员
__balance = None # 私有成员
对于私有成员变量,在外面的对象是无法直接调用的
类的私有方法
对于私有的类的方法,也是使用【__】做开头,这些方法将变系私有方法
class Student:
name = None # 公共成员
age = None # 公共成员
sex = None # 公共成员
__money = None # 私有成员
__balance = None # 私有成员
# 私有方法
def __keep(self):
return self.__money
继承
Py 的继承很简单,只需要在子类定义中加上(父类)即可
语法如下:
# 父类
class Animal:
name = None
age = None
sex = None
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
# 继承父类的子类
class Person(Animal):
school = None
father = None
mother = None
def sayHi(self):
print(f"你好,我是人类")
多继承
Py还支持多继承功能
语法:class 子类(父类1,父类2,...父类n):
# 父类
class Animal:
name = None
age = None
sex = None
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
class Chinese:
chinese_name = None
# 继承父类的子类
class Person(Animal, Chinese):
school = None
father = None
mother = None
def sayHi(self):
print(f"你好,我是人类")
pass 关键字
对于一个类,它继承了其它的类,而这个类我不希望写任何功能和代码,我们可以使用 pass 来告诉 py 我们的这个类不写任何功能:
# 父类
class Animal:
name = None
age = None
sex = None
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
class Chinese:
chinese_name = None
# Person 继承了两个父类,已经包含了两个类的方法和变量,我希望这个类仅仅作为继承使用,不做任何功能,这时可以增加一个 pass 关键字
class Person(Animal, Chinese):
pass
多继承下的相同成员变量情况
当我们继承多个父类,且这些父类中有同名的成员变量时,Py以谁先继承,就使用谁的成员变量:
class A:
name = None
class B:
name = None
class Children(A, B):
def print_name(self):
print(self.name) # 会输出 A 的 name 因为 A 先继承
重写成员变量与方法
在Py 中,支持子类重写父类的成员变量和父类的方法
class Phone:
Imei = None
product = None
def call_by_5g(self):
print("使用5G进行通话")
class IPhone(Phone):
# 重写了父类的成员变量
product = None
# 重写了父类的方法
def call_by_5g(self):
print("使用5G VoLTE进行通话")
调用父类的成员与方法
对于已重写父类的成员和方法时,我们要如何调用父类的成员与方法呢
方法一:
- 使用成员变量:父类名.成员变量
- 使用成员方法:父类名.成员方法(self)
class Phone:
Imei = None
product = None
def call_by_5g(self):
print("使用5G进行通话")
class IPhone(Phone):
# 重写了父类的成员变量
product = None
# 重写了父类的方法
def call_by_5g(self):
print("使用5G VoLTE进行通话")
# 调用父类的成员变量和方法
def call_parent(self):
print(Phone.product)
Phone.call_by_5g(self)
方式二:
- 使用成员变量:super().成员变量
- 使用成员方法:super().成员方法()
class Phone:
Imei = None
product = None
def call_by_5g(self):
print("使用5G进行通话")
class IPhone(Phone):
# 重写了父类的成员变量
product = None
# 重写了父类的方法
def call_by_5g(self):
print("使用5G VoLTE进行通话")
# 调用父类的成员变量和方法
def call_parent(self):
print(super().product)
super().call_by_5g()
变量的类型注解
Python在3.5版本的时候引入了类型注解,以方便静态类型检查工具,IDE等第三方工具。类型注解:在代码中涉及数据交互的地方,提供数据类型的注解(显式的说明)。
主要功能:
- 帮助第三方IDE工具(如PyCharm)对代码进行类型推断,协助做代码提示
- 帮助开发者自身对变量进行类型注释
说白了就是我们可以在变量后面定义该变量的类型,以方便IDE识别该变量的类型,从而方便提供该类型的方法:
class Stud:
pass
s: Stud = Stud()
除了可以定义为一个简单的类型,也可以定义为一个更深层次的类型:
my_list: list[str] = ["a", "b"]
my_tuple: tuple[list[str], int, bool] = (["a", "b"], 123, True)
my_set: set[int] = {1, 2, 3}
my_dict: dict[str, int] = {"a": 123, "b": 456}
注意:
- 元组类型设置类型详细注解,需要将每一个元素都标记出来
- 字典类型设置类型详细注解,需要2个类型,第一个是key类型,第二个是value类型
除了使用类型注解中定义变量的类型,我们还可以使用注释方式对变量进行类型声明
语法:# type: 类型
示例:
# type: int
var_1 = 123 # type:int
注意:类型注解仅用于提示变量类型,而不是强制让该变量变成该类型,所以错误的指定变量的类型并不会使程序报错。
方法的类型注解
在方法的形参中,也可以对形参的类型进行注解
和变量注解类型一样:
def method(data: list[str]):
pass
Union 类型
Union 是用于描述混合类型的,比如下面这些数据,就不能通过普通类型进行注解:
var_2 = [1, 2, "abc", True]
var_3 = {"name": "TZMing", "age": 18}
对于那些包含多种类型混合在里面的变量,可以使用Union联系多种类型进行注解,使用 Union 需要引入包
from typing import Union
利用Union声明混合类型的列表:
var_2: list[Union[int, str]] = [1, 2, "abc", True] # 表示可以包含str或int类型的列表
var_3: dict[str, Union[str, int]] = {"name": "TZMing", "age": 18} # 表示key为str但value可以为str或int类型的字典
在方法中也可以使用Union定义混合类型:
def method2(data: list[Union[str,int]]): # 定义data是一个可以包含str或int类型的列表
pass
多态
多态,指的是:多种状态,即完成某个行为时,使用不同的对象会得到不同的状态。
Py中对于抽象类的定义,是指该父类中的方法使用了pass空实现,此时如果有子类继承父类时,子类需要实现父类的抽象方法
class Ac:
def cool_wind(self):
"""制冷风"""
pass
def hot_wind(self):
"""制热风"""
pass
def wind_l_r(self):
"""风向左右摇摆"""
pass
class GREE(Ac):
def cool_wind(self):
print("格力制冷风")
def hot_wind(self):
print("格力制热风")
def wind_l_r(self):
print("格力左右摇摆")
class MEDIA(Ac):
def cool_wind(self):
print("美的制冷风")
def hot_wind(self):
print("美的制热水")
def wind_l_r(self):
print("美的左右摇摆")
def make_cool(ac: Ac):
ac.cool_wind()
gree = GREE()
media = MEDIA()
make_cool(gree)
make_cool(media)
共有 0 条评论