第六章-类与对象

class 类名称:

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

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

举例:

class Student:
    name = None
    place = None
    age = None
    def say_hi(self):
        print(f"你好,我是{self.name}")

stu1 = Student()
stu1.name = "方靓仔"
stu1.place = "山东省"
stu1.age = 23

print(stu1.age)
stu1.say_hi()

其中,self关键字是成员方法定义的时候必须填写的,用来表示类对象自身。

上面这个代码中的say_hi方法又称为成员方法

类和对象

例子:

假如闹钟有两个属性,id和price和一个行为:响铃ring

import winsound
# 设计一个闹钟类
class clock:
    id = None
    price = None
    def ring(self):
        winsound.Beep(500,500)

# 构造两个闹钟,并让他们工作
clock1 = clock()
clock1.id = "6501"
clock1.price = 20
print(f"闹钟ID:{clock1.id}")
clock1.ring()

clock2 = clock()
clock2.id = "6502"
clock2.price = 22
print(f"闹钟ID:{clock2.id}")
clock2.ring()

魔术方法

Python类内置方法被称为魔术方法

__init__构造方法
__str__字符串方法(类对象转换为字符串)
__lt__小于、大于符号比较

__le__

小于等于、大于等于符号比较
__eq__等于==符号比较

__init__方法

__init__方法是构造方法,创建类对象或构造类时自动执行,同时传入参数自动传递给__init__方法。需要注意的是包括__init__方法在内的几个魔术方法前面和后面都有两条下划线。

class Student:
    def __init__(self, name, id):
        self.name = name
        self.id = id
        print("Student类创建了一个对象")
stu = Student("睿智阿杰", 356)
print(stu.name, stu.id)
# python类内置的方法称为魔术方法
# init构造方法 str字符串方法(类对象转字符串) lt小于、大于符号比较 le小于等于、大于等于符号比较 eq等于符号比较
class student:
    def __init__(self,name,id):
        self.name=name
        self.id=id
    def __str__(self):
        return f'student类对象,name={self.name},id={self.id}'
    def __lt__(self,other):
        return self.id < other.id
    def __le__(self,other):
        return self.id <= other.id
    def __eq__(self,other):
        return self.id == other.id
stu1 = student("睿智杰",356)
stu2 = student("帅哥方",360)
stu3 = student("陈小明",360)
print(stu1)
print(str(stu2))
print('stu1 > stu2',stu1 > stu2)
print('stu1 < stu2',stu1 < stu2)
print('stu3 > stu2',stu3 > stu2)
print('stu3 >= stu2',stu3 >= stu2)
print('stu1 <= stu2',stu1 <= stu2)
print('stu3 == stu2',stu3 == stu2)
print('stu1 == stu2',stu1 == stu2)

☆封装

在实际开发中,不是每一个属性和行为都是公开的,所以使用私有成员来隐藏他们。

私有成员变量的变量名,私有成员方法的方法名都以__开头(两条下划线)。

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

class Phone:
    __current_voltage = 0.6 # 手机运行电压
    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通话,已设置为单核模式省电")
"""
test_phone = Phone()
print(test_phone.__keep_single_core())
# 无法运行
"""

# 私有成员无法被类对象使用,但是可以被其他的成员使用
phone = Phone()
phone.call_by_5g()

例题

设计带有私有成员的手机
设计一个手机类,内部包含:
私有成员变量: __is_5g_enable,类型bool,True表示开启5g,False表示关闭5g

私有成员方法:__check 5g(),会判断私有成员__is_5g_enable的值

        若为True,打印输出:5g开启
        若为False,打印输出:5g关闭,使用4g网络
公开成员方法:call_by_5g(),调用它会执行
        调用私有成员方法:__check_5g(),判断5g网络状态
        打印输出:正在通话中
运行结果:

                5g关闭,使用4g

                网络正在通话中
通过完成这个类的设计和使用,体会封装中私有成员的作用
对用户公开的,call_by_5g()方法
对用户隐藏的,__is_5g_enable私有变量和__check_5g私有成员

我的作答

class phone:
    __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("正在通话中")
mobile = phone()
mobile.call_by_5g()

☆继承

继承可以理解为每次设计新手机都可以基于老设计图修改,而非从0开始

单继承

单继承只继承一个父类,直接将父类写在括号里

继承将会从父类那里复制粘贴来成员变量和成员方法,但是不含私有成员变量和私有成员方法。

class phone2022:
    id = 369
    producer = '啊哈'
    def call_by_4g(self):
        print("可以4G通话")
class phone2023(phone2022):
    face_id = 567
    def call_by_5g(self):
        print("可以5g通话")
phone = phone2023()
print(phone.id, phone.face_id)
phone.call_by_4g()
phone.call_by_5g()

多继承

多继承可以继承多个父类,将父类与父类在括号中用逗号隔开。

当然,成员方法如果重名,按照继承的顺序,越往左优先级越高。

(代码接上条)

class RemoteControl:
    id = 503
    def control(self):
        print("红外遥控开启了")
# pass用于补充语法
class MyPhone(RemoteControl,phone2023):
    pass
