第二阶段第一章——面向对象

前言

学习了这么久Python(呃其实也没多久差不多两周),可能有小伙伴说我废了,两周才学这么点,咋说呢,我曾经也是急于求成,做任何事情都是急于求成,比如我喜欢一个人我就想马上跟她在一起,我学习Java为了拉进度并没有做笔记,学习MySQL高级的内容(比如主从复制和它的底层原理这些)也是没有做笔记,学习Linux也是没有做笔记。很后悔,所以我才开始写下博客,当然这只是写博客的一部分原因。还有一些原因是我想在互联网上发疯,反正也没有人认识我是谁哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈

回归正题,面向对象,无论是Java还是C++,这一点都是很重要的一点,Python虽然是一个解释性语言,但是在设计之初就是面向对象而设计的。

对于初学一门编程语言的同学就会问啦,什么是面向对象呀?

答:面向你的男/女朋友编程  即为面向对象 \(^o^)/~( 疯狂手动俏皮)

        面向对象是一种程序设计思想,它将程序中的数据和操作数据的方法组合成一个对象,通过对象之间的交互来实现程序的功能。面向对象的程序设计思想主要包括封装、继承和多态三个方面。

封装使得对象的内部实现对外部隐藏,只有通过公共接口才能访问对象的属性和方法,从而保证了对象的安全性和可靠性。继承让子类可以复用父类的属性和方法,并且可以在子类中新增或重写父类的属性和方法,从而简化了程序的设计和维护。多态则使得同一个方法可以具有多种不同的行为,增加了程序的灵活性和可扩展性。

这一章主要有以下内容

1.初识对象

2.成员方法

3.类和对象

4.构造方法

5.其他内置方法

6.封装

7.继承

8.类型注解

9.多态

10.综合案例

GOGOGO!!!!!


1.初识对象

第二阶段第一章——面向对象_第1张图片

代码示例:

"""
    初识面向对象
"""
# 1.设计一个类(类比:生活中设计一张登记表)
class Student:
    name = None
    sex = None
    nationality = None
    native_place = None
    age = None
# 2.创建一个对象(类比:生活中打印一张登记表)
stu_1 = Student()
# 3.对象属性进行赋值(类比:生活中填写一张登记表)
stu_1.name = "瓦坎达!!!"
stu_1.sex = "男"
stu_1.nationality = "地球瓦坎达"
stu_1.native_place = "地球"
stu_1.age = "19"
# 4.获取对象中记录的信息
print(stu_1.name)
print(stu_1.sex)
print(stu_1.nationality)
print(stu_1.native_place)
print(stu_1.age)


2.成员方法

(1)成员方法的概念

通过上面的,你已经了解了如何使用了,那么就来系统的了解一下吧

第二阶段第一章——面向对象_第2张图片

类里面包含两个东西

第二阶段第一章——面向对象_第3张图片

属性我们在上面已经见识过了

那么类里面的属性又是什么呢?

第二阶段第一章——面向对象_第4张图片

也就是类里见提供的函数(方法)了

也就是===》》成员方法

(2)成员方法的创建

那么该如何来创建成员方法呢?、

和我们曾今创建方法的方式差不多,但是有一个小差别

第二阶段第一章——面向对象_第5张图片

注意:传参时,可以当做self并不存在,不必理会

(3)代码示例

"""
    成员方法
"""


# 定义一个带有成员方法的类
class Student:
    name = None

    def say_hi(self):
        print(f"大家好,我是{self.name},o(* ̄▽ ̄*)ブ")

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

stu = Student()
stu.name = "lyy"

stu.say_hi()

stu2 = Student()
stu2.name = "wgg"
stu2.say_hello("(*´▽`)ノノ")




3.类和对象

这里来深刻的体会一下面向对象的思想

第二阶段第一章——面向对象_第6张图片

类是图纸,对象是实现 

代码实现

"""
    体会面向对象编程
"""
import winsound


