面向对象(基础)特征一:封装性(encapsulation)

news2024/9/21 22:37:18

文章目录

  • 一、介绍
    • (1)封装性
    • (2)权限修饰符
  • 二、案例
    • (1)案例1
  • 三、练习
    • (1)练习1
    • (2)练习2
    • (3)练习3
    • (4)练习4

面向对象特征之一:封装性

一、介绍

(1)封装性

  1. 为什么需要封装性?
  • 我要用洗衣机,只需要按一下开关和洗涤模式就可以了。有必要了解洗衣机内部的结构吗?有必要碰电动机吗?
  • 我要开车,我不需要懂离合、油门、制动等原理和维修也可以驾驶。

随着我们系统越来越复杂,类会越来越多,那么类之间的访问边界必须把握好,面向对象的开发原则要 遵循“ 高内聚、低耦合 ”。 高内聚、低耦合是软件工程中的概念,也是UNIX 操作系统设计的经典原则。

内聚,指一个模块内各个元素彼此结合的紧密程度;耦合指一个软件结构内不同模块之间互连程度的度量。内聚意味着重用和独立,耦合意味着多米诺效应牵一发动全身。

内聚:把特定的内容封装到不同的类里面,把类里面特定的功能封装到不同的方法当中。

耦合:相互之间要调用的时候,只对外暴露需要用的,不需要使用的细节就不对外暴露了。

理论上:

  • 高内聚类的内部数据操作细节自己完成,不允许外部干涉;
  • 低耦合仅暴露少量的方法给外部使用,尽量方便外部调用。

所谓封装,就是把客观事物封装成抽象概念的类,并且类可以把自己的数据和方法只向可信的类或者对 象开放,向没必要开放的类或者对象隐藏信息。

通俗的说:把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。

(2)权限修饰符

  1. 如何实现数据封装?
    2.1 权限修饰符
    Java规定了4种权限修饰,分别是:private缺省protectedpublic
    image.png
    image.png
    2.2 作用
    我们可以使用4种权限修饰来修饰类及类的内部成员。当这些成员被调用时,体现可见性的大小

:只能使用public缺省修饰
类的内部成员:可以使用4种权限修饰进行修饰。

比如,这里的类用的是“缺省”:

class Animal{   //动物

}

这个类用的是“public”:

public class AnimalTest {
    public static void main(String[] args) {
        Animal animal1=new Animal();
    }
}

但是使用“private”就不行,比如:
image.png

private修饰的是类的内部文件,此时AA就是一个类,它对自己可见,而且外边用不了,没有什么作用。

protected也一样,修饰的属性让子类的类能够看到,主要指的是成员,类自己加没有什么意义。

目前写的类是并列关系,都叫外部类,比如下面的AnimalTest类和Animal类:

public class AnimalTest {
    public static void main(String[] args) {
        Animal animal1=new Animal();
    }
}
class Animal{   //动物

}

若在Animal类里面再写一个类,这个类就是内部类,内部类可以被四种权限修饰。(后边再说,不着急)

2.3 开发中4种权限使用频率的情况:

比较高:public、private

比较低:缺省、protected

  1. 封装性的体现

场景1:私有化(private)类的属性,提供公共(public)的get和set方法,对此属性进行获取或修改

场景2:将类中不需要对外暴露的方法,设置为private.

场景3:单例模式中构造器private的了,避免在类的外部创建实例。(放到static关键字后讲)

二、案例

(1)案例1

看下面的代码:

package yuyi.exer01.exe01;

/**
 * ClassName: AnimalTest
 * Package: yuyi.exer01.exe01
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/10/22 0022 13:29
 */
public class AnimalTest {
    public static void main(String[] args) {
        Animal animal1=new Animal();
        animal1.name="金蟾";
        animal1.legs=4;

        System.out.println("name="+animal1.name+",legs="+animal1.legs);
        animal1.eat();
    }
}
class Animal{   //动物
    //属性
    String name;    //名字
    int legs;   //腿的个数

    //方法
    public void eat(){
        System.out.println("动物觅食");
    }
}

执行结果
image.png

⚡注意

不能直接在Animal类中写这种语句:System.out.println("动物");

