【黑马程序员】Python面向对象

面向对象

对象初始对象

  • 代码示例
# *_*coding:utf-8 *_*
# 设计一个类:类比生活中:设计一张登记表
class Student:
    # 定义类成员属性
    name = None
    gender = None
    nationality = None
    native_place = None
    age = None


# 创建一个对象:类比打印一张登记表
stu = Student()
# 对象属性进行赋值类比生活中填写表单
stu.name = "zsx"
stu.gender = "男"
stu.nationality = "China"
stu.native_place = "baoji"
stu.age = 18

# 获取对象中记录的信息
print(f'姓名:{stu.name},性别:{stu.gender},国籍:{stu.nationality},出生地:{stu.native_place},年龄:{stu.age}')

类的定义和使用

语法

  • 类的定义

    • class:关键字,表示要定义类
    • 类的属性:类中的变量(成员变量)

    • 类的行为:类中的函数(成员方法)

class 类名:
    类的属性
    类的行为
  • 类的使用
对象=类名称()
  • 成员方法的定义语法

    • self关键字是成员方法定义时,必须填写的

    • 用来表示类对象自身,当我们使用类对象调用方法时,self会自动被Python传入

    • 在方法内部,想要访问类成员变量,必须使用self

def 方法名(self,形参1, ... ,形参n)
    方法体

代码示例

# *_*coding:utf-8 *_*
class Student:
    # 成员属性
    name = None

    # 成员方法
    def say_hi(self):
        print(f'hi, {self.name}')

    def say_hi1(self, msg):
        print(f'hi, {self.name}, {msg}')


# 构建类对象
stu = Student()
# 给成员属性赋值
stu.name = "zs"
# 调用成员方法
stu.say_hi()
stu.say_hi1("你好")

内置方法

构造方法

  • python类可以使用:__init__()方法,称之为构造方法

  • 可以实现

    • 在创建类对象的时候,会自动执行

    • 在创建类对象的时候,会将传入参数自动传递给__init__方法使用

  • 代码示例

# *_*coding:utf-8 *_*
class Student:
    # 定义类成员属性
    name = None
    gender = None
    age = 0

    def __init__(self, name, gender, age):
        self.name = name
        self.gender = gender
        self.age = age


stu = Student("zsx", "man", 18)
print(f'姓名:{stu.name}, 性别:{stu.gender}, 年龄:{stu.age}')
  • 注意事项

    • 不要忘记前后两个下划线

    • 构造方法也是成员方法,不要忘记在参数列表中提供:self

    • 在构造方法内定义成员变量,需要使用self关键字

字符串方法

  • 问题:定义好类对象之后,如果直接打印类对象或者使用str强转打印,都会输出内存地址

  • 通过__str__方法可以控制类转换为字符串的行为

  • 代码示例:在上面类中添加__str__方法

    def __str__(self):
        return f'姓名:{self.name}, 性别:{self.gender}, 年龄:{self.age}'

比较方法

__lt__方法
  • 小于符号比较方法

  • 通过__lt__方法可以控制类中小于比较的行为

  • 代码示例

    def __lt__(self, other):
        return self.age < other.age
__le__方法
  • 小于等于符号比较方法

  • 通过__le__方法可以控制类中小于等于比较的行为

  • 代码示例

    def __le__(self, other):
        return self.age <= other.age
__eq__方法
  • 等于符号比较方法

封装

  • 将现实世界事务在类中描述为属性和方法,即为封装

私有成员

  • 在类中描述属性和方法有时候是不公开使用的

  • 定义私有成员的方法,在变量名或者方法名前面以__开头

  • 私有变量无法赋值,也无法使用

  • 代码示例

# *_*coding:utf-8 *_*

class Phone:
    # 私有变量
    __curent_voltage = None  # 当前电压

    # 私有方法
    def __keep_single_core(self):
        print("cpu单核运行")

phone = Phone()
# 访问私有成员,不报错,但无效
# AttributeError: 'Phone' object has no attribute '__curent_voltage'
print(phone.__curent_voltage)

# 报错无法使用
# AttributeError: 'Phone' object has no attribute '__keep_single_core'
phone.__keep_single_core()

使用私有成员

  • 私有成员无法被类对象使用,但是可以被其它成员使用

  • 代码示例

# *_*coding:utf-8 *_*

class Phone:
    # 私有变量
    __curent_voltage = 0.5  # 当前电压

    # 私有方法
    def __keep_single_core(self):
        print("cpu单核运行")

    def call_by_5g(self):
        if self.__curent_voltage >= 1:
            print("5g通话已开启")
        else:
            self.__keep_single_core()
            print("电量不足,无法使用5g通话")

phone = Phone()
phone.call_by_5g()

继承

  • 定义:一个类继承另一个类的成员变量和成员方法

  • 子类构建的类对象

    • 有自己的成员变量和成员方法

    • 可以使用父类的成员变量和成员方法

单继承

  • 一个类继承自一个父类

  • 语法

class 类名(父类名):
    类内容
  • 代码示例
# *_*coding:utf-8 *_*
class Phone:
    IMEI = None  # 序列号
    producer = None  # 厂商

    def call_by_4g(self):
        print("4g通话")


# 继承Phone类
class Phone2024(Phone):
    face_id = True  # 面部识别

    def call_by_5g(self):
        print("5g通话")


p2024 = Phone2024()
p2024.call_by_4g()
p2024.call_by_5g()

