Python进阶02-面向对象高级

embedded/2024/10/16 2:29:05/

零、文章目录

Python进阶02-面向对象高级

1、面向对象的三大特性

  • 面向对象的三大特性:封装、继承、多态
    • ① 封装:将属性和方法书写到类的里面的操作即为封装,封装可以为属性和方法添加私有权限。
    • ② 继承:子类默认继承父类的所有属性和方法,与此同时子类也可以重写父类属性和方法。
    • ③ 多态:多态是同一类事物具有的多种形态。不同的对象调用同一个接口(方法),表现出不同的状态,称为多态。

2、Python中的封装

(1)私有属性和私有方法
  • 在Python中,可以为实例属性和方法设置私有权限,即设置某个实例属性或实例方法不继承给子类
  • 设置私有属性和私有方法的方式非常简单:在属性名和方法名 前面 加上两个下划线 “__” 即可。
(2)设置私有属性
  • 私有属性不能在类的外部被直接访问。
  • 类中的私有属性不能被其子类继承。
'''
在Python代码中,我们在定义类的时候,只需要在定义属性时为其添加两个__,其就变成了私有属性!
class 类名(object):# 定义属性def __init__(self, name, age):self.name = 公有属性self.__age = 私有属性# 定义方法
'''
class Girl(object):# 定义属性def __init__(self, name):self.name = nameself.__age = 18g1 = Girl('小美')
print(g1.name)
print(g1.__age)# 报错,提示Girl对象没有__age属性
(3)获取与设置私有属性值
  • 在Python中,一般定义函数名’ get_xx ‘用来获取私有属性,定义’ set_xx '用来修改私有属性值。
'''
私有属性有何意义?
答:明确区分内外,控制外部对内部数据访问,起到保护数据以及过滤异常数据目的!
'''
class Girl(object):# 定义属性def __init__(self, name):self.name = nameself.__age = 18# 给__age私有属性添加一个访问"接口"def get_age(self):# 获取属性之前# 1、需要验证用户是否具有查看属性的权限# 2、如果有,则返回私有属性;如果没有权限,则直接禁止访问return self.__age# 给__age私有属性添加一个设置"接口"def set_age(self, age):# 在设置属性之前# 1、首先对age进行判断,判断是否是一个合理数据if not isinstance(age, int):print('很抱歉,您设置的age参数非整数类型')returnif age <= 0 or age > 250:print('很抱歉,您设置的age参数范围不合理')return# 2、如果是合理的数据,则允许设置;反之,则直接禁止self.__age = ageg1 = Girl('小美')
print(g1.name)
g1.set_age(20)
print(g1.get_age())
(4)设置私有方法
  • 私有方法的定义方式与私有属性基本一致,在方法名的前面添加两个下划线__方法名()
'''
如何定义私有方法?
class 类名():# 定义属性# 定义方法def __方法名称(self):私有方法
私有方法有何意义呢?答:私有方法并不是用于保护数据,简化程序的复杂度。
银行 => ATM取款 => ① 插卡 ② 用户验证 ③ 输入取款金额 ④ 取款 ⑤ 打印账单
'''
class ATM(object):# 1、定义一个插卡方法def __card(self):print('插卡')# 2、定义一个用户验证def __auth(self):print('用户验证')# 3、定义一个方法def __input(self):print('输入取款金额')# 4、取款def __take_money(self):print('取款')# 5、打印账单def __print_bill(self):print('打印账单')# 定义一个统一的"接口",专门用于实现取款操作def withdraw(self):self.__card()self.__auth()self.__input()self.__take_money()self.__print_bill()# 实例化ATM类,进行取款操作
atm = ATM()
atm.withdraw()
(5)封装的意义
  • 封装私有属性意义:明确的区分内外,控制外部对对隐藏的属性的操作行为

  • 封装私有方法意义:降低程序的复杂度

3、Python中的继承

(1)继承是什么
  • 生活中的继承,一般指的是子女继承父辈的财产。
  • 类是用来描述现实世界中同一组事务的共有特性的抽象模型,但是类也有上下级和范围之分,比如:生物 => 动物 => 哺乳动物 => 灵长型动物 => 人类 => 黄种人
  • 从哲学上说,就是共性与个性之间的关系,比如:白马和马!所以,我们在OOP代码中,也一样要体现出类与类之间的共性与个性关系,这里就需要通过类的继承来体现。简单来说,如果一个类A使用了另一个类B的成员(属性和方法),我们就可以说A类继承了B类,同时这也体现了OOP中代码重用的特性!