类里面只能有属性和方法,而上面的语句既不算属性,也不算方法,只是一个执行语句,它只能放在方法里面。

class Animal{   //动物
    //属性
    String name;    //名字
    int legs;   //腿的个数

	System.out.println("动物");	//不能这样写
    
    //方法
    public void eat(){
        System.out.println("动物觅食");
    }
}

现在想给legs设置一个判断逻辑,只有正偶数的值才能被输出。

在Animal类中直接判断是不对的,如下:
image.png

但是属性可以在方法里面调用,所以我们可以在Animal类中写一个方法,在方法里面对legs进行逻辑判断。

//设置legs属性值
public void setLegs(int l){
        if(l>=0&&l%2==0){   //腿的个数为正偶数
            legs=l;
        }else{
            System.out.println("输入数据非法");
        }
}

在给属性赋值的时候,不需要再直接调用属性了,可以通过刚才的setLegs方法来调用,如下:

 //animal1.legs=4;
animal1.setLegs(4); //若输入的值是正偶数,就能正确输出结果

完整代码:

public class AnimalTest {
    public static void main(String[] args) {
        Animal animal1=new Animal();
        animal1.name="金蟾";
        //animal1.legs=4;
        animal1.setLegs(4); //若输入的值是正偶数,就能正确输出结果

        System.out.println("name="+animal1.name+",legs="+animal1.legs);
        animal1.eat();
    }
}
class Animal{   //动物
    //属性
    String name;    //名字
    int legs;   //腿的个数

    /*不能直接在这里判断
    if(legs>=0){

    }*/

    //方法
    public void eat(){
        System.out.println("动物觅食");
    }
    public void setLegs(int l){
        if(l>=0&&l%2==0){   //腿的个数为正偶数
            legs=l;
        }else{
            System.out.println("输入数据非法");
        }
    }
}

输出结果:
image.png


但是现在我们还是可以直接来调用属性,现在只不过是多了一种方式判断逻辑而已。

那么如何让它彻底不能通过调用属性来给leg赋值?

可以在定义属性的时候,在前面加一个权限修饰符private:(表示将这个属性私有化了,就是将它隐藏起来了,仅限在类的内部看到)

 private int legs;

此时外界(出了Animal类)就看不到legs属性了。

所以直接调用legs属性就不被允许了。如下:
image.png

同时这里的legs也不能用了:
image.png

那怎么办呢?

可以在Animal类中再写一个方法:

//获取legs属性值
public int getLegs(){
        return legs;
}

这个方法的权限是public,使用范围还是很大的。

现在就可以调用了:

System.out.println("name="+animal1.name+",legs="+animal1.getLegs());

此时编译器看到的就是这个方法的返回值类型(int类型的变量),所以就可以使用了。


整体代码:

package yuyi.exer01.exe01;

/**
 * ClassName: AnimalTest
 * Package: yuyi.exer01.exe01
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/10/22 0022 13:29
 */
public class AnimalTest {
    public static void main(String[] args) {
        Animal animal1=new Animal();
        animal1.name="金蟾";
        
        //因为legs声明为private,是私有的,出了Animal类之外就不能调用了
        //animal1.legs=4;

        //只能通过setLegs(),间接对legs属性进行赋值
        animal1.setLegs(4); //若输入的值是正偶数,就能正确输出结果

        //System.out.println("name="+animal1.name+",legs="+animal1.legs);
        System.out.println("name="+animal1.name+",legs="+animal1.getLegs());
        
        animal1.eat();
    }
}
class Animal{   //动物
    //属性
    String name;    //名字
    private int legs;   //腿的个数

    /*不能直接在这里判断
    if(legs>=0){

    }*/

    //方法
    public void eat(){
        System.out.println("动物觅食");
    }

    //设置legs属性值
    public void setLegs(int l){
        if(l>=0&&l%2==0){   //腿的个数为正偶数
            legs=l;
        }else{
            System.out.println("输入数据非法");
        }
    }

    //获取legs属性值
    public int getLegs(){
        return legs;
    }
}

输出结果:
image.png

