[Python] 自学记录 之 面向对象

目录

一、初识对象

二、成员方法

1、类的定义和使用

 2、成员变量和成员方法

 3、成员方法的定义语法

三、类和对象

1. 类和对象的关系是什么?

2. 什么是面向对象编程?

四、构造方法

五、其他内置方法

1、__str__

2、__lt__  --> <

3、__le__ -->   <=

4、__eq__  -->==

六、面向对象的三大特性:

1、封装

2、继承

​编辑

1)单继承

2)多继承

一个类继承多个类,按照顺序从左向右依次继承

3)复写

3、类型注解

类型注解的语法

3、多态


一、初识对象

使用对象组织数据

在程序中是可以做到和生活中那样,设计表格、生产表格、填写表格的组织形式的。

1. 在程序中设计表格,我们称之为:设计类(class)

class student:
    name=None

 2. 在程序中打印生产表格,我们称之为:创建对象

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

 3. 在程序中填写表格,我们称之为:对象属性赋值

#基于类创建对象
stu_1.name='盐汽水'
stu_2.name='小海螺'

二、成员方法

1、类的定义和使用

 

class是关键字,表示要定义类了

类的属性,即定义在类中的变量(成员变量)

 类的行为,即定义在类中的函数(成员方法)

创建类对象:

 2、成员变量和成员方法

类中定义的属性(变量),我们称之为:成员变量

class student:
    name=None
    age=None

类中定义的行为(函数),我们称之为:成员方法

    def say_hi(self,msg):
        print(f'hello,{msg}')
stu=student()
stu.name='盐汽水'
stu.say_hi()

 3、成员方法的定义语法

 self关键字是成员方法定义的时候,必须填写。self出现在形参列表中,但是不占用参数位置,无需理会。

它用来表示类对象自身的意思 当我们使用类对象调用方法的是,self会自动被python传入(传参的时候不用管)

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

class student:
    name=None
    def say_hi(self):
       print('hello')

    def say_hi(self,msg):
        print(f'hello,{msg}')
stu=student()
print(stu.say_hi())#调用时无需传参
print(stu.say_hi2("i'm fine"))#传不是self的参即可

 可以看到,在传入参数的时候,self是透明的,可以不用理会它。        

三、类和对象

类只是一种程序内的“设计图纸”,需要基于图纸生产实体(对象),才能正常工作 这种套路,称之为:面向对象编程 

即设计类,基于类创建对象,由对象做具体的工作

1. 类和对象的关系是什么?

类是程序中的“设计图纸”

对象是基于图纸生产的具体实体

2. 什么是面向对象编程?

面向对象编程就是,使用对象进行编程。

即,设计类,基于类创建对象,并使用对象来完成具体的工作

四、构造方法

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

前后都有2个下划线

在创建类对象(构造类)的时候,会自动执行。

在创建类对象(构造类)的时候,将传入参数自动传递给__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('盐汽水',18,'6156214')
print(stu.name)
print(stu.age)
print(stu.tel)

 在构造方法内定义成员变量,需要使用self关键字,变量是定义在构造方法内部,如果要成为成员变量,需要用self来表示。

五、其他内置方法

魔术方法

1、__str__

class Student:
    def __init__(self,name,age):
        self.name=name
        self.age=age
student=Student('盐汽水',18)
print(student)#==><__main__.Student object at 0x00000202A1601E80>
print(str(student))#==><__main__.Student object at 0x00000202A1601E80>

 当类对象需要被转换为字符串时,会输出如上结果(内存地址)

内存地址没有多大作用,我们可以通过__str__方法,控制类转换为字符串的行为。

提供__str__ 在要转换成字符串时输出是自己定制的字符串

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}'
student=Student('盐汽水',18)
print(student)#==>Student类对象,name=盐汽水,age=18
print(str(student))#==>Student类对象,name=盐汽水,age=18

2、__lt__  --> <

传入参数:other,另一个类对象

返回值:True 或 False

内容:自行定义

比较大于符号的魔术方法是:__gt__

不过,实现了__lt__,__gt__就没必要实现了

class Student:
    def __init__(self,name,age):
        self.name=name
        self.age=age
student1=Student('盐汽水',18)
student2=Student('小海螺',19)
print(student1<student2)
#错误!不支持这两者比较

直接对2个对象进行比较是不可以的,但是在类中实现__lt__方法,即可同时完成:小于符号 和 大于符号 2种比较

class Student:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __lt__(self,other):
        return self.age<other.age