# 设计一个闹钟类
class Clock:
    id = None
    price = None

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


clock1 = Clock()
clock1.id = "001"
clock1.price = 812
clock1.ring()

print(f"闹钟id:{clock1.id},价格:{clock1.price}")

clock2 = Clock()
clock2.id = "002"
clock2.price = 313
clock2.ring()
print(f"闹钟id:{clock1.id},价格:{clock1.price}")


4.构造方法

(1)使用构造方法

构造方法还是挺简单的,简化了赋值操作

其实这里的self,学到这里就可以发现和Java里面的  this关键词有点类似了

第二阶段第一章——面向对象_第7张图片

"""
    演示构造方法
"""

"构造方法的名称为::__init__"
class Student:
    # 这里写不写无所吊谓
    name = None
    sex = None
    age = None

    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age
        print(f"student类创建了一个类")

stu = Student("lyy", "男", 19)
print(stu.name)
print(stu.age)
print(stu.sex)

(2)练习案例:学生信息录入

第二阶段第一章——面向对象_第8张图片

代码示例

"""
    练习案例,学生信息录入
"""
class Student:
    name = None
    age = None
    address = None

    def __init__(self, name, age, address):
        self.name = name
        self.age = age
        self.address = address
        print(f"学生信息录入完成:【姓名:{name},年龄:{age},地址{address}】")



# 共需要录入10个学生
stu_num = int(input("请输入共需要录入多少学生"))

for stu in range(1, stu_num + 1):
    stu_name = input("请输入学生姓名")
    stu_age = input("请输入年龄")
    stu_address = input("请输入地址")
    stu = Student(stu_name, stu_age, stu_address)


5.其他内置方法(魔术方法)

(1)__str__字符串方法

第二阶段第一章——面向对象_第9张图片

但是哈

第二阶段第一章——面向对象_第10张图片

咋说呢,我只能说和Java的toString( )方法是差不多的

(2)__lt__小于、大于符号比较

第二阶段第一章——面向对象_第11张图片

(3)__le__小于等于、大于等于符号比较

第二阶段第一章——面向对象_第12张图片

(4)__eq__ ==符号比较

第二阶段第一章——面向对象_第13张图片

 

(5)总结

第二阶段第一章——面向对象_第14张图片

"""
    演示其他的内置方法
"""


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

    # (1)__str__字符串方法
    def __str__(self):
        return f"name:{self.name},age:{self.age}"

    # (2)__lt__小于、大于符号比较
    def __lt__(self, other):
        return self.age < other.age

    # (3)__le__小于等于、大于等于符号比较
    def __le__(self, other):
        return self.age <= other.age

    # (4)__eq__ ==符号比较
    def __eq__(self, other):
        return self.age == other.age


stu1 = Student("lyy", 18)
stu2 = Student("wgg", 19)
stu3 = Student("GO", 19)
print(stu1 < stu2)
print(stu1 <= stu2)
print(stu2 == stu3)



 


6.封装

面向对象三大特性

封装、继承和多态

(1)封装

第二阶段第一章——面向对象_第15张图片

(2)私有成员

相比于Java的区别,这里私有成员的定义是使用 ' __  '两个下划线 而不是private

第二阶段第一章——面向对象_第16张图片

(3)使用私有成员

其实  私有成员也就是只能给“自己人”用

曾今的方法显然是不管用的,那么

第二阶段第一章——面向对象_第17张图片

如何使用私有成员呢?

第二阶段第一章——面向对象_第18张图片

代码示例:

"""
    演示私有成员
"""


class Phone:
    __current_voltage = 0.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.__keep_single_core  用不了
# phone.__current_voltage 也用不了

phone.call_by_5G()

(4)练习案例:设计带有私有成员的手机

第二阶段第一章——面向对象_第19张图片

参考代码:

"""
    设计带有私有成员的手机
"""