通过这个例子可以看到,为什么需要将一些必要的结构隐藏起来,因为不希望外边的用户可以随意的调用它,就需要将它私有化。如果外边想用,那就提供相应的方法,在方法里面对私有化的属性进行其他的设置。

权限修饰符的使用,就是封装性的体现。


👻总结

在上述案例中,我们给Animal的对象的legs属性赋值。在实际的常识中,我们知道legs不能赋值为负数的。但是如果
直接调用属性legs,是不能加入判断逻辑的。

那怎么办呢?

将legs属性私有化(private),禁止在Animal类的外部直接调用此属性。

提供给legs属性赋值的setLegs()方法,在此方法中加入legs赋值的判断逻辑if(legs >= 0 && legs % 2 ==0)
将此方法暴露出去,使得在Animal类的外部调用此方法,对legs属性赋值。

提供给legs属性获取的getLegs()方法,此方法对外暴露。使得在Animal类的外部还可以调用此属性的值。

若是在类的外部不想让用户获取legs的值,可以不写getLegs()方法,或者将它的权限修饰符设置为private,如下:

private int getLegs(){
        return legs;
}

此时getLegs方法对外也不暴露了,在Animal方法外面也就不能调用它了:
image.png

三、练习

(1)练习1

🌋题目描述

创建程序,在其中定义两个类:Person和PersonTest类。定义如下:

用setAge()设置人的合法年龄(0~130),用getAge()返回人的年龄。

在PersonTest类中实例化Person类的对象b,调用setAge()和getAge()方法,体会Java的封装性。

🤺代码

package yuyi.exer01.exe01;

/**
 * ClassName: Person
 * Package: yuyi.exer01.exe01
 * Description:
 *创建程序,在其中定义两个类:Person和PersonTest类。定义如下:
 * 用setAge()设置人的合法年龄(0~130),用getAge()返回人的年龄。
 * 在PersonTest类中实例化Person类的对象b,调用setAge()和getAge()方法,体会Java的封装性。
 *
 * @Author 雨翼轻尘
 * @Create 2023/10/22 0022 15:02
 */
public class Person {
    //属性
    private int age;    //不对外暴露

    //设置age属性
    public void setAge(int agenumber){
        if(agenumber>=0&&agenumber<=130){
            age=agenumber;
        }else{
            System.out.println("输入的年龄有误");
        }
    }

    //获取age属性
    public int getAge(){
        return age;
    }
}
class PersonTest{
    public static void main(String[] args) {
        //创建Person实例1
        Person b=new Person();

        //b.age=21;   //编译不通过
        b.setAge(22);   //赋值
        System.out.println(b.getAge()); //获取值

    }
}

⚡输出结果
image.png

👻注意

可以将这两个方法合并吗?如下:
image.png

现在两个功能合并在一起了,Age方法的耦合度更高,不建议这样来写!

比如之前已经有了一个Person对象,现在我只想看看是多少岁,如果是左边的两种方法,我就可以通过getAge看一下是多少岁。

但如果是右边的Age方法,此时我需要传进一个参数,然后又返回相同的数值,这就违背初衷了。

每一个方法就只单纯的完成一个功能,在实际需要的时候再去组合这些方法完成特定的操作即可。不要刻意合并!!!

(2)练习2

🌋题目描述

【自定义图书类】

设定属性包括:

书名bookName,

作者author,

价格price;

方法包括:

相应属性的get/set方法,

图书信息介绍等。

🤺代码

【book.java】

package yuyi.exer01.exe01;

/**
 * ClassName: book
 * Package: yuyi.exer01.exe01
 * Description:
 * 【自定义图书类】
 * 设定属性包括:
 * 书名bookName,
 * 作者author,
 * 价格price;
 * <p>
 * 方法包括:
 * 相应属性的get/set方法,
 * 图书信息介绍等。
 *
 * @Author 雨翼轻尘
 * @Create 2023/10/22 0022 15:39
 */
public class book {
    //属性
    private String bookName; //书名
    private String author;   //作者
    private double price;   //价格

    //方法

    //1.1设置书名
    public void setbookName(String b) {
        //...
        bookName = b;
    }

    //1.2获取书名
    public String getbookName() {
        return bookName;
    }

    //2.1设置作者
    public void setauthor(String a) {
        //...
        author = a;
    }