student1=Student('盐汽水',18)
student2=Student('小海螺',19)
print(student1<student2)#==>True
print(student1>student2)#==>False

3、__le__ -->   <=

传入参数:other,另一个类对象

返回值:True 或 False

内容:自行定义

>=符号实现的魔术方法是:__ge__

不过,实现了__le__,__ge__就没必要实现了

class Student:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __le__(self,other):
        return self.age<=other.age
student1=Student('盐汽水',18)
student2=Student('小海螺',19)
print(student1<=student2)#==>True
print(student1>=student2)#==>False

4、__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
student1=Student('盐汽水',18)
student2=Student('小海螺',19)
print(student1==student2)#==>False

不实现__eq__方法,对象之间可以比较,但是是比较内存地址,也即是:不同对象==比较一定是False结果。

实现了__eq__方法,就可以按照自己的想法来决定2个对象是否相等了。

总结

方法

功能

__init__

构造方法,可用于创建类对象的时候设置初始化行为

__str__

用于实现类对象转字符串的行为

__lt__

用于2个类对象进行小于或大于比较

__le__

用于2个类对象进行小于等于或大于等于比较

__eq__

用于2个类对象进行相等比较

六、面向对象的三大特性:

面向对象编程,是许多编程语言都支持的一种编程思想。 简单理解是:基于模板(类)去创建实体(对象),使用对象完成功能开发。

面向对象包含3大主要特性:

封装 继承 多态

1、封装

封装表示的是,将现实世界事物的:属性 行为

封装到类中,描述为: 成员变量 成员方法

私有成员-->只能内部自己使用,对象不能用

现实事物有部分属性和行为是不公开对使用者开放的。同样在类中描述属性和方法的时候也需要达到这个要求

 类中提供了私有成员的形式来支持 私有成员变量 私有成员方法

定义私有成员的方式非常简单,只需要:

私有成员变量:变量名以__开头(2个下划线)

私有成员方法:方法名以__开头(2个下划线) 即可完成私有成员的设置

class Phone:
    __current_voltage=None
    def __keep_single_core(self):
        print('让CPU以单核运行')

phone=Phone()
print(phone.__current_voltage)#==>报错
phone.__keep_single_core#==>报错

私有方法无法直接被类对象使用 

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

class Phone:
    __current_voltage=1
    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('电量不足')
phone=Phone()
phone.call_by_5g()#-->5g通话已开启

类对象无法访问私有成员

类中的其它成员可以访问私有成员

私有成员意义:在类中提供仅供内部使用的属性和方法,而不对外开放(类对象无法使用)

2、继承

继承就是一个类,继承另外一个类的成员变量和成员方法

继承分为:单继承和多继承 使用如图语法,可以完成类的单继承。

继承表示:将从父类那里继承(复制)来成员变量和成员方法(不含私有)

1)单继承

一个类继承另一个类

class Phone:
    IMEI=None
    producer=None
    def call_by_4g(self):
            print("4g通话")

class Phone2022(Phone):#继承->Phone 里的都能用
    face_id=True #新功能
    def call_by_5g(self):
            print("5g通话")
phone=Phone2022()
phone.call_by_4g()#-->4g通话

2)多继承

一个类继承多个类,按照顺序从左向右依次继承

Python的类之间也支持多继承,即一个类,可以继承多个父类

class Phone:
    IMEI=None
    producer=None
    def call_by_5g(self):
            print("5g通话")

class NFCReader:
    nfc_type='第五代'
    producer='HM'
    def read_carf(self):
            print("读取NFC卡")
    def write_card(self):
        print("写入NFC")

class RemoteCoontrol:
    rc_type="红外遥控"

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

class MyPhone(Phone,NFCReader,RemoteCoontrol):
    pass

phone=MyPhone()
phone.call_by_5g()
phone.read_carf()
phone.write_card()
phone.control()

多个父类中,如果有同名的成员,那么默认以继承顺序(从左到右)为优先级。 即:先继承的保留,后继承的被覆盖

子类构建的类对象,可以 :
1)有自己的成员变量和成员方法 2)使用父类的成员变量和成员方法

pass关键字的作用: pass是占位语句,用来保证函数(方法)或类定义的完整性,表示无内容,空的意思

3)复写

对父类的成员属性或成员方法进行重新定义

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

class Phone:
    IMEI=None
    producer="盐汽水"
    def call_by_5g(self):
            print("父类的5g通话")
        
class MyPhone(Phone):
    producer="小海螺"
    def call_by_5g(self):
            print("子类的5g通话")
        