class Phone:
    __is_5g_enable = False

    def __check_5g(self):
        if self.__is_5g_enable == True:
            print("5g开启")
        else:
            print("5g关闭,使用4g信号")

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

    def open_or_down_5g(self):
        """
        是否开启5g
        :return:
        """
        str = input("你是否要开始y/n")
        if str == "y":
            self.__is_5g_enable = True
        else:
            self.__is_5g_enable = False


phone = Phone()
phone.open_or_down_5g()
phone.call_by_5g()


7.继承

如何理解继承?

答:

继承是面向对象编程中的一个概念,它指的是一个新类(子类)可以从现有的类(父类)继承属性和方法。在继承中,父类中存在的公共属性和方法可以被子类直接使用,子类也可以根据需要重写父类中的方法或添加新的属性和方法。

继承可以帮助程序员重用已有的代码和类,避免重复的编写和维护。继承也可以实现代码的扩展和灵活性,子类可以在不改变原有功能的基础上,增加新的功能。

继承的实现方式可以通过关键字extends来实现,子类可以继承父类的属性和方法,并且可以调用父类的构造器来初始化子类的对象。在Java中,一个子类只能继承一个直接父类,但是可以通过多级继承从祖先类中继承属性和方法。

(1)单继承

相比于Java的继承方法采用extend关键词,这里只需要将父类作为参数传入即可

第二阶段第一章——面向对象_第20张图片

(2)多继承

这里就发现了又一个和Java 的区别了,Java是不支持多继承的,而Python是支持的

第二阶段第一章——面向对象_第21张图片

注意事项

谁先继承,谁的优先级更高

第二阶段第一章——面向对象_第22张图片

(3)复写

其实就是相当于Java的重写

第二阶段第一章——面向对象_第23张图片

(4)调用父类同名成员

第二阶段第一章——面向对象_第24张图片


8.类型注解

Python 3.5引入了一种类型注解机制,即PEP 484,它使开发者可以在函数参数和函数返回值中注明变量类型。类型注解可以帮助开发者更好地理解代码,并提高代码的可读性和可维护性。

类型注解在Python中并不会严格检查类型,也不会影响程序运行。它仅仅是给开发者提供了一种规范和提示,让开发者更好地编写代码。

示例如下:


def add_numbers(a: int, b: int) -> int:
    return a + b

在这个例子中,我们使用类型注解来告诉函数参数a和b应该是整数类型,函数返回值也应该是整数类型。当然,如果我们在调用add_numbers函数时传入的参数类型不是整数,Python解释器也不会报错。但是,通过类型注解,我们可以清楚地知道这个函数的参数和返回值类型应该是什么。

我对于这个的理解是,她想约束类型,但是还是算了,所以相当于给出一个规范,你可以遵守,也建议你遵守

(1)变量的类型注解

1.普通变量

第二阶段第一章——面向对象_第25张图片

2.容器

第二阶段第一章——面向对象_第26张图片

3.在注释中进行类型注解

第二阶段第一章——面向对象_第27张图片

4.限制

第二阶段第一章——面向对象_第28张图片

代码示例;

"""
    演示变量的类型注解
"""
import json
import random

# 基础数据类型注解
var1: int = 12
var2: str = "lyy"
var3: bool = True


# 类对象类型注解
class Student:
    pass


stu: Student = Student()

# 基础容器类型注解
my_list: list = [1, 2, 3]
my_tuple: tuple = (1, 2, 3)
my_dict: dict = {"lyy": 812}
# 容器类型详细注解
my_list: list[int] = [1, 2, 3]
my_tuple: tuple[int, str, bool] = (1, "wgg", False)
my_dict: dict[str, int] = {"lyy": 812}

# 在注释中进行类型注解
var1 = random.randint(1, 10)  # type: int
var2 = json.loads('{"name":"zhangsan"}')  # type: dict[str, str]


def func():
    return 10


var3 = func()  # type: int

# 类型注解的限制
var4: int = "我就用字符串了"
# 运行也不报错