    //2.2获取作者
    public String getauthor() {
        return author;
    }

    //3.1设置价格
    public void setprice(double s) {
        //...
        price = s;
    }

    //3.2获取价格
    public double getprice() {
        return price;
    }

    //4.获取图书信息
    public String showInfo(){
        return "bookName:"+bookName+",author:"+author+",price:"+price;
    }
}

【bookTest.java】

package yuyi.exer01.exe01;

/**
 * ClassName: bookTest
 * Package: yuyi.exer01.exe01
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/10/22 0022 15:54
 */
public class bookTest {
    public static void main(String[] args) {
        book book1=new book();
        book1.setbookName("西游记");
        book1.setauthor("吴承恩");
        book1.setprice(30.46);
        System.out.println(book1.showInfo());
    }
}

可以使用Ctrl+Alt+L来调整代码格式(idea编译器)

此时我们看到的就是对外暴露的方法。

从后期来看,只要不是一些常量的话,一般都将属性私有化,对外都是暴露方法,通过方法对属性进行修改。

⚡输出结果
image.png

👻注意

每创建一个对象,类里面的属性就会各自持有一份。

现在“封装性”考虑的只是控制这些属性、方法在被访问的时候权限的大小而已。不会影响各个对象属性方法之间的关系,都会各自一份属性方法。

(3)练习3

🌋题目描述

【普通员工类】

(1)声明员工类Employee,

  • 包含属性:姓名、性别、年龄、电话,属性私有化
  • 提供get/set方法
  • 提供String getInfo()方法
    (2)在测试类的main中创建员工数组,并从键盘输入员工对象信息,最后遍历输出
    image.png

image.png

🤺代码

【Employee.java】

package yuyi.exer01.exe01;

/**
 * ClassName: Employee
 * Package: yuyi.exer01.exe01
 * Description:
 *【普通员工类】
 * (1)声明员工类Employee,
 * - 包含属性:姓名、性别、年龄、电话,属性私有化
 * - 提供get/set方法
 * - 提供String getInfo()方法
 * (2)在测试类的main中创建员工数组,并从键盘输入员工对象信息,最后遍历输出
 *
 * @Author 雨翼轻尘
 * @Create 2023/10/22 0022 16:06
 */
public class Employee {
    //属性
    private String name;
    private char sex;
    private int age;
    private String number;

    //方法
    //1.1设置姓名
    public void setname(String na){
        //...
        name=na;
    }
    //1.2获得姓名
    public String getname(){
        return name;
    }

    //2.1设置性别
    public void setsex(char se){
        //...
        sex=se;
    }
    //2.2获得性别
    public char getsex(){
        return sex;
    }

    //3.1设置年龄
    public void setage(int ag){
        //...
        age=ag;
    }
    //3.2获得年龄
    public int getage(){
        return age;
    }

    //4.1设置电话
    public void setnumber(String nu){
        //...
        number=nu;
    }
    //4.2获得电话
    public String getnumber(){
        return number;
    }

    //String getInfo()
    public String getInfo(){
        //return getname()+"\t"+getsex()+"\t"+getage()+"\t"+getnumber();
        return name+"\t"+sex+"\t"+age+"\t"+number;
    }
}

【EmployeeTest.java】

package yuyi.exer01.exe01;

import java.util.Scanner;

/**
 * ClassName: EmployeeTest
 * Package: yuyi.exer01.exe01
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/10/22 0022 18:03
 */
public class EmployeeTest {
    public static void main(String[] args) {
        //Employee ie=new Employee();

        //创建Employee[] 假设只有两个员工
        Scanner scan=new Scanner(System.in);

        Employee[] ie=new Employee[2];
        for (int i = 0; i < ie.length; i++) {
            ie[i]=new Employee();
            System.out.println("--------添加第"+(i+1)+"个员工--------");

            System.out.print("姓名:");
            String name=scan.next();

            System.out.print("性别:");
            char sex=scan.next().charAt(0);

            System.out.print("年龄:");
            int age=scan.nextInt();

            System.out.print("电话:");
            String number=scan.next();

            //给指定的employee对象的各属性赋值
            ie[i].setname(name);
            ie[i].setsex(sex);
            ie[i].setage(age);
            ie[i].setnumber(number);
        }

        //遍历员工列表
        System.out.println("---------------员工列表----------------");
        System.out.println("编号\t姓名\t性别\t年龄\t电话");
        for (int i = 0; i < ie.length; i++) {
            System.out.println((i+1)+"\t"+ie[i].getInfo());
        }
        System.out.println("---------------员工列表完成----------------");
    }
}