多继承

  • 一个类可以继承多个父类

  • 注意事项

    • 多个父类中,如果有同名的成员,默认以从左到右为优先级
  • 语法

class 类名(父类1,父类2, ... ):
    类内容
  • 代码示例
# *_*coding:utf-8 *_*
class Phone:
    IMEI = None
    producer = "HM2"

    def call_by_5g(self):
        print("5g通话")


class NFCReader:
    nfc_type = "第5代"
    producer = "HM1"

    def read_card(self):
        print('读取nfc卡')

    def write_card(self):
        print('写入nfc卡')


class RemoteControl:
    rc_type = "红外遥控"

    def control(self):
        print("红外遥控开启")


class XiaoMePhone(Phone, NFCReader, RemoteControl):
    # pass表示空,只做语法不全,没有实际含义
    pass


my_phone = XiaoMePhone()
my_phone.call_by_5g()
my_phone.read_card()
my_phone.write_card()
my_phone.control()
# 多个类有同名属性时优先级为从左向右
print(my_phone.producer)

重写父类成员方法

  • 子类对父类已有的方法进行重新定义

  • 代码示例

# *_*coding:utf-8 *_*
class Phone:
    def call_5g(self):
        print("使用5g通话")


class MyPhone(Phone):
    # 子类对父类的方法进行重写
    def call_5g(self):
        print("使用升级5g通话")


my_phone = MyPhone()
my_phone.call_5g()

调用父类同名成员

  • 一旦重写了父类成员,那么类对象调用成员的时候,就会调用重写后的新成员

  • 如果需要使用被复写的父类成员,需要特殊的调用

  • 语法

# 方式一:使用父类名调用
使用成员变量:父类名.成员变量
使用成员方法:父类名.成员方法(self)

# 方式二:使用super()调用父类成员
使用成员变量:super().成员变量
使用成员方法:super().成员方法(self)
  • 代码示例
# *_*coding:utf-8 *_*
class Phone:
    id = 1

    def call_5g(self):
        print("使用5g通话")


class MyPhone(Phone):
    id = 2

    # 子类对父类的方法进行重写
    def call_5g(self):
        print("使用升级5g通话")
        # 方式一:调用父类成员
        print(f'父类id:{Phone.id}')
        print(f'父类id:{Phone.call_5g(self)}')
        # 方式二:调用父类成员
        print(f'父类id:{super().id}')
        print(f'父类id:{super().call_5g()}')


my_phone = MyPhone()
my_phone.call_5g()

类型注解

  • 定义:在代码中涉及数据交互的地方,提供数据类型的注解(显式说明)

  • 功能:

    • 帮助第三方IDE工具对代码进行类型推断,协助做代码提示

    • 帮助开发者自身对变量进行类型注解

  • 支持

    • 变量的类型注解

    • 函数形参列表和返回值的类型注解

变量注解

对变量设置类型注解
  • 语法:变量:类型

  • 代码示例

# *_*coding:utf-8 *_*
# 基础数据类型注解
var1: int = 10
var2: float = 3.12
var3: bool = True
var4: str = "sgfdghs"


class Student:
    pass


# 类对象类型注解
stu: Student = Student()

# 基础容器类型注解
my_list: list = [1, 2, 3]
my_tuple: tuple = (1, 2, 3)
my_set: set = {1, 2, 3}
my_dict: dict = {"a": 1}
my_str: str = "dhsdjs"

# 容器类型详细注解
my_list1: list[int] = [1, 2, 3]
my_tuple1: tuple[int, bool, str] = (1, True, "dsd")
my_set1: set[int] = {1, 2, 3}
my_dict1: dict[str, int] = {"a": 1}
在注释中进行类型注解
  • 语法:#type:类型

  • 代码示例

var1 = 1  # type: int
var2 = 4.56  # type: float
var3 = "sdas"  # type: st
类型注解的限制
  • 类型注解只是个提示,标记错了也没有关系
var1: int = "dasdsads"
var2: float = 3
var3: bool = 12321

函数注解

  • 语法:
def 函数名(形参: 类型, ..., 形参: 类型) -> 返回值类型:
    pass
  • 代码示例
def add(x: int, y: int) -> int:
    return x + y


def func(data: list) -> list:
    pass

union类型

  • 同时对多个类型进行注解

  • 代码示例

# *_*coding:utf-8 *_*
from typing import Union

# 只是单类型的注解
my_list: list[int] = [1, 2, 3, 4]
my_dict: dict[str, int] = {"age": 12, "num": 1}

# 存在混合类型的注解

# Union[int, bool, float] 类型有可能是int, bool, float
my_list1: list[Union[int, bool, float]] = [1, True, 4.12]
my_dict1: dict[str, Union[str, int, float]] = {"name": "zs", "age": 12, "score": 85.5}

多态

  • 完成某个行为时,使用不同的对象会得到不同的状态

  • 代码示例

# *_*coding:utf-8 *_*
# 抽象类:含有抽象方法的类
class Animal:
    # 抽象方法:方法体是空实现(pass)
    def speak(self):
        pass

class Cat(Animal):
    def speak(self):
        print("cat speak")

class Dog(Animal):
    def speak(self):
        print("dog speak")

def do_speak(animal: Animal):
    animal.speak()

do_speak(Cat())
do_speak(Dog())
  • 19
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

double_happiness

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值