(2)函数(方法)的类型注解

1.形参注解

第二阶段第一章——面向对象_第29张图片

 2.返回值注解

第二阶段第一章——面向对象_第30张图片

整体参考代码

"""
    对函数进行类型注解
"""


# 对参数进行类型注解
def add(x: int, y: int):
    return x + y


print(add(812, 313))

# 对返回值进行注解
def func(data: list) -> list:
    return data

 

(3)Union类型

第二阶段第一章——面向对象_第31张图片

第二阶段第一章——面向对象_第32张图片

代码示例:

"""
    演示Union联合类型注解
"""
# 使用Union类型,得先导包
from typing import Union

my_list: list[Union[int, str]] = [1, 2, "lyy", "wgg"]


def func(data: Union[int, str]) -> Union[int, str]:
    pass


func()


9.多态

(1)多态的概念

第二阶段第一章——面向对象_第33张图片

多态常用于继承的关系上 

第二阶段第一章——面向对象_第34张图片

(2)抽象类(接口) 

如何理解抽象类?

答:

在Python中,抽象类是使用abc模块(Abstract Base Class)来定义的。抽象类不能被实例化,而是用来规范其他类的行为。抽象类中定义了一些抽象方法,这些方法必须在子类中被实现。

要定义一个抽象类,需要继承abc.ABC类,并使用@abc.abstractmethod来装饰抽象方法。例如:


import abc

class Animal(abc.ABC):
    @abc.abstractmethod
    def talk(self):
         pass

这里我们定义了一个Animal类,并且使用@abc.abstractmethod装饰talk()方法。这个类就是一个抽象类,不能被实例化,只能被其他类继承。

子类继承抽象类时,必须实现父类中的所有抽象方法,否则会抛出TypeError异常。例如:


class Dog(Animal):
    def talk(self):
        print("Woof!")

class Cat(Animal):
    def talk(self):
        print("Meow!")

这里我们定义了两个子类Dog和Cat,它们都继承了Animal类,并且实现了抽象方法talk()。我们可以实例化这些子类,并且调用它们的talk()方法。例如:


dog = Dog()
dog.talk()  # 输出 "Woof!"

cat = Cat()
cat.talk()  # 输出 "Meow!"

在Python中,抽象类的作用是规范子类的行为,强制子类遵循一定的规范。通过抽象类,我们可以让代码更加规范和清晰。同时,抽象类也可以作为多态的基础,让代码更加灵活和可扩展。

第二阶段第一章——面向对象_第35张图片

 为什么要使用抽象类呢?

第二阶段第一章——面向对象_第36张图片

抽象类的实现

第二阶段第一章——面向对象_第37张图片

(3)代码实现

"""
    多态的演示
"""


# 这就是抽象类,或者说是接口
class Animal:
    def speak(self):
        pass


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


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


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


dog = Dog()
cat = Cat()

make_voice(dog)
make_voice(cat)


# 演示抽象类
class AC:
    def cool_wind(self):
        """制冷"""
        pass

    def hot_wind(self):
        """制热"""
        pass

    def swing_l_r(self):
        """左右摆风"""
        pass


class Midea_AC(AC):
    def cool_wind(self):
        """制冷"""
        print("美的空调制冷")

    def hot_wind(self):
        """制热"""
        print("美的空调制热")

    def swing_l_r(self):
        """左右摆风"""
        print("美的空调左右摆风")


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

    def hot_wind(self):
        """制热"""
        print("格力空调制热")

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


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

midea_AC = Midea_AC()
gree_AC = Gree_AC()

make_cool(midea_AC)
make_cool(gree_AC)


10.综合案例

(1)案例分析

第二阶段第一章——面向对象_第38张图片

数据内容 

第二阶段第一章——面向对象_第39张图片

(2)需求分析

第二阶段第一章——面向对象_第40张图片

(3)代码实现

1.data_define.py
"""
    数据定义的类
"""