运行输入:
image.png

⚡输出结果
image.png

(4)练习4

🌋题目描述

测试权限修饰,先忽略protected。

🤸测试

在包test1里面创建一个类Order

ackage yuyi.exer01.exe01.test1;

public class Order {
    //声明不同权限的属性
    private int orderPrivate;
    int orderDefault;   //缺省权限
    public int orderPublic;

    //声明不同权限的方法
    private void methodPrivate(){

    }
    void methodDefault(){

    }
    public void methodPublic(){

    }

}

①在当前类里面

在类的某一个方法内,上面的都可以调用。方法里面可以调属性,调方法。(如下面的test方法)

package yuyi.exer01.exe01.test1;

public class Order {
    //声明不同权限的属性
    private int orderPrivate;
    int orderDefault;   //缺省权限
    public int orderPublic;

    //声明不同权限的方法
    private void methodPrivate(){

    }
    void methodDefault(){

    }
    public void methodPublic(){

    }

    public void test(){
        //调用属性
        orderPrivate=1;
        orderDefault=2;
        orderPublic=3;
        
        //调用方法
        methodPrivate();
        methodDefault();
        methodPublic();
    }

}

权限再小,在当前类中也能用。

当前包里面,当前类外面

在当前test1包里面新建一个类OrderTest,调用Order类里面的结构。

public class OrderTest {
    public static void main(String[] args) {
        //Order类的权限是public,在各个包里面都能看得见
        //因为是同一个包下,所以不用import
        Order order=new Order();
    }
}

即使现在的Order类是缺省修饰的,也可以被调用。因为缺省权限是本包内有效。如下:

class Order{
    //...
}

接下来测试调用属性和方法:

package yuyi.exer01.exe01.test1;

/**
 * ClassName: OrderTest
 * Package: yuyi.exer01.exe01.test1
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/10/22 0022 19:45
 */
public class OrderTest {
    public static void main(String[] args) {
        //Order类的权限是public,在各个包里面都能看得见
        Order order=new Order();

        //调用属性
        order.orderPublic=1;
        order.orderDefault=2;
        //order.orderPrivate=3; //不可以调用

        //调用方法
        order.methodDefault();
        order.methodPublic();
        //order.methodPrivate();    //不可以调用
    }
}
  • 调用属性

image.png

  • 调用方法

image.png

private修饰符只能在本类里面调用,出了类就不行了。

缺省可以在本包内调用,不会局限于类里面。(缺省就是default,但是现在不这么用了,因为容易和switch…case语句里面的default弄混)

不同包里面

在不同包下面创建文件,现在在test2包下创建OrderTest文件:
image.png

接下来想看一下test1包下的Order类里面的属性和方法在包test2内的OrderTest类中能不能调用。

若此时Order类被缺省修饰,就不能在包test2内的OrderTest类中创建对象了,因为缺省修饰的只能在当前包内使用。

class Order{
    //...
}

可以看到,如果现在创建Order对象是不可以的:
image.png

所以,Order类的权限要大一点:

public class Order{
    //...
}

此时不会报错了,但是导包是必须的,如下:
image.png


看一下测试代码:

package yuyi.exer01.exe01.test2;


import yuyi.exer01.exe01.test1.Order;

/**
 * ClassName: OrderTest
 * Package: yuyi.exer01.exe01.test2
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/10/23 0023 0:04
 */
public class OrderTest {
    public static void main(String[] args) {
        Order order=new Order();

        //调用属性
        order.orderPublic=1;
        //order.orderPrivate=2;	//不可以
        //order.orderDefault=3;	//不可以

        //调用方法
        order.methodPublic();
        //order.methodPrivate();	//不可以
       //order.methodDefault();	//不可以
    }
}

