python入门(十一)——面向对象

上期文章

python入门(十)——基础综合案例之可视化



一、初识对象

使用对象组织数据

1.设计类class

class Student:
	name = None	# 记录学生姓名

2.创建对象

# 基于类创建对象
stu_1 = Student()
stu_2 = Student()

3.对象属性赋值

stu_1.name = '周杰伦'	# 为学生1对象赋予名称属性值
stu_2.name = '林俊杰'	# 为学生2对象赋予名称属性值
class Student:
    name = None
    gender = None
    nationality = None
    native_place = None
    age = None

stu_1 = Student()

stu_1.name = '林俊杰'
stu_1.gender = '男'
stu_1.nationality = '中国'
stu_1.native_place = '山东省'
stu_1.age = 31

print(stu_1.name)
print(stu_1.gender)

林俊杰
男

类的定义和使用

class 类名称:	# class是关键字,定义类
	类的属性	# 类的属性,即定义在类中的变量 成员变量
	类的行为	# 类的行为,即定义在类中的函数 成员方法

创建类对象的语法:
对象 = 类名称()

成员变量和成员方法

class Student:
	name = None
	age = None

	def say_hi(self):
		print(f'hi大家好,我是{self.name}')

方法:定义在类内部的函数
函数:定义在类外部的函数

成员方法的定义语法

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

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

  • 用来表示类对象自身的意思
  • 当使用类对象调用方法时,self会自动被python传入
  • 在方法内部,想要访问类的成员变量,必须使用self
def say_hi(self):
		print(f'hi大家好,我是{self.name}')

self关键字尽管在参数列表中,但是传参的时候可以忽略它

class Student:
	name = None

	def say_hi1(self):
		print('hello大家好!')

	def say_hi2(self, msg):
		print(f'hello大家好, {msg}')

stu = Student()
stu.say_hi1()	# 调用时无需传参
stu.say_hi2('很高兴认识大家')	# 调用时需要传msg参数
class Student:
    name = None

    def say_hi(self):
        print(f'hello大家好!我是{self.name},欢迎大家多多关照')


stu = Student()
stu.name = '周杰伦'
stu.say_hi()

stu2 = Student()
stu2.name = '林俊杰'
stu2.say_hi()

hello大家好!我是周杰伦,欢迎大家多多关照
hello大家好!我是林俊杰,欢迎大家多多关照
class Student:
    name = None

    def say_hi(self):
        print(f'hello大家好!我是{self.name},欢迎大家多多关照')

    def say_hi2(self, msg):
        print(f'大家好,我是{self.name},{msg}')


stu = Student()
stu.name = '周杰伦'
stu.say_hi2('哎哟不错哟')

stu2 = Student()
stu2.name = '林俊杰'
stu2.say_hi2('小伙子我看好你')

大家好,我是周杰伦,哎哟不错哟
大家好,我是林俊杰,小伙子我看好你

二、类和对象

类是程序中的设计图纸,对象是基于图纸生产的具体实体
使用类创建对象,并用对象来完成具体的工作

class Clock:
    id = None
    price = None

    def ring(self):
        import winsound
        winsound.Beep(2000, 3000)


clock1 = Clock()
clock1.id = '003032'
clock1.price = 19.99
print(f'闹钟ID:{clock1.id},价格:{clock1.price}')
clock1.ring()

clock2 = Clock()
clock2.id = '003033'
clock2.price = 21.99
print(f'闹钟ID:{clock2.id},价格:{clock2.price}')
clock2.ring()

三、构造方法

—init—()

  • 创建类对象(构造类)的时候,会自动执行
  • 创建类对象(构造类)的时候,将传入参数自动传递给_init_方法使用

在方法内使用成员变量需要使用self

class Student:
    name = None
    age = None
    tel = None

    def __init__(self, name, age, tel):
        self.name = name
        self.age = age
        self.tel = tel
        print('Student类创建了一个类对象')


stu = Student('周杰伦', 31, '11111111')

Student类创建了一个类对象

类里面成员变量的定义可以不写

class Student:

    def __init__(self, name, age, tel):
        self.name = name
        self.age = age
        self.tel = tel
        print('Student类创建了一个类对象')


stu = Student('周杰伦', 31, '11111111')
print(stu.name)

Student类创建了一个类对象
周杰伦
class Student:
    def __init__(self, name, age, address):
        self.name = name
        self.age = age
        self.address = address


for i in range(1, 3):
    print(f'当前录入第{i}位学生信息,总共需要录入2位学生信息')
    name = input('请输入学生姓名:')
    age = input('请输入学生年龄:')
    address = input('请输入学生地址:')
    stu = Student(name, age, address)
    print(f'学生{i}信息录入完成,信息为:【学生姓名:{stu.name},年龄:{stu.age},地址:{stu.address}】')

print('所有学生信息已录入完毕!')

