【Python】面向对象

笔者学过Java,对面向对象有一定了解,故内容可能不够全面

在类中,不仅可以定义属性用来记录数据,也可以定义函数,用来记录行为

  • 类中定义的属性(变量),我们称之为:成员变量
  • 类中定义的行为(函数),我们称之为:成员方法
class Student:
    name = None
    age = None
    gender = None
#上面的3个变量为Student类的属性,下面的函数为它的行为
    def sayHi(self):
        print(f"Hi,我是{self.name}")
        
    def sayHi1(self,msg):
        print(f"Hi,我是{self.name},{msg}")
        
stu1 = Student()
stu1.name = "root"
stu1.age = 23
stu1.gender = "female"
stu1.sayHi()
print(f"我的年龄是{stu1.age}")
stu2 = Student()
stu2.name = "坤坤"
stu2.sayHi1("哎呦你干嘛")

在类中定义成员方法和定义函数基本一致,但仍有细微区别:

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

可以看到,在方法定义的参数列表中有一个self关键字

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

  • 它用来表示类对象自身的意思
  • 当我们实用类对象调用方法时,self会自动被python传入
  • 在方法内部,想要访问类的成员变量,必须使用self

类比this关键字

魔术方法

构造方法

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

  • 在创建类对象(构造类)的时候,会自动执行
  • 在创建类对象(构造类)的时候,将传入参数自动传递给__init__()方法使用
class Student:
    name = None
    age = None
    gender = None

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

stu1 = Student("Fat Cat",21,"男")
print(stu1.name)

字符串方法

__str__()

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

class Student:
    name = None
    age = None
    gender = None

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

    def __str__(self):
        return f"Student类对象,name:{self.name},age:{self.age},gender:{self.gender}"

stu1 = Student("Fat Cat",21,"男")
print(stu1)

如果没有字符串方法,直接输出stu1会输出内存地址

小于符号比较方法

__lt__()

自定义对象比较规则

class Student:
    name = None
    age = None

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

    def __lt__(self, other):
        return self.age < other.age

stu1 = Student("张三",28)
stu2 = Student("罗翔",35)
print(stu1 < stu2)#True
print(stu1 > stu2)#False

小于等于符号比较方法

__le__()

小于符号比较方法不能比较等于的情况

class Student:
    name = None
    age = None

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

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

stu1 = Student("李四",35)
stu2 = Student("罗翔",35)
print(stu1 <= stu2)#True
print(stu1 >= stu2)#True

等于符号比较方法

__eq__()

不使用此方法,两个对象可以用"==“运算符进行比较,比较的是内存地址,两个不同的对象这样比较,结果必然是"False”,而使用此方法可以自定义比较规则

class Student:
    name = None
    lastname = None

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

    def __eq__(self, other):
        return self.lastname == other.lastname

stu1 = Student("罗永浩","罗")
stu2 = Student("罗翔","罗")
print(stu1 == stu2)#True

封装

私有成员

  • 私有成员变量:变量名以两个下划线开头
  • 私有成员方法:方法名以两个下划线开头

对于私有成员,类对象无法直接使用,但其内部其他成员可以使用

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()

继承

class 类名(父类名):
     类内容体

子类从父类那里继承成员变量和方法(不含私有)

class Phone:
   IMEI = None #序列号
   producer = None #厂商

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

class Phone2022(Phone):
    face_id = True #面部识别

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

iPhone14Pro = Phone2022()
iPhone14Pro.producer = "锤子"
print(iPhone14Pro.producer)
iPhone14Pro.call_by_4g()
iPhone14Pro.call_by_5g()

上面示例为“单继承

多继承

顾名思义,继承多个父类

class 类名(父类1,父类2,...父类N):
     类内容体

代码示例省略

这里我们说一种情况,当我们子类继承了多个父类后,继承的很完善,不需要再添加内容,但我们也不能直接空着,这时候我们可以写一个"pass"

多个父类中,如果有同名的成员,那么默认以继承顺序(从左到右)为优先级,即按照先继承的。

复写

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

class Phone:
   IMEI = None #序列号
   producer = "锤子" #厂商

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

class Phone2022(Phone):
    producer = "苹果"
    face_id = True #面部识别

    def call_by_4g(self):
        print("您当前选择使用4g通话,如果要使用5g通话请进行切换")
        
    def call_by_5g(self):
        print("2022最新5g通话")

iPhone14Pro = Phone2022()
print(iPhone14Pro.producer)
iPhone14Pro.call_by_4g()

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

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

方式1:

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

方式2:

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

代码示例省略

类型注解

Python在3.5版本的时候引入了类型注解,以方便静态类型检查工具,IDE等第三方工具

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

主要功能:

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

支持:

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

对变量设置类型注解

#基础语法:变量:类型
import json
import random
#基础数据类型注解
var1:int = 10
var2:float = 3.1415926
var3:bool = True
var4:str = "Sweet Dreams (Mixed)"
#类对象类型注解
class Student:
    pass
stu:Student = Student()
#基础容器类型注解
list1:list = [1,2,3]
tuple1:tuple = (1,2,3)
set1:set = {1,2,3}
dict1:dict = {"rainy":1}
#容器类型详细注解
my_list:list[int] = [1,2,3]
my_tuple:tuple[str,int,bool] = ("root",1111,True)
my_set:set[int] = {1,2,3}
my_dict:dict[str,int] = {"windy":5}
#在注释中进行类型注解
data = '{"春":1,"夏":2,"秋":3,"冬":4}'
def func():
    pass
test1 = random.randint(1,10) # type:int
test2 = json.loads(data) # type:dict[str,int]
test3 = func() #type:Student
  • 元组类型设置类型详细注解,需要将每一个元素都标记出来
  • 字典类型设置类型详细注解,需要2个类型(key和value)

类型注解不是强制性的,如果注解的和实际的不一致也不会报错(会提示警告),程序也能正常运行

sentence:int = "hello"
print(sentence)

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

#对形参进行类型注解
def add(x:int, y:int):
    return x+y
#对返回值进行类型注解
def func(data) -> list:
    return data

Union类型

#可以使用Union[类型,......,类型]定义联合类型注解
from typing import Union
my_list:list[Union[str,int]] = [1,2,"itheima","itcast"]
my_dict:dict[str,Union[str,int]] = {"name":"周杰轮","age":31}
def func(data:Union[int,str]) -> Union[int,str]:
    pass

多态

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

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)

这种设计的含义是:父类用来确定有哪些方法,具体的方法实现由子类自行决定

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

抽象类:含有抽象方法的类称之为抽象类

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

  • 36
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值