(2)继承的基本语法
  • 假设A类要继承B类中的所有属性和方法(私有属性和私有方法除外)
  • 在Python中,所有类默认继承object类,object类是顶级类或基类;其他子类叫做派生类。
python">class B(object):passclass A(B):passa = A()
a.B中的所有公共属性
a.B中的所有公共方法
  • 案例:人类和学生
'''
在Python代码中,为了实现代码重用 => 体现共性与个性的问题,可以通过继承来实现重用关系
如果A类继承了B中的所有公共属性和公共方法,基本语法:
class B(object):# 公共属性# 公共方法class A(B):A这个类实例化的对象会自动拥有B类的中所有公共属性和公共方法
'''
class Person(object):# 定义公共方法def eat(self):print('i can eat food!')# 定义公共方法def run(self):print('i can run!')class Student(Person):pass# 实例化对象
stu = Student()
stu.eat()
stu.run()
(3)几个相关概念
  • 继承:一个类从另一个已有的类获得其成员的相关特性,就叫作继承!

  • 派生:从一个已有的类产生一个新的类,称为派生!

  • 很显然,继承和派生其实就是从不同的方向来描述的相同的概念而已,本质上是一样的!

  • 父类:也叫作基类,就是指已有被继承的类!

  • 子类:也叫作派生类或扩展类

  • 扩展:在子类中增加一些自己特有的特性,就叫作扩展,没有扩展,继承也就没有意义了!

  • 单继承:一个类只能继承自一个其他的类,不能继承多个类,单继承也是大多数面向对象语言的特性!

  • 多继承:一个类同时继承了多个父类, (C++、Python等语言都支持多继承)

(4)单继承
  • 单继承:一个类只能继承自一个其他的类,不能继承多个类。这个类会有具有父类的属性和方法。
class Animal(object):def eat(self):print('吃...')def sleep(self):print('睡...')def call(self):print('叫...')class Dog(Animal):passclass Cat(Animal):pass
(5)单继承传递性
  • 在Python继承中,如A类继承了B类,B类又继承了C类。则根据继承的传递性,则A类也会自动继承C类中所有属性和方法(公共)