phone=MyPhone()
phone.call_by_5g()#-->子类的5g通话

调用父类同名成员

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

方式1:

调用父类成员  

使用成员变量:父类名.成员变量      

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

方式2: 使用super()调用父类成员      

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

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

注意:只可以在子类内部调用父类的同名成员,子类的实体类对象调用默认是调用子类复写的

法一:

class Phone:
    IMEI=None
    producer="盐汽水"
    def call_by_5g(self):
            print("父类的idol头衔")

class MyPhone(Phone):
    producer="小海螺"
    def call_by_5g(self):
            print(f'父类的idol头衔是{Phone.producer}')#->父类的idol头衔是盐汽水
            Phone.call_by_5g(self)#->父类的idol头衔
            print("子类的idol头衔")

phone=MyPhone()
phone.call_by_5g()

法二:

class Phone:
    IMEI=None
    producer="盐汽水"
    def call_by_5g(self):
            print("父类的idol头衔")

class MyPhone(Phone):
    producer="小海螺"
    def call_by_5g(self):
            print(f'父类的idol头衔是{super().producer}')#->父类的idol头衔是盐汽水
            super().call_by_5g()#->父类的idol头衔
            print("子类的idol头衔")

phone=MyPhone()
phone.call_by_5g()

3、类型注解

一、PyCharm确定这个对象,是list类型,就可以提示

 二、当我们调用方法,进行传参的时候(快捷键ctrl + p弹出提示):

提示传入2个参数 类型是int

类型注解:在代码中涉及数据交互的地方,提供数据类型的注解(显式的说明)。 主要功能:

主要功能:

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

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

支持:

变量的类型注解

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

类型注解的语法

1、为变量设置类型注解 基础语法:  变量: 类型

 

元组类型设置类型详细注解,需要将每一个元素都标记出来

字典类型设置类型详细注解,需要2个类型,第一个是key第二个是value

2、 也可以在注释中进行类型注解

语法: # type: 类型

class Student:
    pass

var_1=random.randint(1,10)   #type:int
var_2=json.loads('{"name":"zhangsna"}')       #type:dict[str,str]
var_3=Student()              #type:Student

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

并不会真正的对类型做验证和判断。 也就是,类型注解仅仅是提示性的,不是决定性的

如图代码,是不会报错的

函数(方法)的类型注解 - 形参注解

函数和方法的形参类型注解语法:

 

 

 函数(方法)的类型注解 - 返回值注解

 

 

 注意,返回值类型注解的符号使用: ->

Union类型

使用Union[类型, ......, 类型] 可以定义联合类型注解 

Union的使用方式 导包:from typing import

Union 使用:Union[类型, ......, 类型]

 Union联合类型注解,在变量注解、函数(方法)形参和返回值注解中,均可使用。

3、多态

同样的行为(函数),传入不同的对象,得到不同的状态

多态常作用在继承关系上.

比如 函数(方法)形参声明接收父类对象  实际传入父类的子类对象进行工作

即: 以父类做定义声明 以子类做实际工作 用以获得同一行为, 不同状态

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)#喵喵喵

父类Animal的speak方法,是空实现,这种设计的含义是:

父类用来确定有哪些方法 具体的方法实现,由子类自行决定

这种写法,就叫做抽象类(也可以称之为接口)

抽象类(接口):含有抽象方法的类称之为抽象类,抽象类就好比定义一个标准, 包含了一些抽象的方法,要求子类必须实现。

抽象方法:方法体是空实现的(pass)称之为抽象方法

配合多态,完成:

抽象的父类设计(设计标准)

具体的子类实现(实现标准)

class AC:
    def cool_wind(self):
        '''制冷'''
        pass
    def hot_wind(self):
        '''制热'''
        pass
    def swing(self):
        '''左右摆风'''

class Midea(AC):
    def cool_wind(self):
        print("美的空调核心制冷")
    
    def hot_wind(self):
        print("美的空调核电热丝加热")
    
    def swing(self):
        print("美的空调左右摆风")

class GREE(AC):
    def cool_wind(self):
        print("格力空调核心制冷")

    def hot_wind(self):
        print("格力空调核电热丝加热")

    def swing(self):
        print("格力空调左右摆风")

def make_cool(ac:AC):
    ac.cool_wind()

Midea_AC=Midea()
GREE_AC=GREE()

make_cool(Midea_AC)#美的空调核心制冷
make_cool(GREE_AC)#格力空调核心制冷

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值