6.0 KiB
6.0 KiB
2-面向对象
- 封装
- 继承
- 多态
类的属性和方法
class 类名:
属性 = 属性值
def 方法名(self, 形参1, 行参2, ...):
方法体
对象 = 类名()
对象.方法名()
# self 必须填写
# 表示类对象本身
# 在方法内部, 通过self访问属性
# 调用的时候忽略它
示例
class Student:
name = None
age = None
def say_hello(self):
print(f"hello, my name is {self.name}, and my age is {self.age}")
stu1 = Student()
stu1.name = "张三"
stu1.age = 18
stu1.say_hello()
print(stu1.name)
print(stu1.age)
构造方法
# __init__()
# 同样需要self参数
# 构造方法的实例化时会自动执行
# 把参数传给构造方法使用
# 属性可以不写, 放到构造方法里声明并赋值
示例:
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
print("我是构造方法")
def say_hello(self):
print(f"hello, my name is {self.name}, and my age is {self.age}")
stu1 = Student("张三",18)
stu1.say_hello()
print(stu1.name)
print(stu1.age)
常见的内置方法(魔术方法)
都是用__
包围起来
__str__
字符串方法
返回字符串, 供打印该对象时输出
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
print("我是构造方法")
def say_hello(self):
print(f"hello, my name is {self.name}, and my age is {self.age}")
stu1 = Student("张三",18)
print(stu1) # 输出内存地址, 类似 <__main__.Student object at 0x10ec4ffd0>
class Student2:
def __init__(self, name, age):
self.name = name
self.age = age
print("我是构造方法")
def say_hello(self):
print(f"hello, my name is {self.name}, and my age is {self.age}")
def __str__(self):
return (f"学生对象, 名称是 {self.name}, 年龄是 {self.age}")
# 返回字符串
stu2 = Student2("张三",18)
print(stu2)
# 学生对象, 名称是 张三, 年龄是 18
__lt__
小于符号比较
让两个实例的对象可以比较
# 传入 self 和 other
# 返回True or False
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __lt__(self, other):
return self.age < other.age
stu1 = Student("张三",18)
stu2 = Student("李四",19)
print(stu1 < stu2)
__le__
小于等于 符号比较
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __le__(self, other):
return self.age <= other.age
stu1 = Student("张三",18)
stu2 = Student("李四",19)
stu3 = Student("王五",18)
print(stu1 <= stu2)
print(stu1 >= stu2)
print(stu1 <= stu3)
print(stu1 >= stu3)
__eq__
等于号 符号比较
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
return self.age == other.age
stu1 = Student("张三",18)
stu2 = Student("李四",19)
stu3 = Student("王五",18)
print(stu1 == stu2)
print(stu1 == stu3)
封装
- 私有属性, 私有方法: 用__开头
私有属性和方法只能在类内部使用
class Phone:
def __init__(self,voltage):
self.__voltage = voltage
def __type(self):
if self.__voltage > 4:
return "性能模式"
else:
return "省电模式"
def get_type(self):
print(self.__type())
phone1 = Phone(5)
phone1.get_type()
# phone1.__type() # 报错
# print(phone1.__voltage) # 报错
phone2 = Phone(3)
phone2.get_type()
继承
# 单继承
class 子类名(父类):
方法体
# 多继承
class 子类名(父类1, 父类2, ...):
方法体
# 多继承, 属性或者方法名重复的话, 左边的优先
# pass关键字: 占位用的, 没有实际含义
复写
同样名称的属性或者方法在子类中再写一遍
子类调用父类的方法
方法一:
父类名.属性
父类名.方法(self)
方法二:
super().属性
super().方法()
示例:
class Human:
def __init__(self, name, age):
self.name = name
self.age = age
def say_hello(self):
print(f"hello, my name is {self.name}, and my age is {self.age}")
class Student(Human):
def __init__(self, name, age, cla):
super().__init__(name, age) # 不需要self
# Human.__init__(self, name, age) # 这里要self
self.cla = cla
def say_hello(self):
print(f"hello, my name is {self.name}, and my age is {self.age}, and my class is {self.cla}")
stu = Student("张三",18,"一班")
stu.say_hello()
子类有多个父类时, 调用父类的init方法, 是调用第一个父类的
类型注解
变量的类型注解
提示性的备注, 错了也不会停止
# 变量: 类型
# 基础类型注解
# 没什么意义, 自动推断
var_int: int = 10
var_float: float = 3.14
var_bool: bool = True
var_str: str = "str"
# 类对象注解
class Student:
pass
stu: Student = Student()
# 容器类型注解
var_lsit: list = [1, 2, 3]
var_tuple: tuple = (1, 2, 3)
var_set: set = {1, 2, 3}
var_dict: dict = {"name": "张三"}
# 容器的详细注解
var_l1: list[int] = [1, 2, 3]
# 元组需要把每个元素都标记出来
var_t1: tuple[int, bool, str] = (1, True, "str")
var_s1: set[int] = {1,2,3}
# 字典需要两个类型, 一个key, 一个value
var_d1: dict[str,int] = {"age": 18}
在注释中进行类型注解
# type: 类型
name = "张三" # type: str
示例:
import random
num = random.randint(1, 10) # type: int
print(num)
函数的类型注解
def 函数名(形参: 类型) -> 返回值类型:
pass
Union 联合类型注解
from typing import Union
Union[类型1, 类型2, ...]
示例:
from typing import Union
my_list: list[Union[str,int]] = [1, "a", 2, "str"]
my_dict: dict[str, Union[str,int]] = {"name": "张三", "age": 18}
多态
同样的函数, 传入不同的对象,能够输出多种状态
- 抽象方法: 方法为空, 只定义, 具体由子类复写
- 抽象类: 具有抽象方法的类, 用于顶层设计