只有Public修饰可以:
image.png

出了本包之后,不能调用Default和Private。

总结:
在这里插入图片描述
代码敲的比较快,如果文章哪里有误,欢迎指正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1122582.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【2023年11月第四版教材】软考高项极限冲刺篇笔记(3)

8 成本管理 成本类型:可变成本、固定成本、直接成本、间接成本、机会成本、沉没成本 应急储备:成本基准内 管理成本:成本基准外 进度偏差:SV,SPI 成本管理主要是规划和控制 成本估算 类比估算 参数估算 自上而下估算 三点估算 备选方案分析 储备分析 质量成本 总资…

strstr函数和strtok函数

文章目录 strstr函数函数使用函数模拟实现strtok函数 strstr函数 参数为两个字符串的地址&#xff0c;在str1中找str2不包括结束符。 函数使用 #include<stdio.h> #include<string.h>int main() {char* str1 "abcdeffgmnlo";char* str2 "de"…

《语音优先》智能语音技术驱动的交互界面设计与语音机器人设计(译者序)...

“言为心声,语为心境”&#xff0c;语言与对话是我们沟通与协作的重要方式。而智能语音技术是一种基于人工智能和自然语言处理技术的语音交互技术。它可以通过语音识别技术将用户的语音指令转换为文本&#xff0c;然后通过自然语言处理技术对文本进行分析和理解&#xff0c;最终…

TP-LINK XDR6088 WiFi6路由器 简单开箱评测

TL-XDR6088易展版AX6000双频WiFi6路由器 简单开箱测评&#xff0c;双2.5G网口&#xff0c;双频8流&#xff0c;8颗FEM&#xff0c;支持Docker。 TP-LINK XDR5470 WiFi6路由器 简单开箱评测&#xff1a;https://blog.zeruns.tech/archives/725.html TP-LINK XDR3040 WiFi6路由…

WinMIPS64汇编指令详解

目录 MIPS指令R I J三种格式 MIPS五种寻址方式 立即数寻址 寄存器寻址 基址寻址 PC相对寻址 伪直接寻址 WinMIPS64汇编指令 助记 从内存中加载数据 lb lbu lh lhu lw lwu ld l.d lui 存储数据到内存 sb sh sw sd s.d 算术运算 daddi daddui dadd…

C++笔记之vector的初始化以及assign()方法

C笔记之vector的初始化以及assign()方法 —— 2023年4月15日 上海 code review 文章目录 C笔记之vector的初始化以及assign()方法代码——实践出真知0. 空的vector1. 花括号(initializer_list)——最推荐的初始化方法2. 花括号3. 圆括号花括号4. 圆括号5. 圆括号6. 指针花括号7…

我做不到受每个人喜欢

我做不到受每个人喜欢 我想描述一下昨天发生争吵后我个人的观点&#xff0c;希望能够重新呈现出一种积极的态度。 首先&#xff0c;让我简要梳理一下事件的经过&#xff0c;当天我像往常一样去另一个宿舍找人聊天&#xff0c;可能因为说话声音有点大&#xff0c;坐在我后面的那…

GUI设计——PyQt5快速入门

一、学习目标 了解有关GUI界面设计的基本语法能够编写简单的界面设计程序 二、PyQt5 安装与环境配置 首先&#xff0c;本人通过网上的教程&#xff0c;在Index of / (qt.io)官网上下载好了 Qt Designer 和 Qt Creator 。本人下载的版本为 5.14。随后&#xff0c;通过网络的资源…

【Spring Cloud Alibaba】seata分布式事务官方入门案例(实战版)

文章目录 1. 业务介绍1.1. 用例1.2. 架构图1.3. 3个服务的代码及业务逻辑&#xff08;略&#xff09; 2. SEATA 的分布式交易解决方案3. 由Dubbo SEATA提供支持的示例&#xff08;实战&#xff09;3.1. 步骤 1&#xff1a;建立数据库&#xff0c;如seata数据库3.2. 步骤 2&…

OSPF基础实验