# pass表示无内容,空的意思
phone = MyPhone()
phone.control()
print(phone.id)

复写

子类中重新定义同名的属性或方法

class Phone:
    id = 2
    def call(self):
        print("父类的通话")
class MyPhone(Phone):
    id = 16
    def call(self):
        print("子类的通话")
mobile = MyPhone()
mobile.call()

调用

调用父类成员变量super().成员变量父类名.成员变量
调用父类成员方法super.成员方法()父类名.成员方法(self)
class MyNewPhone(Phone):
    id = 17
    def call(self):
        print(f"父类的编号{Phone.id}")
        Phone.call(self)
    def call2(self):
        print(f"父类编号{super().id}")
        super().call()
newphone = MyNewPhone()
newphone.call()
newphone.call2()

类型注解

传参时快捷键ctrl+p可以弹出提示

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

显示的变量定义一般无需注解,即能一眼看出来就不用类型注解了

基础语法

变量:类型

import json
import random
# 基础数据类型注解
var1: int = 35
var2: str = 'fang'
var3: bool = True
# 类对象类型注解
class Student:
    pass
stu: Student = Student()
# 基础容器类型注解
mylist1: list = [1, 2, 3]
mytuple1: tuple = (1, 2, 3)
mydict1: dict = {'a': 1, 'b': 2, 'c': 3}
# 容器类型详细注解
mylist2: list[int] = [1, 2, 3]
mytuple2: tuple[int, str, bool] = (1, 'f', True)
mydict2: dict[str, int] = {'a': 1, 'b': 2, 'c': 3}
# 在注释中进行类型注解
var4 = random.randint(1, 10)    # type: int
var5 = json.loads('{"name":"zhangsan"}') # type: dict[str,str]
def func():
    return 10
var6 = func() # type: int

类型注解的限制

类型注解仅仅是提示性的,不是决定性的,比如下面这行不合理的代码仅仅是警告而非报错

var7: int = 'fang'

函数的类型注解

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

Union类型的类型注解

使用Union类型,必须先导包

from typing import Union

Union[类型1,类型2,...]

from typing import Union
mylist: list[int] = [1, 2, 3]
# Union类型
mylist2: list[Union[int, str]] = [1, 2, 'fang', 'interesting']
mydict: dict[str, Union[int, str]] = {'name': 'fang','age':24}
print(mydict)
# 使用Union类型,必须先导包
# from typing import Union
def func(data: Union[int, str]) -> Union[int, str]:
    pass
func()

☆多态

多肽是多个氨基酸通过肽键连接形成的化合物

多态是父类中的方法可以被不同子类用不同方式实现。

class Animal:
    def speak(self):
        pass
class Dog(Animal):
    def speak(self):
        print("汪汪汪")
class Cat(Animal):
    def speak(self):
        print("喵")
Dog().speak()
Cat().speak()

比如这段代码中同样是speak方法,Dog类调用speak方法和Cat类调用speak方法输出不同,有不同的表现。

这种写法也就是抽象类了。

说白了就是子承父业,父亲指明方向,告诉孩子有这个东西,孩子努力实现。

抽象类:含有抽象方法的类

抽象方法:方法体是空实现的pass,有两个专门做空调的厂商方集团和李集团

注意:子类需要父类中的每一个抽象类,一个都不能漏

举个例子:

比如制定空调的标准是会制冷和制热和摆风

class standard:
    def cool_wind(self):
        pass
    def hot_wind(self):
        pass
    def swing(self):
        pass
class fang(standard):
    def cool_wind(self):
        print("方集团研究的制冷")
    def hot_wind(self):
        print("方集团研究的制热")
    def swing(self):
        print("方集团研究的摆风")
class li(standard):
    def cool_wind(self):
        print("李集团研究的制冷")
    def hot_wind(self):
        print("李集团研究的制热")
    def swing(self):
        print("李集团研究的摆风")
def make_cool(a: standard):
    a.cool_wind()
producer1 = fang()
producer2 = li()
make_cool(producer1)
make_cool(producer2)

课堂案例——猫狗大战

class Cat:
    role = 'cat'
    def __init__(self, name, breed, bite, value):
        self.name = name
        self.breed = breed
        self.value = value
        self.bite = bite
    def attack(self,dog):
        dog.value -= self.bite
    def eat(self):
        self.value += 50
    def die(self):
        if self.value <= 0:
            print("cat die")
        else:
            print(self.name,"生命值还有",self.value)
class Dog:
    role = 'dog'
    def __init__(self, name, breed, bite, value):
        self.name = name
        self.breed = breed
        self.value = value
        self.bite = bite
    def attack(self,cat):
        cat.value -= self.bite
    def eat(self):
        self.value += 50
    def die(self):
        if self.value <= 0:
            print("dog die")
        else:
            print(self.name,"生命值还有",self.value)
a = Cat('1','jumao',30,500)
b = Dog('2','jinmao', 50, 300)
a.die()
b.die()
a.attack(b)
b.die()


基础部分到此完毕,后面Python程序设计基础部分会更新一些例题和修改一些存在问题的表述。加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值