当前录入第1位学生信息,总共需要录入2位学生信息
请输入学生姓名:周杰伦
请输入学生年龄:31
请输入学生地址:北京
学生1信息录入完成,信息为:【学生姓名:周杰伦,年龄:31,地址:北京】
当前录入第2位学生信息,总共需要录入2位学生信息
请输入学生姓名:林俊杰
请输入学生年龄:31
请输入学生地址:上海
学生2信息录入完成,信息为:【学生姓名:林俊杰,年龄:31,地址:上海】
所有学生信息已录入完毕!

四、魔术方法

内置的类方法,各自有各自特殊的功能,这些内置方法被称之为魔术方法

_str_字符串方法

类对象变成字符串类型

class Student:

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


stu = Student('周杰伦', 31)
print(stu)
print(str(stu))

<__main__.Student object at 0x7fd4e8b84fa0>
<__main__.Student object at 0x7fd4e8b84fa0>
class Student:

    def __init__(self, name, age):
        self.name = name
        self.age = age
        
    def __str__(self):
        return f'Student类对象,name:{self.name},age:{self.age}'


stu = Student('周杰伦', 31)
print(stu)
print(str(stu))

Student类对象,name:周杰伦,age:31
Student类对象,name:周杰伦,age:31

_lt_小于符号比较方法

传入参数:other,指的是另一个类对象
返回值:True或者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('周杰伦', 31)
stu2 = Student('周杰伦', 36)
print(stu1 < stu2)
print(stu1 > stu2)

True
False

_le_小于等于比较符号方法

传入参数:other,另一个类对象
返回值:True或False
内容:自行定义

class Student:

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

    def __le__(self, other):
        return self.age <= other.age


stu1 = Student('周杰伦', 31)
stu2 = Student('周杰伦', 36)
print(stu1 <= stu2)
print(stu1 >= stu2)

True
False

stu1 = Student('周杰伦', 36)
stu2 = Student('周杰伦', 36)
print(stu1 <= stu2)
print(stu1 >= stu2)

True
True

_eq_比较运算符实现方法

传入参数:other,另一个类对象
返回值:True或False
内容:自定义

class Student:

    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __eq__(self, other):
        return self.age == other.age


stu1 = Student('周杰伦', 36)
stu2 = Student('周杰伦', 36)
print(stu1 == stu2)

True

魔术方法总结

在这里插入图片描述

五、封装

封装:将现实世界事物在类中描述为属性和方法

私有成员

现实事物有部分属性和行为是不公开对使用者开放的,同样在类中描述属性和方法的时候也需要达到这个要求,就需要定义私有成员,不公开的属性和行为,变量名和方法名以__两个下划线开头

私有方法无法直接被类对象使用,私有变量无法赋值,也无法获取值,但是可以被其他的成员使用

class Phone:

    __current_voltage = None

    def __keep_single_core(self):
        print('让CPU以单核模式运行')


phone = Phone()
phone.__keep_single_core()
print(phone.__current_voltage)

AttributeError: 'Phone' object has no attribute '__keep_single_core'
AttributeError: 'Phone' object has no attribute '__current_voltage'

可以被类中的其他成员方法使用私有成员的方法和变量

class Phone:

    __current_voltage = 0.5

    def __keep_single_core(self):
        print('让CPU以单核模式运行')

    def call_by_5g(self):
        if self.__current_voltage >=1:
            print('5g通话已开启!')

        else:
            self.__keep_single_core()
            print('电量不足,无法使用5g通话,并已设置为单核运行进行')


phone = Phone()
phone.call_by_5g()

让CPU以单核模式运行
电量不足,无法使用5g通话,并已设置为单核运行进行

私有成员的意义:

  • 在类中提供仅供内部使用的属性和方法,而不对外开放(类对象无法使用)
  • 定义不需要向用户开放的属性和行为
class Phone:
# 5g状态不需要向用户提供,直接转换为私有

    __is_5g_enable = False

    def __check_5g(self):
        if self.__is_5g_enable:
            print('5G开启')
        else:
            print('5G关闭,使用4G网络')

    def call_by_5g(self):
        self.__check_5g()
        print('正在通话中')


phone = Phone()
phone.call_by_5g()

5G关闭,使用4G网络
正在通话中

六、继承

单继承

class 类名(父类名):
	类内容体
class Phone:
    IMEL = None
    productor = 'HM'

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


class Phone2023(Phone):
    face_id = '10001'

    def call_by_5g(self):
        print('2023年新功能:5g通话')


phone = Phone2023()
print(phone.productor)
phone.call_by_4g()
phone.call_by_5g()

HM
4g通话
2023年新功能:5g通话

多继承

一个子类继承多个父类

class 类名(父类1, 父类2, ..., 父类N):
	类内容体
class Phone:
    IMEL = None
    productor = 'HM'

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


class Phone2023(Phone):
    face_id = '10001'

    def call_by_5g(self):
        print('2023年新功能:5g通话')


class NFCReader:
    nfc_type = '第五代'
    productor = 'HM'

    def read_card(self):
        print('NFC读卡')

    def write_card(self):
        print('NFC写卡')


class RemoControl:
    rc_type = '红外遥控'

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