class Record:
    # 日期
    date: str = None
    # 订单id
    order_id: str = None
    # 销售额
    money: int = None
    # 销售省份
    province: str = None

    def __init__(self, date, order_id, money, province):
        self.date = date
        self.order_id = order_id
        self.money = money
        self.province = province

    def __str__(self):
        return f"date:{self.date}, id:{self.order_id},money:{self.money},province:{self.province}"
2.file_define.py
"""
    文件相关类定义
"""
import json

from data_define import Record


# 定义一个抽象类,用于做顶层设计
class FileReader:

    def read_data(self) -> list[Record]:
        """
        读取文件数据,将每一条数据都转换为Record对象
        封装到list内返回
        """
        pass


class TextFileReader(FileReader):
    # 文件路径
    path = None

    def __init__(self, path):
        self.path = path

    def read_data(self) -> list[Record]:
        """
        复写读取文件方法
        :return:
        """
        f = open(self.path, "r", encoding="UTF-8")
        record_list: list[Record] = []
        for line in f.readlines():
            # 消除 \n
            line = line.strip()
            data_list = line.split(",")
            record_list.append(
                Record(
                    data_list[0],
                    data_list[1],
                    int(data_list[2]),
                    data_list[3]
                )
            )
        f.close()
        return record_list


class JsonFileReader(FileReader):
    # 文件路径
    path = None

    def __init__(self, path):
        self.path = path

    def read_data(self) -> list[Record]:
        """
        复写读取JSON文件方法
        :return:
        """
        f = open(self.path, "r", encoding="UTF-8")
        record_list: list[Record] = []
        for line in f.readlines():
            data_dict = json.loads(line)
            record_list.append(
                Record(
                    data_dict["date"],
                    data_dict["order_id"],
                    int(data_dict["money"]),
                    data_dict["province"]
                )
            )
        f.close()
        return record_list


# 测试代码
if __name__ == '__main__':
    r = TextFileReader("D:\\IOText\\DataDoing\\2011年1月销售数据.txt")
    j = JsonFileReader("D:\\IOText\\DataDoing\\2011年2月销售数据JSON.txt")
    list1 = r.read_data()
    print(list1[0])
    list2 = j.read_data()

    # for r in list1:
    #     print(r)

    # for j in list2:
    #     print(j)
3.main.py
"""
    主业务逻辑代码
"""
from file_define import FileReader, TextFileReader, JsonFileReader
from data_define import Record
from pyecharts.charts import Bar
from pyecharts.options import *
from pyecharts.globals import ThemeType

text_file_reader = TextFileReader("D:\\IOText\\DataDoing\\2011年1月销售数据.txt")
json_file_reader = JsonFileReader("D:\\IOText\\DataDoing\\2011年2月销售数据JSON.txt")

month_1_data: list[Record] = text_file_reader.read_data()
month_2_data: list[Record] = json_file_reader.read_data()

# 将两个月份的数据合并
all_data: list[Record] = month_1_data + month_2_data
# 开始进行数据计算
data_dict = {}
for record in all_data:
    if record.date in data_dict.keys():
        # 累加
        data_dict[record.date] += record.money
    else:
        # 创建
        data_dict[record.date] = record.money

# 可视化
bar = Bar(
    init_opts=InitOpts(theme=ThemeType.LIGHT)
)
# 添加x轴的数据
bar.add_xaxis(list(data_dict.keys()))
# 添加Y轴的数据
bar.add_yaxis("销售额", list(data_dict.values()), label_opts=LabelOpts(is_show=False))

bar.set_global_opts(
    title_opts=TitleOpts(title="每日销售额")
)
bar.render("每日销售额.html")

结语

学这么点内容,学习了一天,确实是不用着急,不要慌张,脚踏实地的一步一步的走就行啦

今天就到这里

拜拜ヾ( ̄▽ ̄)Bye~Bye~

你可能感兴趣的:(Python之路,python,面向对象)