python">'''
多层继承也是单继承的一种延伸,简单来说:A => B => C,所以A自动继承了C中的所有公共属性和公共方法
'''
class C(object):def func1(self):print('C类中的func1方法')class B(C):def func2(self):print('B类中的func2方法')class A(B):pass# 实例化A类产生一个a对象
a = A()
a.func2()
a.func1()
(6)多继承
  • 多继承:一个类同时继承了多个父类,并且同时具有所有父类的属性和方法
python">'''
Python语言是少数支持多继承的一门编程语言,所谓的多继承就是允许一个类同时继承自多个类的特性。
class C(object):pass
class B(object):passclass A(B, C):pass
'''
# 汽油车类
class GasolineCar(object):def run_with_gasoline(self):print('i can run with gasoline!')# 电动车类
class ElectricCar(object):def run_with_electric(self):print('i can run with electric!')# 混动汽车
class HybridCar(ElectricCar, GasolineCar):passbenz = HybridCar()
benz.run_with_gasoline()
benz.run_with_electric()
(7)多继承的覆盖问题
  • 在 Python 中,类的定义可以包括一个基类列表,这些基类将按照它们在类定义中出现的顺序被继承。如果多个基类又相同的属性和方法,会继承排在前面基类的属性和方法
python"># 汽油车类
class GasolineCar(object):def run(self):print('i can run with gasoline!')# 电动车类
class ElectricCar(object):def run(self):print('i can run with electric!')# 混动汽车
class HybridCar(ElectricCar, GasolineCar):pass# 到底HybridCar优先继承哪个类中的所有公共属性和公共方法呢?
benz = HybridCar()
benz.run()  # i can run with electric!
(8)子类重写父类属性方法
  • 重写也叫作覆盖,就是当子类成员与父类成员名字相同的时候,从父类继承下来的成员会重新定义!
  • 此时,通过子类实例化出来的对象访问相关成员的时候,真正起作用的是子类中定义的成员!
  • 上面单继承例子中 Animal 的子类 Cat和Dog 继承了父类的属性和方法,但是我们狗类Dog 有自己的叫声’汪汪叫’,猫类 Cat 有自己的叫声 ‘喵喵叫’ ,这时我们需要对父类的 call() 方法进行重构。如下:
python">class Animal(object):# 定义属性name和agedef __init__(self, name, age):self.name = nameself.age = agedef eat(self):print('吃...')def sleep(self):print('睡...')def call(self):print('叫...')class Dog(Animal):def call(self):print('汪汪叫...')class Cat(Animal):def call(self):print('喵喵叫...')# Dog实例对象
dog = Dog('汪汪',10)
dog.eat()
dog.call()# Cat实例对象
cat = Cat('喵喵',8)
cat.eat()
cat.call()
  • 思考一个问题:此时父类中的call方法还在不在?

    • 答:还在,只不过是在其子类中找不到了。类方法的调用顺序,当我们在子类中重构父类的方法后,Cat子类的实例先会在自己的类 Cat 中查找该方法,当找不到该方法时才会去父类 Animal 中查找对应的方法。
  • 输出结果

...
汪汪叫...
吃...
喵喵叫...
(9)子类调用父类属性和方法
  • super():调用父类属性或方法
  • 完整写法:super(当前类名, self).属性或方法()
python">'''
在Python代码中,如果在继承重写的基础上,我们还需要强制调用父类中的属性或方法,可以考虑使用super()
基本语法:
super().属性
super().方法()
'''
class Animal():def __init__(self, name, age):self.name = nameself.age = agedef eat(self):print('吃...')def sleep(self):print('睡...')def call(self):print('叫...')class Dog(Animal):def __init__(self, name, age, sex):super().__init__(name, age)self.sex = sexdef __str__(self):return f'{self.name},今年{self.age}岁了,我会汪汪叫...'class Cat(Animal):def __init__(self, name, age, sex):super().__init__(name, age)self.sex = sexdef __str__(self):return f'{self.name},今年{self.age}岁了,我会喵喵叫...'dog = Dog('阿呆',18,'男')
dog.eat()
print(dog)cat = Cat('阿瓜',20,'女')
cat.eat()
print(cat)
  • 输出
...
阿呆,今年18岁了,我会汪汪叫...
吃...
阿瓜,今年20岁了,我会喵喵叫...

4、Python中的多态

(1)多态是什么
  • 多态指的是一类事物有多种形态。
  • 定义:多态是一种使用对象的方式,子类重写父类方法,调用不同子类对象的相同父类方法,可以产生不同的执行结果① 多态依赖继承② 子类方法必须要重写父类方法
  • 好处:调用灵活,有了多态,更容易编写出通用的代码,做出通用的编程,以适应需求的不断变化!
(2)多态的实现步骤
  • 定义父类,并提供公共方法
  • 定义子类,并重写父类公共方法
  • 传递子类对象给调用者,可以看到不同子类执行效果不同
python">'''
什么是多态?简单来说就是一种事物,随着传入对象的不同,可以返回多种形态。
① 多态依赖继承
② 子类还需要重写父类中的方法
'''
class Fruit(object):# 定义一个公共方法def makejuice(self):passclass Apple(Fruit):# 重写父类中的公共方法def makejuice(self):print('i can make apple juice!')class Orange(Fruit):# 重写父类中的公共方法def makejuice(self):print('i can make orange juice!')class Banana(Fruit):# 重写父类中的公共方法def makejuice(self):print('i can make banana juice!')# 定义一个公共接口 => 多态特性 => 要求传入一个对象作为参数
def service(obj):obj.makejuice()apple = Apple()
orange = Orange()
banana = Banana()service(apple)
service(orange)
service(banana)
(3)多态实现
  • 类具有继承关系,并且子类类型可以向上转型看做父类类型,如果我们从 Animal 派生出 Cat和 Dog,并都写了一个 call() 方法,如下示例:
python">'''
多态:同一个方法,随着传入对象的不同,返回不同的结果(多态)
① 有继承
② 重写父类中的公共方法
'''
class Dog():# 定义一个公共方法def work(self):passclass ArmyDog(Dog):# 重写父类中的work方法def work(self):print('追击敌人...')class DrugDog(Dog):# 重写父类中的work方法def work(self):print('追查毒品...')class Person(object):# 定义一个多态接口 => 函数、方法def work_with_dog(self, obj):obj.work()# 实例化Person类生成一个对象
police = Person()
police.work_with_dog(ArmyDog())

5、面向对象的其他特性

(1)类属性
  • 类属性就是类中定义的属性,它被该类的所有实例对象所共有。通常用来记录与这类相关的特征,类属性不会用于记录 具体对象的特征。
  • 案例:定义一个工具类, 每件工具都有自己的名称,需求:知道使用这个类,创建了多少个工具对象?
python">'''
在面向对象中,属性一般可以分为两种形式:① 对象属性(成员属性) ② 类属性
在Python代码中,一切皆对象。类也是一种特殊的对象,所以我们也可以为类来创建一个属性 => 类属性
既然类也可以拥有属性,类属性与对象属性有何区别呢?
对象属性(成员属性)是由这个类产生的对象所拥有的属性。
类属性:并不是由实例化对象拥有的,而是这个类所拥有的属性,可以理解为是所有对象共同拥有的属性,但是其不属于某一个对象。
应用场景:比如我们想知道由这个类到底生成了多少个对象,如何定义一个属性来进行统计呢?
强调一下:类属性并不是某个对象所拥有的,而是所有对象所共同组成的一个特征,我们就可以把其定义为类属性
定义类属性:
class 类名称():属性 = 属性值类属性如何访问呢?既可以在类的里面也可以在类的外面
类名.类属性(推荐)
对象.类属性(也可以,但是不推荐)
'''
class Person(object):# 定义一个类属性:用于统计到底由这个类产生了多少个对象count = 0# 通过__init__魔术方法定义的都是对象属性def __init__(self, name, age):self.name = nameself.age = age# 对类属性进行累加计数Person.count += 1p1 = Person('小明', 23)
p2 = Person('小美', 18)print(f'由Person类一共创建了{Person.count}个对象!')
(2)类方法
  • 类方法就是针对类定义的方法,在类方法中可以直接访问类属性或者调用其他类方法。
  • 基本语法:
python">@classmethod
def 类方法名称(cls):pass
  • 类方法需要用修饰器" @classmethod “来标识,告诉解释器这是一个类方法类方法的第一个参数应该是” cls "

    • ① 有哪一个类调用的方法,方法内的" cls "就是哪一个类的引用
    • ② 这个参数和示例方法的第一个参数是"self"类似
    • ③ 提示使用其他名称也可以,不过习惯使用" cls " 通过类名.调用类方法,调用方法时,不需要传递" cls "参数
  • 在方法内部

    • ① 可以通过"cls."访问类的属性
    • ② 也可以通过 “cls.” 调用其他的类方法
  • 案例:

    • 定义一个工具类
    • 每件工具都有自己的名称
    • 需求 :在类封装一个" getCount"的类方法,输出当前这个类创建的对象个数
python">'''
类方法:在Python代码中,类属性与对象属性一样,都强调封装特性,不建议直接在类的外部直接对类属性进行操作。
如果想在类的外部获取类属性的信息,必须使用类方法来实现。
类方法 => 基本语法:
class 类名称():类属性 = 属性值@classmethod => 装饰器def 类方法(cls):因为这个方法属于类方法,所以cls代表这个类本身调用类方法:
类名称.类方法()  =>  强烈推荐使用第一种
对象.类方法()
案例:统计Tool工具类到底生成了多少个工具类对象
'''
class Tool(object):# 定义一个类属性count = 0# 定义对象属性def __init__(self, name):self.name = name# 对类属性进行操作,进行+1Tool.count += 1# 定义一个类方法 => 专门用于操作类属性@classmethoddef getCount(cls):return f'您一共实例化了{cls.count}个对象!'# 实例化对象
t1 = Tool('斧头')
t2 = Tool('榔头')
t3 = Tool('锤子')# 调用类方法,输出一共创建了多少个对象
print(Tool.getCount())
(3)静态方法
  • 在开发时,如果需要在类中封装一个方法,这个方法:

    • ① 既 不需要访问实例属性或者调用实例方法
    • ② 也 不需要访问类属性或者调用类方法这个时候
    • ③ 可以把这个方法封装成一个静态方法
  • 基本语法:

python">@staticmethod
def 静态方法名():    pass
  • 静态方法需要用修饰器 “@staticmethod” 来标识,告诉解释器这是一个静态方法。通过类名.调用 静态方法
python">class Game:@staticmethoddef menu():print('------')print('开始[1]')print('暂停[2]')print('退出[3]') Game.menu()
  • 案例:打印学生管理系统菜单
python">'''
什么样的方法可以封装为静态方法?
答:既不需要调用自身属性(对象属性、类属性),也不需要调用自身方法(对象方法、类方法),本身就是一个独立功能。
定义:
class 类名称():@staticmethoddef 静态方法():由于静态方法本身就是一个独立功能,既不需要调用自身属性也不需要调用自身方法,所以其没有参数
'''
class StudentManager(object):# 打印系统功能菜单@staticmethoddef menu():print('-' * 40)print('欢迎使用学生管理系统V1.0')print('【1】添加学员信息')print('【2】删除学员信息')print('【3】修改学员信息')print('【4】查询学员信息')print('-' * 40)# 调用静态方法 => 类名.静态方法() 或者 对象.静态方法()
StudentManager.menu()

6、综合案例-学生管理系统

(1)需求分析
  • ① 系统要求:学员数据存储在文件中

  • ② 系统功能:

    • 添加学员
    • 删除学员
    • 修改学员信息
    • 查询学员信息
    • 显示所有学员信息
    • 保存学员信息
    • 退出系统
(2)对象分析
  • 学员对象(姓名、年龄、电话) => 自身属性,打印学生时,还需要输出学生信息 => _str_()

  • 学生管理系统对象(可以实现对学生进行增、删、改、查)

  • 注意事项

    • ① 为了方便维护代码,一般一个角色一个程序文件

    • ② 项目要有主程序入口,习惯为main.py

(3)项目创建
  • 创建类文件 => studentManager.py

  • 创建项目入口文件 => main.py

image-20210319145119665

(4)代码实现
  • student.py类文件实现
python"># 定义一个Student类
class Student():# 定义魔术方法,用于初始化属性信息def __init__(self, name, age, mobile):self.name = nameself.age = ageself.mobile = mobile# 定义魔术方法,用于打印输出学员信息def __str__(self):return f'{self.name}, {self.age}, {self.mobile}'
  • studentManager.py类文件实现
python">from student import Studentclass StudentManager(object):# 定义一个__init__魔术方法,用于初始化数据def __init__(self):# 初始化一个student_list属性,用于将来保存所有学员对象信息self.student_list = []# 定义load_student()方法def load_student(self):passdef add_student(self):# 提示用户输入学员信息name = input('请输入学员的姓名:')age = int(input('请输入学员的年龄:'))mobile = input('请输入学员的电话:')# 使用Student类实例化对象student = Student(name, age, mobile)# 调用student_list属性,追加student对象信息self.student_list.append(student)print('学员信息已添加成功')def del_student(self):# 提示用户输入要删除的学员姓名name = input('请输入要删除的学员姓名:')# 对student_list属性(本质列表)进行遍历for i in self.student_list:if i.name == name:# 找到了要删除的学员,删除self.student_list.remove(i)print(f'学员{name}信息删除成功')breakelse:print('您要删除的学员不存在...')def mod_student(self):# 提示用户输入要修改的学员姓名name = input('请输入要修改的学员姓名:')# 对student_list属性进行遍历,判断要修改的学员姓名是否存在for i in self.student_list:if i.name == name:i.name = input('请输入修改后的学员姓名:')i.age = int(input('请输入修改后的学员年龄:'))i.mobile = input('请输入修改后的学员电话:')print(f'学员信息修改成功,修改后信息如下 => 学员姓名:{i.name},学员年龄:{i.age},学员电话:{i.mobile}')breakelse:print('您要修改的学员信息不存在...')def show_student(self):# 提示用户输入要查询的学员姓名name = input('请输入要查询的学员姓名:')# 对student_list属性进行遍历for i in self.student_list:if i.name == name:print(i)breakelse:print('您要查找的学员信息不存在...')def show_all(self):# 直接对列表进行遍历for i in self.student_list:print(i)# 把self.student_list转换为字符串保存到student.data文件中def save_student(self):# 打开文件f = open('student.data', 'w', encoding='utf-8')# 把列表中的对象转换为字典new_list = [i.__dict__ for i in self.student_list]# 文件读写(写入)f.write(str(new_list))# 关闭文件f.close()# 提示用户数据已经保存成功了print('学员信息保存成功')# 定义load_student()方法def load_student(self):# 捕获异常try:f = open('student.data', 'r', encoding='utf-8')except:f = open('student.data', 'w', encoding='utf-8')else:# 如果文件存在,没有异常,则执行else语句content = f.read()if not content:content = '[]'# 把字符串转换为原数据类型[{}, {}, {}]data = eval(content)# 把列表中的所有字典 => 转换为对象self.student_list = [Student(i['name'], i['age'], i['mobile']) for i in data]finally:f.close()# 定义静态show_help()方法@staticmethoddef show_help():print('-' * 40)print('通讯录管理系统V2.0')print('1.添加学员信息')print('2.删除学员信息')print('3.修改学员信息')print('4.查询学员信息')print('5.遍历所有学员信息')print('6.保存学员信息')print('7.退出系统')print('-' * 40)# 定义一个run()方法,专门用于实现对管理系统中各个功能调用def run(self):# 1、调用一个学员加载方法,用于加载文件中的所有学员信息,加载完成后,把得到的所有学员信息保存在student_list属性中self.load_student()# 2、显示帮助信息,提示用户输入要实现的功能编号while True:# 显示帮助信息self.show_help()# 提示用户输入要操作功能编号user_num = int(input('请输入要操作功能的编号:'))if user_num == 1:self.add_student()elif user_num == 2:self.del_student()elif user_num == 3:self.mod_student()elif user_num == 4:self.show_student()elif user_num == 5:self.show_all()elif user_num == 6:self.save_student()elif user_num == 7:print('感谢您使用通讯录管理系统V2.0,欢迎下次使用!')breakelse:print('信息输入错误,请重新输入...')
  • main.py入口文件实现
python"># 从studentManager模块中导入StudentManager类功能
from studentManager import StudentManager# 定义入口代码
if __name__ == '__main__':student_manager = StudentManager()student_manager.run()

http://www.ppmy.cn/embedded/102709.html

相关文章

全场景——(五)Modbus 协议细节

文章目录 一、Modbus协议概述二、Modbus寄存器&#xff08;存储区&#xff09;2.1 存储区类型2.2 协议地址模型 三、Modbus常用功能码四、Modbus协议类型五、Modbus报文帧5.1 Modbus ASCII 模式5.2 Modbus RTU 模式5.3 串行报文帧总结&#xff1a; 六、Modbus 差错校验6.1 LRC校…

代码零风险:深信达SDC沙盒如何革新源代码防泄漏

当前信息技术迅速发展的环境下&#xff0c;企业对源代码安全的高度重视。源代码作为企业最宝贵的资产之一&#xff0c;其安全性直接关系到企业的竞争力和市场地位。源代码泄露不仅可能导致企业技术优势的丧失&#xff0c;还可能引发严重的经济损失和法律风险。因此&#xff0c;…

常用git命令

目录 1、常用git命令 2、git merge 和 git rebase 的区别 3、获取远程仓库数据命令 git fetch 和 git pull的区别 4、git reset 和 git revert 的区别 1、常用git命令 git init //初始化本地仓库 git status //查看文件状态git diff //显示工作目录中当前文件…

Neo4j - CQL简介

简述 CQL 代表密码查询语言。就像 Oracle 数据库有查询语言 SQL&#xff0c;Neo4j 有 CQL 作为查询语言。 Neo4j CQL 是 Neo4j 图形数据库的查询语言。是一种声明性模式匹配语言。遵循类似 SQL 的语法。语法非常简单并且是人类可读的格式。 像 Oracle SQL Neo4j CQL 具有执…

深入了解搜索引擎蜘蛛:从定义到最新技术应用

撰写一篇关于搜索引擎蜘蛛的详细文章&#xff0c;需涵盖从基础概念到未来趋势的多个方面。以下是根据您提供的大纲撰写的长篇文章&#xff0c;适合用于了解搜索引擎蜘蛛的重要性及其在现代互联网中的作用。 1. 引言 在互联网的浩瀚世界中&#xff0c;搜索引擎就像是庞大的图书…

71 OSPF多区域实验(华三)

HCIE认证体系 一 网络结构图(OSPFv2) 这个网络结构图为基准后期会常用到主要是(OSPF BGP ISIS OSPFV3 BGP4+ ISISV6) 二 需求 利用OSPF实现全网互通

JAVA之MAC详解以及子线程MDC传递

MDC简介 MDC(Mapped Diagnostic Context)是用于分布式系统中跟踪和诊断日志的重要概念。是一个在Java项目中用于日志跟踪的工具&#xff0c;它允许你在多线程环境下关联和传递特定的上下文信息。 MDC是一个线程本地的、可维护的、可传递的上下文环境。在Java中&#xff0c;MDC…

Spring-MVC

1.1 mvc思想&#xff0c;前端控制器&#xff0c;springmvc概述&#xff0c;配置版spring mvc程序 MVC思想 MVC概念&#xff1a;模型(Model)、视图(View)、控制器(Controller)的简写&#xff0c;是一种软件设计规范&#xff0c;将业务逻辑、数据、显示分离的方式来组织代码 MVC…