class MyPhone(Phone, NFCReader, RemoControl):
    pass    # 补全语法,不需要额外补充,不产生语法错误

phone = MyPhone()
phone.call_by_4g()
phone.read_card()
phone.write_card()
phone.control()
print(phone.productor)

4g通话
NFC读卡
NFC写卡
红外遥控开启
ITCAST
# 对于同名的方法或属性,按照父类谁在左边,谁在第一个的位置则谁的优先级更高的顺序来,即先继承的优先级高于后继承

pass关键字

pass是占位语句,用来保证函数/方法或类定义的完整性,表示无内容,空的意思

复写和使用父类成员

复写

子类继承父类的成员属性和成员方法后,如果对其不满意,可以进行复写,即在子类中重新定义同名的属性或方法即可

class Phone:
    IMEI = None
    producer = 'ITCAST'

    def call_by_5g(self):
        print('使用5g网络进行通话')


class MyPhone(Phone):
    producer = 'ITHIMA'

    def call_by_5g(self):
        print('开启CPU单核模式,确保通话的时候省电')
        print('使用5g网络进行通话')
        print('关闭CPU单核模式,确保性能')

phone = MyPhone()
phone.call_by_5g()
print(phone.producer)

开启CPU单核模式,确保通话的时候省电
使用5g网络进行通话
关闭CPU单核模式,确保性能
ITHIMA

调用父类同名成员

一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员,如果需要使用被复写的父类的成员,需要特殊的调用方式

只可以在子类内部调用父类的同名成员,如果在子类的实体类对象中调用则默认是调用子类复写之后的属性和方法

方式一:调用父类成员

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

方法二:使用super()调用父类成员

使用成员变量:super().成员变量
使用成员方法:super().成员方法()

class Phone:
    IMEI = None
    producer = 'ITCAST'

    def call_by_5g(self):
        print('使用5g网络进行通话')


class MyPhone(Phone):
    producer = 'ITHIMA'

    def call_by_5g(self):
        print('开启CPU单核模式,确保通话的时候省电')
        # 方法一
        # print(f'父类的厂商是:{Phone.producer}')
        # Phone.call_by_5g(self)
        # 方法二
        print(f'父类的厂商是:{super().producer}')
        super().call_by_5g()
        print('关闭CPU单核模式,确保性能')

phone = MyPhone()
phone.call_by_5g()
print(phone.producer)

开启CPU单核模式,确保通话的时候省电
父类的厂商是:ITCAST
使用5g网络进行通话
关闭CPU单核模式,确保性能
ITHIMA

七、类型注解

方便静态类型检查工具、IDE等第三方工具,在代码中涉及数据交互的地方,提供数据类型的注解(显式的说明)

主要功能

  • 帮助第三方IDE工具(如pycharm)对代码进行类型推断,协助做代码提示
  • 帮助开发者自身对变量进行类型注解

支持

  • 变量的类型注解
  • 函数(方法)形参列表和返回值的类型注解

类型注解语法

基础语法:变量:类型

在这里插入图片描述
在这里插入图片描述
注意

  • 元组类型设置类型详细注解,需要将每一个元素都标记出来
  • 字典类型设置类型详细注解,需要2个类型,第一个是key第二个是value

# type: 类型

在注解中进行类型注释
在这里插入图片描述
选中导入的包 option+回车 自动导入包操作

显示的变量定义一般无需注解,就算不写注解也能明确的知晓变量的类型

无法直接看出变量类型时会添加变量的类型注解

类型注解只是个备注,并不会真正的对类型做验证和判断,仅仅是提示性并不是决定性,不会报错
在这里插入图片描述

函数和方法类型注解

提示性非决定性注解

形参注解

def 函数方法名(形参名: 类型, 形参名: 类型,...):
	pass

command + p 提示注解

在这里插入图片描述

返回值注释

def 函数方法名(形参名: 类型, 形参名: 类型,...) ->返回值类型:
	pass

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

union联合类型注解

Union[类型, …, 类型]可以定义联合类型注解

导包方式:from typing import Union
在这里插入图片描述
在这里插入图片描述

八、多态

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

多态常用在继承关系上,比如函数(方法)形参声明接收父类对象,实际传入父类的子类对象进行工作

  • 以父类做定义声明
  • 以子类做实际工作
  • 用以获得同一行为,不同状态
class Animal:
    def speak(self):
        pass


class Dog(Animal):
    def speak(self):
        print('汪汪汪')


class Cat(Animal):
    def speak(self):
        print('喵喵喵')


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


dog = Dog()
cat = Cat()

make_noise(dog)
make_noise(cat)

汪汪汪
喵喵喵

抽象类(接口)

在这里插入图片描述
用父类来确定有哪些方法,具体的方法实现由子类自行决定,这种写法叫抽象类

抽象类:含有抽象方法的类称之为抽象类
抽象方法:方法体是空实现的(pass)称之为抽象方法
在这里插入图片描述
配合多态完成:

  • 抽象的父类设计(设计标准)
  • 具体的子类实现(实现标准)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值