一、实验拓扑 二、实验要求 1、按照图示配置 IP 地址 2、R1&#xff0c;R2&#xff0c;R3 运行 OSPF 使内网互通&#xff0c;所有接口(公网接口除外)全部宣告进 Area 0; 要求使用环回口作为 Router-id 3、业务网段不允许出现协议报文 4、R5 模拟互联网&#xff0c;内网通过…

Andriod学习笔记(二)

页面设计的零碎知识 通用属性设置文本大小设置视图宽高设置视图的对齐方式 页面布局LinearLayoutRelativeLayoutGridLayoutScollView 按钮触控ButtonImageViewImageButton 通用属性 设置文本大小 纯数字的setTextSize方法&#xff0c;内部默认字体单位为sp&#xff0c;sp是An…

Git报错解决

本篇主要汇总在使用 Git 进行提交和拉取文件时&#xff0c;遇到的问题的解决方案&#xff0c;以便下次查找。 1 关于使用Git出现“git Failed to connect to 127.0.0.1 port xxxx: Connection refused”的问题解决方案 1. 问题描述 在使用 git 拉取、提交代码的时候&#xff…

Access,Trunk,Hybrid的一些接触知识以及实验

VLAN基本配置 一、实验目的 1.掌握VLAN基础配置原理&#xff1b; 2.掌握Access接口工作原理及配置&#xff1b; 3.掌握Trunk接口工作原理及配置&#xff1b; 4.掌握Hybrid接口工作原理及配置。 二、实验设备 1.电脑1台&#xff1b; 2.ENSP仿真软件。 三、实验内容及步骤 VLAN( …

Ps:选择主体

“主体”之所以成为主体&#xff0c;因为它是一张图片中最突出或者最应该被关注的区域。 选择主体 Select Subject是 Photoshop 2018 年 1 月版开始增加的命令。Adobe 持续改良此命令的算法&#xff0c;现在不仅具有内容识别功能&#xff0c;而且对毛发区域的处理方式也有大幅改…

周阳老师学习

分布式事务 2、3pc tcc 可靠消息最终一致性 最大努力通知 总结 1&#xff09;最大努力通知VS 可靠消息最终一致性 向上管理 态度 》 能力 沟通 》 抱怨 大局 》 细节 汇报进度 寻求知道 成长答疑 先完成后完美 分布式事务-独立消息服务MQ 追溯业务执行状态的接口…

解决谷歌学术bib信息不全的问题

在我们撰写学术论文时&#xff0c;经常需要引用参考文献。如果用latex撰写论文&#xff0c;势必会用到文献的bib信息&#xff0c;大部分的教程都会告诉我们去google scholar上去搜索。 一、问题描述 搜索一篇文章&#xff0c;然后选择cite&#xff0c;再选择bib。 很明显&…

最详细STM32,cubeMX串口发送,接收数据

这篇文章将详细介绍 串口 发送数据&#xff0c;接受数据。 文章目录 前言一、串口的基础知识二、cubeMX 配置三、自动生成代码解析四、串口发送数据函数五、使用串口收发数据点亮 led重定向函数&#xff1a; 总结 前言 实验开发板&#xff1a;STM32F103C8T6。所需软件&#xf…

c语言用json解析库(jansson)检测字符串是否是json格式的数据

C语言检测字符串是否是json格式的数据&#xff0c;可以用jansson库检测&#xff0c;也可以用cjson库来校验。但是若数据格式有问题&#xff0c;jansson可以指出哪里有错误&#xff0c;cjson无法指出。 下面就演示C语言如何使用jansson库检测字符串是否是json格式的数据。 1.下载…

pow函数

pow函数 pow的翻译是指数表达式 第一个参数为底数&#xff0c;第二个参数为指数 返回值为&#xff1a; 头文件为include <math.h> #include <stdio.h> #include <math.h>int main() {int ret (int)pow(10, 2);printf("%d\n", ret);return 0; }…

算法、语言混编、分布式锁与分布式ID、IO模型

一、算法初识 数据结构和算法是程序的基石。我们使用的所有数据类型就是一种数据结构&#xff08;数据的组织形式&#xff09;&#xff0c;写的程序逻辑就是算法。 算法是指用来操作数据、解决程序问题的一组方法。 对于同一个问题&#xff0c;使用不同的算法&#xff0c;也…