当前位置: 首页 > news >正文

面向对象高级(1)

文章目录

  • final
    • 认识final关键字
      • 修饰类:
      • 修饰方法:
      • 修饰变量
      • final修饰变量的注意事项
    • 常量
  • 单例类
    • 什么是设计模式?
    • 单例怎么写?
    • 饿汉式单例的特点是什么?
    • 单例有啥应用场景,有啥好处?
    • 懒汉式单例类。
  • 枚举类
    • 认识枚举类
    • 枚举类的常见应用场景
  • 抽象类
    • 认识抽象类
    • 使用抽象类的好处
    • 模板方法设计模式
  • 接口
    • 什么是接口
    • 接口语法
    • 接口如何实现
    • 接口的好处
    • 接口的综合小案例
      • 需求
      • 分析
      • 代码
    • JDK8新增的三种方法
    • 接口的注意事项
      • 1
      • 2
      • 3
      • 4
  • 抽象类和接口的区别
  • 案例

final、单例类、枚举类、抽象类、接口

final

认识final关键字

final 关键字是最终的意思,可以修饰:类、方法、变量。
修饰类:该类被称为最终类,特点是不能被继承了。应用场景:工具类,不需要被继承。
修饰方法:该方法被称为最终方法,特点是不能被重写了。应用场景:在抽象类会讲。
修饰变量:该变量有且仅能被赋值一次。应用场景:局部变量修饰一些固定的值,比如圆周率。
成员变量,比如作为系统的配置信息。给实例变量加无意义。

修饰类:

public class FinalDemo1 {public static void main(String[] args) { }
}
// 1、final修饰类,类不能被继承。
final class A{
}
// class B extends A{} // 报错
// 应用场景 : 工具类不需要继承,所以加final
// 在比如java的内置math方法是个工具类。查看Ctrl+点击math 查看源码
// 你会发现math类使用了final:  public final class Math{...}
public final class XxxxUtil {public static void xxx(){   ......  }public static boolean xxxx(String email){  ... }  public static String xxxxx(int n){  ... }...
}

修饰方法:

public class FinalDemo1 {public static void main(String[] args) { }
}//  final修饰方法,方法不能被重写。应用场景会在抽象类中讲。
class C{public final void show(){System.out.println("show方法被执行");}
}
class D extends C{
//     @Override
//     public void show(){
//         System.out.println("show方法被执行");
//     }
}

修饰变量

我们知道变量分为很多种

  1. 成员变量:
    • 静态成员变量
    • 实例成员变量
  2. 局部变量
    下面对每种变量都加一个final修饰。
public class FinalDemo1 {public static void main(String[] args) {// final修饰变量:变量有且仅能被赋值一次。// 修饰局部变量final double rate = 3.14;// rate = 3.16; // 第二次赋值,报错。// 局部变量应用// 比如这里打八折buy(0.8);}public static void buy(final double z){// z = 0.1;  // 第二次赋值,报错。System.out.println(z);}
}public class FinalDemo1 {// final修饰静态成员变量// final修饰静态变量,这个变量今后被称为常量,// 常量可以记住一个固定值,并且程序中不能修改了,// 应用场景: 通常这个值作为系统的配置信息。// 常量的名称,建议全部大写,多个单词用下划线链接public static final String SCHOOL_NAME = "黑马程序员";public static void main(String[] args) { }
}public class FinalDemo1 {// final修饰实例变量(一般没有意义)private final String name = "猪刚鬣";public static void main(String[] args) {FinalDemo1 f = new FinalDemo1();System.out.println(f.name);// f.name = "高翠兰"; // 第二次赋值,报错。}
}

final修饰变量的注意事项

final修饰基本类型的变量,变量存储的数据不能被改变。
final修饰引用类型的变量,变量存储的地址不能被改变,但地址所指向对象的内容是可以被改变的。

public class FinalDemo1 {public static void main(String[] args) {final int a = 20;// a = 30; // 第二次赋值,报错。final int[] arr = {11, 22, 33, 44};// arr = new int[]{33, 55, 44}; // 第二次赋值,报错。修改地址arr[2] = 90;// 不报错没有修改地址}
}

常量

使用了 static final 修饰的成员变量就被称为常量(上节已经讲过).
作用:常用于记录系统的配置信息。

public class Constant {public static final String SCHOOL_NAME  = “传智教育";
} 

注意!常量名的命名规范:建议使用大写英文单词,多个单词使用下划线连接起来。

使用常量记录系统配置信息的优势、执行原理

代码可读性更好,可维护性也更好。
程序编译后,常量会被“宏替换”:出现常量的地方全部会被替换成其记住的字面量,这样可以保证使用常量和直接用字面量的性能是一样的。
运行下面代码,在out文件夹下查看编译后的代码。

public class Constant {public static final String SYSTEM_NAME = "黑马程序员智能家居AI系统";
}
public class FinalDemo2 {public static void main(String[] args) {// 目标:详解常量。System.out.println(Constant.SYSTEM_NAME);System.out.println(Constant.SYSTEM_NAME);System.out.println(Constant.SYSTEM_NAME);System.out.println(Constant.SYSTEM_NAME);System.out.println(Constant.SYSTEM_NAME);System.out.println(Constant.SYSTEM_NAME);}
}

out文件夹下查看编译后的代码如下:
常量会被“宏替换”

package com.itheima.finaldemo;public class FinalDemo2 {public FinalDemo2() {}public static void main(String[] args) {System.out.println("黑马程序员智能家居AI系统");System.out.println("黑马程序员智能家居AI系统");System.out.println("黑马程序员智能家居AI系统");System.out.println("黑马程序员智能家居AI系统");System.out.println("黑马程序员智能家居AI系统");System.out.println("黑马程序员智能家居AI系统");}
}

单例类

单例类属于设计模式这门课,设计模式架构师学的技术。
我们面试或者看底层源码可能会有一些知识涉及到设计模式。

什么是设计模式?

一个问题通常有n种解法,其中肯定有一种解法是最优的,这个最优的解法被人总结出来了,称之为设计模式。简而言之:设计模式是具体问题的最优解决方案。
设计模式有20多种,对应20多种软件开发中会遇到的问题。

关于设计模式,主要学什么?

  1. 解决什么问题。
  2. 怎么写。

单例模式解决了什么问题 ?或者说他是干什么的。
确保某个类只能创建一个对象。

单例怎么写?

  1. 把类的构造器私有;
  2. 定义一个静态变量存储类的一个对象;
  3. 提供一个静态方法返回对象。
// 设计成单例设计模式
public class A {// 2、定义一个静态变量,用于存储本类的一个唯一对象。// 第三步可以用下面的这个代替。// public static final A a = new A();private static A a = new A();// 1、私有化构造器: 确保单例类对外不能创建太多对象,单例才有可能性。private A() {}// 3、提供一个公开的静态方法,返回这个类的唯一对象。public static A getInstance() {return a;}
}
package com.itheima.singleinstance;public class Test {public static void main(String[] args) {// 目标:设计单例类。A a1 = A.getInstance();A a2 = A.getInstance();System.out.println(a1); // com.itheima.singleinstance.A@404b9385System.out.println(a2); // com.itheima.singleinstance.A@404b9385System.out.println(a1 == a2);// trueSystem.out.println("============================");B b1 = B.getInstance();B b2 = B.getInstance();System.out.println(b1);System.out.println(b2);System.out.println(b1 == b2);}
}

饿汉式单例的特点是什么?

在获取类的对象时,对象已经创建好了。

单例有啥应用场景,有啥好处?

  • 任务管理器对象、获取运行时对象。
  • 在这些业务场景下,使用单例模式,可以避免浪费内存。

懒汉式单例类。

用对象时,才开始创建对象。

  1. 懒汉单例模式怎么写?
    1. 把构造器私有。
    2. 定义一个类变量用于存储对象。
    3. 提供一个类方法,保证返回的是同一个对象。
// 懒汉式单例类。
public class B {// 2、私有化静态变量private static B b;// 1、私有化构造器private B() { }// 3、提供静态方法返回对象: 真正需要对象的时候才开始创建对象。public static B getInstance() {if (b == null) {// 第一次拿对象时,会创建对象,给静态变量b记住。b = new B();}return b;}
}public class Test {public static void main(String[] args) {B b1 = B.getInstance();B b2 = B.getInstance();System.out.println(b1);// com.itheima.singleinstance.B@682a0b20System.out.println(b2);// com.itheima.singleinstance.B@682a0b20System.out.println(b1 == b2);//true}
}

枚举类

认识枚举类

枚举是一种特殊类。
枚举类的写法

修饰符 enum 枚举类名{  名称1 ,  名称2, ... ; 其他成员…
}

特点:
枚举类中的第一行,只能写枚举类的对象名称,且要用逗号隔开。
这些名称,本质是常量,每个常量都记住了枚举类的一个对象。

// 枚举类
public enum A {// 枚举类的第一行:只能罗列枚举对象的名称,这些名称本质是常量。X, Y, Z;
}
// 这是
public class Test {public static void main(String[] args) {// 目标:认识枚举类,搞清楚其本质特点。A a1 = A.X;System.out.println(a1);A a2 = A.Y;System.out.println(a2);// 编译器为枚举类新增了几个方法System.out.println(a1.name()); // XSystem.out.println(a2.name()); // YSystem.out.println(a1.ordinal()); // 索引  0System.out.println(a2.ordinal()); // 索引  1}
}

我们来看一下public enum A{ }的编译后的代码

Compiled from “A.java"
public final class A extends java.lang.Enum<A> {public static final A X = new A();public static final A Y = new A();public static final A Z = new A();public static A[] values();public static A valueOf(java.lang.String);
}

枚举都是最终类,不可以被继承,枚举类都是继承java.lang.Enum类的。
枚举类的第一行只能罗列一些名称,这些名称都是常量,并且每个常量会记住枚举类的一个对象。
枚举类的构造器都是私有的(写不写都只能是私有的),因此,枚举类对外不能创建对象。
编译器为枚举类新增了几个方法。

枚举类的常见应用场景

先使用变量写:

public class Constant {public static final int UP = 0; // 上public static final int DOWN = 1; // 下public static final int LEFT = 2; // 左public static final int RIGHT = 3; // 右
}public class Test2 {public static void main(String[] args) {// 需求:模拟上下左右移动图片。// 第一种是常量做信息标志和分类: 但参数值不受约束。// 参数值可以传入0,1,110。move(Constant.UP);}public static void move(int direction){// 根据这个方向做移动:上下左右。switch (direction){case Constant.UP :System.out.println("向上移动");break;case Constant.DOWN :System.out.println("向下移动");break;case Constant.LEFT :System.out.println("向左移动");break;case Constant.RIGHT :System.out.println("向右移动");break;default:System.out.println("输入有误");}}
}

使用枚举类写。

public enum Direction {UP, DOWN, LEFT, RIGHT;
}
public class Test2 {public static void main(String[] args) {// 第二种是枚举做信息标志和分类: 参数值受枚举类约束。move2(Direction.DOWN);}public static void move2(Direction direction){// 根据这个方向做移动:上下左右。switch (direction){case UP:System.out.println("向上移动");break;case DOWN :System.out.println("向下移动");break;case LEFT :System.out.println("向左移动");break;case RIGHT :System.out.println("向右移动");break;}}
}

抽象类

认识抽象类

在Java中有一个关键字叫:abstract,它就是抽象的意思,可以用它修饰类、成员方法。

  • abstract修饰类,这个类就是抽象类。
  • abstract修饰方法,这个方法就是抽象方法。

语法

修饰符 abstract class 类名{ // 抽象方法:必须abstract修饰,只有方法签名,不能有方法体修饰符 abstract 返回值类型 方法名称(形参列表)}

抽象类的注意事项、特点

  • 抽象类中不一定要有抽象方法,有抽象方法的类必须是抽象类。
  • 类有的成员:成员变量、方法、构造器,抽象类都可以有。
  • 抽象类最主要的特点:抽象类不能创建对象,仅作为一种特殊的父类,让子类继承并实现
  • 一个类继承抽象类,必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类。
// 抽象类
public abstract class A {// 抽象类中不一定要有抽象方法,有抽象方法的类必须是抽象类。// 抽象类中:成员变量、方法、构造器,抽象方法都可以有private String name;private int age;public A() { System.out.println("A的无参构造器"); }public A(String name, int age) {this.name = name;this.age = age;}// 抽象方法:必须用abstract修饰,没有方法体,只有方法声明。public abstract void show();public void show1() { System.out.println("show1方法"); }//省略getter()和setter()
}public class B extends A{
// 一个类继承抽象类,必须重写完继承的全部抽象方法,否则这个类也必须定义成抽象类@Overridepublic void show() {System.out.println("B类重写show方法");}
}
public class AbstractDemo1 {public static void main(String[] args) {// 目标:认识抽象类,抽象方法,搞清楚他们的特点。// 抽象类的核心特点:有得有失(得到了抽象方法的能力,失去了创建对象的能力)// 抽象类不能创建对象(重点)。// A a = new A();  // 报错了// 抽象类的使命就是被子类继承:就是为了生孩子。B b = new B(); // A的无参构造器b.setName("张三");b.setAge(18);System.out.println(b.getName() + "---" + b.getAge());// 张三---18b.show(); // B类重写show方法b.show1();// show1方法}
}

使用抽象类的好处

父类知道每个子类都要做某个行为,但每个子类要做的情况不一样,父类就定义成抽象方法,交给子类去重写实现,我们设计这样的抽象类,就是为了更好的支持多态

public abstract class Animal {// 每个动物的叫声。// 如果这里不写抽象方法cry(),无法使用父类调用子类的方法。//  Animal a = new Dog();右侧不能解耦。public abstract void cry();
}
public class Dog extends Animal{@Overridepublic void cry() {System.out.println("🐕是汪汪汪的叫~~~");}
}
public class Cat extends Animal{@Overridepublic void cry() {System.out.println("🐱是喵喵喵的叫~~~");}
}
public class Test {public static void main(String[] args) {Animal a = new Dog();a.cry();// 🐕是汪汪汪的叫~~~}
}

模板方法设计模式

  • 提供一个方法作为完成某类功能的模板,模板方法封装了每个实现步骤,但允许子类提供特定步骤的实现。
  • 模板方法设计模式可以:提高代码的复用、并简化子类设计。
    在这里插入图片描述
    写法
    1、定义一个抽象类。
    2、在里面定义2个方法
    • 一个是模板方法:把共同的实现步骤放里面去。
    • 一个是抽象方法:不确定的实现步骤,交给具体的子类来完成。

建议使用final关键字修饰模板方法,为什么?

  • 模板方法是给子类直接使用的,不能被子类重写。
  • 一旦子类重写了模板方法,模板方法就失效了。
public abstract class People {// 1、模板方法设计模式。public final void write(){System.out.println("\t\t\t《我的爸爸》");System.out.println("\t我爸爸是一个好人,我特别喜欢他,他对我很好,我来介绍一下:");// 2、模板方法知道子类一定要写这个正文,但是每个子类写的信息是不同的,父类定义一个抽象方法// 具体的实现交给子类来重写正文。writeMain();System.out.println("\t我爸爸真好,你有这样的爸爸吗?");}public abstract void writeMain();
}
public class Student extends People{@Overridepublic void writeMain() {System.out.println("\t我爸爸很牛逼,是个管理者,我开车不用看红绿灯的,有这样的爸爸真好,下辈子还要做他儿子!");}
}
public class Teacher extends People {@Overridepublic void writeMain() {System.out.println("\t我爸爸经常让我站在这里别动,他要去买几斤橘子~~柚子我也吃,毕竟是亲生的!");}
}
public class Test {public static void main(String[] args) {// 抽象类的使用场景之二:模板方法设计模式。// 学生和老师都要写一篇作文:《我的爸爸》//         第一段是一样的:我爸爸是一个好人,我特别喜欢他,他对我很好,我来介绍一下://         第二段是不一样:老师和学生各自写各自的。//         第三段是一样的:我爸爸真好,你有这样的爸爸吗?// 解决:抽出一个父类。父类中还抽取一个模板方法给子类直接用。Student s = new Student();s.write();
//        			《我的爸爸》
//	我爸爸是一个好人,我特别喜欢他,他对我很好,我来介绍一下:
//	我爸爸很牛逼,是个管理者,我开车不用看红绿灯的,有这样的爸爸真好,下辈子还要做他儿子!
// 我爸爸真好,你有这样的爸爸吗?s.writeMain();
//我爸爸很牛逼,是个管理者,我开车不用看红绿灯的,有这样的爸爸真好,下辈子还要做他儿子!}
}

接口

什么是接口

Java提供了一个关键字interface定义出接口。

接口语法

public interface 接口名 {// 成员变量(常量)// 成员方法(抽象方法)
} 

注意:接口不能创建对象。

接口如何实现

接口是用来被类实现(implements)的,实现接口的类称为实现类,一个类可以同时实现多个接口。

修饰符 class 实现类类名 implements 接口1, 接口2, 接口3 , ... {// 实现类实现多个接口,必须重写完全部接口的全部抽象方法,// 否则实现类需要定义成抽象类。// JDK 8之前,接口中只能定义常量和抽象方法。
} 
// 接口:使用interface关键字定义的
public interface A {// JDK 8之前,接口中只能定义常量和抽象方法。// 1、常量:接口中定义常量可以省略public static final不写,默认会加上去。String SCHOOL_NAME = "黑马程序员";// public static final String SCHOOL_NAME2 = "黑马程序员";// 2、抽象方法: 接口中定义抽象方法可以省略public abstract不写,默认会加上去。// public abstract void run();void run();String go();
}
public interface B {void play(); // 玩
}
public class Test {public static void main(String[] args) {System.out.println(A.SCHOOL_NAME);// 注意:接口不能创建对象。C c = new C();c.run();System.out.println(c.go());c.play();}
}
// C被称为实现类。同时实现了多个接口。
// 实现类实现多个接口,必须重写完全部接口的全部抽象方法,否则这个类必须定义成抽象类
class C implements  B , A{@Overridepublic void run() {System.out.println("C类重写了run方法");}@Overridepublic String go() {return "黑马找磊哥!";}@Overridepublic void play() {System.out.println("C类重写了play方法");}
}

接口的好处

+ 弥补了类单继承的不足,一个类同时可以实现多个接口,使类的角色更多,功能更强大。
+ 让程序可以面向接口编程,这样程序员就可以灵活方便的切换各种业务实现(更利于程序的解耦合)。
public class Test {public static void main(String[] args) {// 接口弥补了类单继承的不足,可以让类拥有更多角色,类的功能更强大。// 学生是个人,但是学生可能兼职代代驾。所以亲爹是人,干爹是代驾等等。People p = new Student();Driver d = new Student(); // 多态BoyFriend bf = new Student();// 接口可以实现面向接口编程,更利于解耦合。// 比如说A公司要做一个对学生增删改查的功能,A公司设计一个接口,// 这个接口要求删接口 查接口 统计作业接口 // 给学生建议接口 集成ai接口。// 现在有B,C两个公司去实现这5个接口,我们用哪个呢?// A公司 a = new B公司 // A公司 a = new C公司 // 如上A公司接口不变,只要换个公司就能接着实现功能Driver a = new Student();Driver a2 = new Teacher();BoyFriend b1 = new Student();BoyFriend b2 = new Teacher();}
}
interface Driver{}
interface BoyFriend{}
class People{}
class Student extends People implements Driver, BoyFriend{}class Teacher implements Driver, BoyFriend{}

接口的综合小案例

需求

请设计一个班级学生的信息管理模块:学生的数据有:姓名、性别、成绩
功能1:要求打印出全班学生的信息;
功能2:要求打印出全班学生的平均成绩。

注意!以上功能的业务实现是有多套方案的,比如:

  • 第1套方案:能打印出班级全部学生的信息;能打印班级全部学生的平均分。
  • 第2套方案:能打印出班级全部学生的信息(包含男女人数);能打印班级全部学生的平均分(要求是去掉最高分、最低分)。
    要求:系统可以支持灵活的切换这些实现方案。

分析

提供两套业务实现方案,支持灵活切换(解耦合): 面向接口编程。
– 定义一个接口(规范思想):必须完成打印全班学生信息,打印平均分。(ClassDataInter)

  • 定义第一套实现类,实现接口:实现打印学生信息,实现打印平均分。
  • 定义第二套实现类,实现接口:实现打印学生信息(男女人数),实现打印平均分(去掉最高分和最低分)。

在这里插入图片描述

代码

在这里插入图片描述

// Student.java
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {private String name;private char sex;private double score;
}
public interface ClassDataInter {void printAllStudentInfos();void printAverageScore();
}
public class ClassDataInterImpl1 implements ClassDataInter{private Student[] students; // 记住送来的全班学生对象信息。public ClassDataInterImpl1(Student[] students) {this.students = students;}@Overridepublic void printAllStudentInfos() {System.out.println("全班学生信息如下:");for (int i = 0; i < students.length; i++) {Student s = students[i];System.out.println(s.getName() + " " + s.getSex() + " " + s.getScore());}}@Overridepublic void printAverageScore() {double sum = 0;for (int i = 0; i < students.length; i++) {Student s = students[i];sum += s.getScore();}System.out.println("全班平均成绩为:" + sum / students.length);}
}
//    -- 定义第二套实现类,实现接口:实现打印学生信息(男女人数),实现打印平均分(去掉最高分和最低分)。
public class ClassDataInterImpl2 implements ClassDataInter{private Student[] students; // 记住送来的全班学生对象信息。public ClassDataInterImpl2(Student[] students) {this.students = students;}@Overridepublic void printAllStudentInfos() {System.out.println("学生信息如下:");int maleCount = 0; // 男生人数for (int i = 0; i < students.length; i++) {Student s = students[i];System.out.println(s.getName() + " " + s.getSex() + " " + s.getScore());if (s.getSex() == '男') {maleCount++;}}System.out.println("男学生人数:" + maleCount);System.out.println("女学生人数:" + (students.length - maleCount));}// 实现打印平均分(去掉最高分和最低分)@Overridepublic void printAverageScore() {System.out.println("平均分如下:");Student s1 = students[0];double sum = s1.getScore();double max = s1.getScore();double min = s1.getScore();for (int i = 1; i < students.length; i++) {Student s = students[i];sum += s.getScore();if(s.getScore() > max) {max = s.getScore();}if(s.getScore() < min) {min = s.getScore();}}System.out.println("最高分:" + max);System.out.println("最低分:" + min);System.out.println("平均分:" + (sum - max - min) / (students.length - 2));}
}
public class Test {public static void main(String[] args) {// 目标:完成接口的小案例。// 1、定义学生类,创建学生对象,封装学生数据,才能交给别人处理学生的数据。// 2、准备学生数据,目前我们自己造一些测试数据Student[] allStudents = new Student[10];allStudents[0] = new Student("张三", '男', 100);allStudents[1] = new Student("李四", '女', 99);allStudents[2] = new Student("王五", '男', 98);allStudents[3] = new Student("赵六", '女', 97);allStudents[4] = new Student("孙七", '男', 96);allStudents[5] = new Student("周八", '女', 95);allStudents[6] = new Student("吴九", '男', 94);allStudents[7] = new Student("郑十", '女', 93);allStudents[8] = new Student("赵敏", '女', 100);allStudents[9] = new Student("周芷若", '女', 90);// 3、提供两套业务实现方案,支持灵活切换(解耦合): 面向接口编程。//    -- 定义一个接口(规范思想):必须完成打印全班学生信息,打印平均分。(ClassDataInter)//    -- 定义第一套实现类,实现接口:实现打印学生信息,实现打印平均分。//    -- 定义第二套实现类,实现接口:实现打印学生信息(男女人数),实现打印平均分(去掉最高分和最低分)。ClassDataInter cdi = new ClassDataInterImpl2(allStudents);cdi.printAllStudentInfos();cdi.printAverageScore();}
}

JDK8新增的三种方法

一般开发不用,这是sun公司为了开发其他功能而设计的。

public interface A {// 1、默认方法(普通实例方法):必须加default修饰,// 默认会用public修饰。// 如何调用? 使用接口的实现类的对象来调用。default void go(){System.out.println("==go方法执行了===");run();}// 2、私有方法(JDK 9开始才支持的)// 私有的实例方法。// 如何调用? 使用接口中的其他实例方法来调用它private void run(){System.out.println("==run方法执行了===");}// 3、静态方法// 默认会用public修饰。// 如何调用? 只能使用当前接口名来调用。static void show(){System.out.println("==show方法执行了===");}
}
class AImpl implements A{}
public class Test {public static void main(String[] args) {// 目标:搞清楚接口JDK 8新增的三种方法,并理解其好处。// 我们知道当我们需要添加一个新接口去实现某个东西,// 我们需要修改几十个接口的实现类,// 当我们有了这三种就可以直接实现不用修改接口的实现类。AImpl a = new AImpl();a.go();A.show(); // 静态方法'}
}

接口的注意事项

1、接口与接口可以多继承:一个接口可以同时继承多个接口[重点]。
2、一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承,也不支持多实现。[了解]
3、一个类继承了父类,又同时实现了接口,如果父类中和接口中有同名的默认方法,实现类会优先用父类的。
4、一个类实现了多个接口,如果多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。

1

public class Test {public static void main(String[] args) {  }
}
// 1、接口与接口可以多继承:一个接口可以同时继承多个接口[重点]。
// 类与类: 单继承 一个类只能继承一个直接父类
// 类与接口:多实现,一个类可以同时实现多个接口。
// 接口与接口: 多继承,一个接口可以同时继承多个接口。
interface A {void show1();
}
interface B {void show2();
}
interface C extends B , A{void show3();
}
class D implements C{@Overridepublic void show3() {}@Overridepublic void show1() {}@Overridepublic void show2() {}
}

2

public class Test {public static void main(String[] args) {  }
}// 2、一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承,也不支持多实现。[了解]
interface A1 {void show();
}
interface B1 {String show();
}
// 下面报错
//interface C1 extends A1, B1 {
//}
//class D1 implements A1, B1{
//}

3

public class Test {public static void main(String[] args) {Dog d = new Dog();d.go();// 父类中的 show 方法// 父类中的 show 方法// 接口中的 A2 show 方法}
}// 3、一个类继承了父类,又同时实现了接口,如果父类中和接口中有同名的方法,实现类会优先用父类的。[了解]
interface A2 {default void show(){System.out.println("接口中的 A2 show 方法");}
}class Animal{public void show(){System.out.println("父类中的 show 方法");}
}class Dog extends Animal implements A2 {public void go(){show(); // 父类的super.show(); // 父类的A2.super.show(); // A2接口的方法}
}

4

public class Test {public static void main(String[] args) {Dog d = new Dog();d.go();}
}// 4、一个类实现了多个接口,如果多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。
interface A3 {default void show(){System.out.println("接口中的 A3 show 方法");}
}interface B3 {default void show(){System.out.println("接口中的 B3 show 方法");}
}class Dog2 implements A3, B3 {@Overridepublic void show() {A3.super.show(); // A3干爹的B3.super.show(); // B3干爹的}
}

抽象类和接口的区别

相同点:

  1. 多是抽象形式,都可以有抽象方法,都不能创建对象。
  2. 都是派生子类形式:抽象类是被子类继承使用,接口是被实现类实现。
  3. 一个类继承抽象类,或者实现接口,都必须重写完他们的抽象方法,否则自己要成为抽象类或者报错!
  4. 都能支持的多态,都能够实现解耦合。

不同点:

  1. 抽象类中可以定义类的全部普通成员,接口只能定义常量,抽象方法(JDK8新增的三种方式)
  2. 抽象类只能被类单继承,接口可以被类多实现。
  3. 一个类继承抽象类就不能再继承其他类,一个类实现了接口(还可以继承其他类或者实现其他接口)。
  4. 抽象类体现模板思想:更利于做父类,实现代码的复用性。 最佳实践
  5. 接口更适合做功能的解耦合:解耦合性更强更灵活。 最佳实践

案例

某智能家居系统,可以让用户选择要控制的家用设备(吊灯,电视机,洗衣机,落地窗),并可以对它们进行打开或者关闭操作。
在这里插入图片描述

import java.util.Scanner;public class Test {public static void main(String[] args) {// 目标:面向对象编程实现智能家居控制系统。// 角色:设备(吊灯,电视机,洗衣机,落地窗,....)// 具备的功能:开和关。// 谁控制他们:智能控制系统(单例对象),控制调用设备的开和关。// 1、定义设备类:创建设备对象代表家里的设备。// 2、准备这些设备对象,放到数组中,代表整个家庭的设备。JD[] jds = new JD[4];jds[0] = new TV("小米电视", true);jds[1] = new WashMachine("美的洗衣机", false);jds[2] = new Lamp("欧灯", true);jds[3] = new Air("美的空调", false);// 3、为每个设备制定一个开个关的功能。定义一个接口,让JD实现开关功能。// 4、创建智能控制系统对象,控制设备开和关。SmartHomeControl smartHomeControl = new SmartHomeControl();// 5、控制电视机。// smartHomeControl.control(jds[0]);// 6 、提示用户操作,a、展示全部设备的当前情况。b、让用户选择哪一个操作。// 打印全部设备的开和关的现状。while (true) {smartHomeControl.printAllStatus(jds);System.out.println("请您选择要控制的设备:");Scanner sc = new Scanner(System.in);String command = sc.next();switch (command){case "1":smartHomeControl.control(jds[0]);break;case "2":smartHomeControl.control(jds[1]);break;case "3":smartHomeControl.control(jds[2]);break;case "4":smartHomeControl.control(jds[3]);break;case "exit":System.out.println("退出App!");return;default:System.out.println("输入有误,请重新输入");}}}
}
public class Air extends JD{public Air(String name, boolean status) {super(name, status);}
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;// 家电
@Data
@NoArgsConstructor
@AllArgsConstructor
public class JD implements Switch{private String name;// 状态:开或者关。private boolean status; // false 默认是关闭。@Overridepublic void press() {// 控制当前设备开和关status = !status;}
}
// 灯
public class Lamp extends JD{public Lamp(String name, boolean status) {super(name, status);}
}
// 智能控制系统类。
public class SmartHomeControl {// 多态。public void control(JD jd) {System.out.println(jd.getName() + "状态目前是:" + (jd.isStatus() ? "开着" : "关闭!"));System.out.println("开始您的操作。。。。。");jd.press(); // 按下开关。System.out.println(jd.getName() + "状态已经是:" + (jd.isStatus() ? "开着" : "关闭!"));}public void printAllStatus(JD[] jds) {// 使用for循环,根据索引遍历每个设备。for (int i = 0; i < jds.length; i++) {JD jd = jds[i];System.out.println((i + 1) + "," + jd.getName() + "状态目前是:" + (jd.isStatus() ? "开着" : "关闭!"));}}
}
public interface Switch {void press(); // 按压
}
public class TV extends JD{public TV(String name, boolean status) {super(name, status);}
}
// 洗衣机
public class WashMachine extends JD{public WashMachine(String name, boolean status) {super(name, status);}
}

相关文章:

面向对象高级(1)

文章目录 final认识final关键字修饰类&#xff1a;修饰方法&#xff1a;修饰变量final修饰变量的注意事项 常量 单例类什么是设计模式&#xff1f;单例怎么写?饿汉式单例的特点是什么&#xff1f;单例有啥应用场景&#xff0c;有啥好处&#xff1f;懒汉式单例类。 枚举类认识枚…...

Vim 编辑器的常用快捷键介绍

以下是 Vim 编辑器的常用快捷键分类介绍&#xff0c;帮助你快速掌握高效编辑技巧&#xff1a; 一、基础模式切换 Vim 的核心是 模式化操作&#xff0c;常用模式包括&#xff1a; 普通模式&#xff08;默认&#xff09;&#xff1a;导航、命令输入。插入模式&#xff1a;输入/…...

如何使用AI辅助开发R语言

R语言是一种用于统计计算和图形生成的编程语言和软件环境&#xff0c;很多学术研究和数据分析的科学家和统计学家更青睐于它。但对与没有编程基础的初学者而言&#xff0c;R语言也是有一定使用难度的。不过现在有了通义灵码辅助编写R语言代码&#xff0c;我们完全可以用自然语言…...

docker 运行自定义化的服务-后端

docker 运行自定义化的服务-前端-CSDN博客 运行自定义化的后端服务 具体如下&#xff1a; ①打包后端项目&#xff0c;形成jar包 ②编写dockerfile文件&#xff0c;文件内容如下&#xff1a; # 使用官方 OpenJDK 镜像 FROM jdk8:1.8LABEL maintainer"ATB" version&…...

【Grok 大模型深度解析】第二期:架构探秘与训练哲学

在上一期的内容中,我们对 Grok 大模型从技术溯源的角度,了解了它从 Transformer 架构局限性出发,迈向混合架构创新的历程,同时也梳理了从 Grok - 1 到 Grok - 3 的版本迭代所带来的技术跃迁以及其独特的差异化优势。这一期,我们将深入到 Grok 大模型的架构内部,探究其精妙…...

oracle update 原理

Oracle 11g 中的 UPDATE 操作是数据库修改数据的关键机制&#xff0c;其核心原理涉及事务管理、多版本并发控制&#xff08;MVCC&#xff09;、Undo/Redo 日志、锁机制等 1. 执行前的准备 SQL 解析与执行计划&#xff1a; Oracle 解析 UPDATE 语句&#xff0c;生成执行计划&…...

优化项目缓慢卡顿

大家好&#xff0c;好久不见&#xff0c;因为最近在搞几个老项目&#xff0c;没怎么跟大家见面。在做老项目的时候发现了一些小问题拿出来跟大家分享分享。 因为这个问题是生产环境下面出现的&#xff0c;所以在开发环境的时候很难发现&#xff0c;而且网速快的话也很难发现&a…...

【黑客帝国连接虚拟与现实:数据采集系统(DAQ)硬核技术深度解析】

1. DAQ系统核心架构&#xff1a;从物理世界到数字域的精密映射 1.1 传感器与信号调理&#xff1a;物理量到电信号的精准转换 传感器的物理原理与非线性补偿 热电偶&#xff08;Thermocouple&#xff09;&#xff1a;基于塞贝克效应&#xff0c;其输出电压与温度差的非线性关系…...

解决unity设置鼠标图标发布以后没有效果的问题

public Texture2D dragCursor; Cursor.SetCursor(dragCursor, Vector2.zero, CursorMode.Auto); 首先设置一个Texture2D的变量&#xff0c;用来保存自己想要设置的图&#xff0c;然后将鼠标设置为自己定义的图片。原本是很简单的功能&#xff0c;而且在编辑器里面运行也正常。…...

CExercise_10_1动态数组Vector

题目&#xff1a; 动手自己实现动态数组Vector&#xff0c;基于以下结构体定义和函数声明&#xff1a; typedef int ElementType; typedef struct { ElementType *data; // 指向堆空间的数组 int size; // 元素的个数 int capacity; // 数组的容量 } Vector; // 请实现下面方法…...

Nextra + TypeScript + MDX 项目的完整目录结构

典型的 Nextra TypeScript MDX 博客项目的完整目录结构。 Pages 架构 my-blog/ ├── components/ # React 组件 │ ├── HelloWorld.tsx # 示例组件 │ └── ... # 其他组件 ├── pages/ # 页面…...

MDM功能演示:远程锁定与数据擦除,保障企业移动设备安全

在当今高度互联的商业环境中&#xff0c;企业数据伴随着员工穿梭于不同城市、时区和设备之间。智能手机、平板电脑和笔记本电脑赋予员工随时随地办公的能力&#xff0c;但也带来了新的安全挑战&#xff1a;设备一旦遗失或落入不当之手&#xff0c;企业数据就面临泄露风险。 无…...

快速idea本地和推送到远程仓库

在你需要推送的那个文件夹打开 #创建本地仓库 git init#添加文件并首次提交 git add . git commit -m "Initial commit"#添加远程仓库地址 git remote add origin https://gitee.com/你的用户名/你的仓库名.git#查看远程仓库是否设置chengg git remote -v#原来远程仓…...

django数据迁移操作受阻

错误信息&#xff1a; django.db.utils.OperationalError: (1227, Access denied; you need (at least one of) the SYSTEM_VARIABLES_ADMIN or SESSION_VARIABLES_ADMIN privilege(s) for this operation)根据错误信息分析&#xff0c;该问题是由于MySQL用户 缺乏SYSTEM_VARI…...

使用Lombok的@Slf4j和idea构建:找不到log符号-解决

问题&#xff1a;在使用Lombok的Slf4j构建项目时提示如下内容&#xff1a; MvcConfiguration.java:26:9 java: cannot find symbol symbol: variable log location: class cn.edu.wynu.mrcinerec.mrserver.config.WebMvcConfiguration查了网上的方法都是改配置 但是使用Googl…...

物联网传感器技术架构与功能解析

物联网传感器作为物联网体系的关键组成部分&#xff0c;主要承担环境或物体状态信息的捕获与传输功能。其通过检测物理、化学或生物参数&#xff0c;将模拟信号转化为数字格式&#xff0c;并利用多种通信协议实现数据交互&#xff0c;最终服务于各类智能化应用。 核心功能模块分…...

wx213基于php+vue+uniapp的新闻资讯小程序

开发语言&#xff1a;PHP框架&#xff1a;phpuniapp数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;PhpStorm 系统展示 管理员登录界面 管理员功能界面 新闻类别管理 新闻信息管理 用户管理 管理员管…...

SOEM编译Ubuntu 22.04

下载SOEM源码 $ git clone https://github.com/OpenEtherCATsociety/SOEM.git编译源码 进入SOEM源码目录 $ mkdir build && cd build $ cmake .. $ make测试 eth1 位网卡名 $ cd test/linux/slaveinfo/ $ sudo ./slaveinfo eth1SOEM (Simple Open EtherCAT Master) …...

栈和队列(Stack和Queue)

栈和队列&#xff08;Stack和Queue&#xff09; 1&#xff1a;栈的概念 示意图&#xff1a; 2&#xff1a;创建一个类Stack&#xff0c;给定一个整形数组elem&#xff0c;数组已使用长度usedSize&#xff0c;默认长度default_size为10&#xff0c;再给定一个构造方法&#xff0…...

Django的定制以及admin

Django是一个全面的Python Web开发框架&#xff0c;具有丰富的功能&#xff0c;和众多开箱即用的接口。 简单使用 我们使用Django的django-admin工具创建项目&#xff1a; django-admin startproject project1 cd project1 django-admin startapp app1以后&#xff0c;一个简…...

LLM架构解析:编码器-解码器架构(Encoder-Decoder Architecture)(第四部分)—— 从基础原理到实践应用的深度探索

本专栏深入探究从循环神经网络&#xff08;RNN&#xff09;到Transformer等自然语言处理&#xff08;NLP&#xff09;模型的架构&#xff0c;以及基于这些模型构建的应用程序。 本系列文章内容&#xff1a; NLP自然语言处理基础词嵌入&#xff08;Word Embeddings&#xff09…...

Unity VideoPlayer 播放无声音

增加一个videoPlayer下挂&#xff0c;audiorSource脚本 this.videoPlayer.EnableAudioTrack(0, true); this.videoPlayer.audioOutputMode VideoAudioOutputMode.AudioSource; this.videoPlayer.SetTargetAudioSource(0, this.videoPlayer.GetComponent<AudioSource>()…...

【Kafka基础】监控与维护:动态配置管理,灵活调整集群行为

1 基础配置操作 1.1 修改主题保留时间 /export/home/kafka_zk/kafka_2.13-2.7.1/bin/kafka-configs.sh --alter \--bootstrap-server 192.168.10.33:9092 \--entity-type topics \--entity-name yourtopic \--add-config retention.ms86400000 参数说明&#xff1a; retention…...

AutoGen深度解析:从核心架构到多智能体协作的完整指南

AutoGen是微软推出的一个革命性多智能体(Multi-Agent)框架&#xff0c;它通过模块化设计和灵活的对话机制&#xff0c;极大地简化了基于大型语言模型(LLM)的智能体系统开发。本文将深入剖析AutoGen的两个核心模块——core基础架构和agentchat多智能体对话系统&#xff0c;带您全…...

接口请求控制工具

接口请求控制工具 功能说明代理转发安全控制访问控制错误处理配置管理日志管理 技术栈快速开始环境要求配置说明启动服务 工具源码 功能说明 代理转发 支持多路由配置支持静态资源代理灵活的路由规则配置支持请求转发和响应处理支持负载均衡 支持多目标服务器配置提供多种负载…...

Git 实践笔记

这里写自定义目录标题 一、将当前改动追加到某次commit上二、git 强制修改分支位置 一、将当前改动追加到某次commit上 stash工作区中的当前改动 git stash假设需要修改的commit是 f744c32&#xff0c;将HEAD移动到需要改动的commit的父提交上 git rebase f744c32^ --interact…...

记一个Unity中Humanoid中骨骼与武器脱离的问题

在Untiy中&#xff0c;有时人物的Humanoid的骨骼对应上了&#xff0c;但是套用动画的时候武器等节点有时会脱离&#xff0c;这是因为Humanoid只包含了人物骨骼&#xff0c;不包括其他额外的骨骼&#xff0c;因此如果想要武器节点也跟随&#xff0c;需要在Humanoid中也绑定骨骼设…...

Python asyncio

一些Pre关键概念 asyncio 本质上还是单进程单线程的Python程序&#xff1b; 建立event_loop 概念&#xff0c;上面event_loop 可以理解为大脑&#xff0c;下面是若干个可执行的Task&#xff1b; Task 没有控制权&#xff0c;没有办法控制event_loop 执行某个Task&#xff0c;只…...

【前端分享】JavaScript异步编程详解!

JavaScript 的异步编程是其核心特性之一&#xff0c;主要用于处理非阻塞操作&#xff08;如网络请求、文件读写、定时任务等&#xff09;。由于 JavaScript 是单线程的&#xff0c;异步机制可以避免代码阻塞&#xff0c;提高性能和用户体验。以下是 JavaScript 异步编程的核心概…...

深度学习基础--CNN经典网络之InceptionV1研究与复现(pytorch)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 InceptionV1是提出并行卷积结构&#xff0c;是CNN的经典网络之一&#xff1b;本次任务是探究InceptionV1结构并进行复现实验&#xff1b;欢迎收藏 关注…...

用 Vue 3 + D3.js 实现动态数据流图

文章目录 一、项目背景与功能概览二、项目准备与依赖安装2.1 安装 Vue 3 项目2.2 安装 D3.js2.3 项目结构 三、实现动态数据流图3.1 创建 DataFlowChart 组件3.2 动态更新数据流3.2.1 动态更新边和节点位置3.2.2 动画效果 四、节点拖拽与编辑功能实现4.1 添加节点拖拽功能4.2 编…...

46、Spring Boot 详细讲义(三)

五、Spring Boot 与 Web 开发 1. 简介 Spring Boot 是基于 Spring Framework 开发的一个框架,旨在简化配置,快速构建应用。它内嵌 Tomcat 等 servlet 容器,支持 RESTful API 开发,处理静态资源,以及集成视图层技术如 Thymeleaf 和 Freemarker。 2. Spring MVC 集成 Sp…...

热门面试题第15天|最大二叉树 合并二叉树 验证二叉搜索树 二叉搜索树中的搜索

654.最大二叉树 力扣题目地址(opens new window) 给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下&#xff1a; 二叉树的根是数组中的最大元素。左子树是通过数组中最大值左边部分构造出的最大二叉树。右子树是通过数组中最大值右边部分构造出的最大…...

为了避免unboundLocalError和为什么X的值一直不变呢?

## 1.为了避免unboundLocalError 发生unboundLocalError&#xff01; def generate_integer(level):if level 1:X randint(1,9)return X这里出错的原因在于&#xff0c;一旦if 后面的条件没有成立&#xff0c;然后X根本没出生&#xff0c;然后你去使用它&#xff0c;这是有…...

Express中间件(Middleware)详解:从零开始掌握(1)

1. 中间件是什么&#xff1f; 想象中间件就像一个"加工流水线"&#xff0c;请求(Request)从进入服务器到返回响应(Response)的过程中&#xff0c;会经过一个个"工作站"进行处理。 简单定义&#xff1a;中间件是能够访问请求对象(req)、响应对象(res)和下…...

Linux升级gcc版本

目录 1.安装 scl 工具集 2.安装新版本gcc 3.启用新版本 gcc 4.将启动新版本gcc指令写入配置文件 本文主要讲述如何去升级 linux 操作系统下的 gcc 编译器版本。 1.安装 scl 工具集 sudo yum install centos-release-scl scl-utils-build 由于作者已经安装过&#xff0c;…...

【概念】什么是UI(User interface)什么是UX(User experience)?

1. 软件生命周期管理 (Software Life Cycle Management) 解释&#xff1a; 中文&#xff1a; 软件生命周期管理是指从软件规划、设计、开发、测试、部署到后续维护甚至退役的整个过程。English: Software Life Cycle Management refers to the systematic process of plannin…...

【GIT】git pull --rebase 功能解析

1. git pull 命令基础 git pull 是一个常用的 Git 命令&#xff0c;用于从远程仓库获取最新的更改&#xff0c;并尝试将这些更改合并到当前分支中。这通常涉及两个步骤&#xff1a;首先&#xff0c;git fetch 命令从远程仓库下载最新的更改&#xff1b;然后&#xff0c;git me…...

难度偏低,25西电人工智能学院821、833、834考研录取情况

1、人工智能学院各个方向 2、人工智能学院近三年复试分数线对比 学长、学姐分析 由表可看出&#xff1a; 1、智能院25年院线相对于24年院线 全部专业下降比较多&#xff0c;其中控制科学与工程下降20分&#xff0c;计算机科学与技术下降20分&#xff0c;计算机技术[专硕]下降…...

L2-051 满树的遍历

L2-051 满树的遍历 - 团体程序设计天梯赛-练习集 (pintia.cn) 题解 数据结构选择 为了表示树的结构&#xff0c;我们可以使用邻接表。邻接表是一种常用的图和树的表示方法&#xff0c;它能够高效地存储每个节点的子节点信息。在本题中&#xff0c;我们可以使用一个数组 g&am…...

2025年电子电气与新材料国际学术会议

重要信息 官网&#xff1a;www.iceenm.org&#xff08;点击了解详情&#xff09; 时间&#xff1a;2025年4月25-27日 地点&#xff1a;中国-杭州 部分介绍 征稿主题 电子电气 新材料 电力电子器件和系统设计 可再生能源与电网集成技术 下一代半导体…...

数字人:打破次元壁,从娱乐舞台迈向教育新课堂(4/10)

摘要&#xff1a;数字人正从娱乐领域的璀璨明星跨界到教育领域的智慧导师&#xff0c;展现出无限潜力。从虚拟偶像、影视游戏到直播短视频&#xff0c;数字人在娱乐产业中大放异彩&#xff0c;创造巨大商业价值。在教育领域&#xff0c;数字人助力个性化学习、互动课堂和虚拟实…...

【Hyperlane 】轻松实现大文件分块上传!

【Hyperlane 】轻松实现大文件分块上传&#xff01; 痛点直击&#xff1a;大文件上传不再是难题 在云存储、音视频处理、文件协作等场景中&#xff0c;大文件上传常面临中断重试成本高、内存占用大、网络不稳定等挑战。传统方案要么复杂笨重&#xff0c;要么性能瓶颈明显。 现…...

【深入浅出 Git】:从入门到精通

这篇文章介绍下版本控制器。 【深入浅出 Git】&#xff1a;从入门到精通 Git是什么Git的安装Git的基本操作建立本地仓库配置本地仓库认识工作区、暂存区、版本库的概念添加文件添加文件到暂存区提交文件到版本库提交文件演示 理解.git目录中的文件HEAD指针与暂存区objects对象 …...

APP动态交互原型实例|墨刀变量控制+条件判断教程

引言 不同行业的产品经理在绘制原型图时&#xff0c;拥有不同的呈现方式。对于第三方软件技术服务公司的产品经理来说&#xff0c;高保真动态交互原型不仅可以在开发前验证交互逻辑&#xff0c;还能为甲方客户带来更直观、真实的体验。 本文第三部分将分享一个实战案例&#…...

第二节:React 基础篇-受控组件 vs 非受控组件

一、场景题&#xff1a;设计一个实时搜索输入框&#xff0c;说明选择依据 受控组件 vs 非受控组件 核心区别 特征受控组件非受控组件数据管理由React状态&#xff08;state&#xff09;控制通过DOM元素&#xff08;ref&#xff09;直接访问更新时机每次输入触发onChange提交…...

电脑的usb端口电压会大于开发板需要的电压吗

电脑的USB端口电压通常不会大于开发板所需的电压&#xff0c;以下是详细解释&#xff1a; 1. USB端口电压标准 根据USB规范&#xff0c;USB接口的标称输出电压为5V。实际测量时&#xff0c;USB接口的输出电压会略有偏差&#xff0c;通常在4.75V到5.25V之间。USB 2.0和USB 3.0…...

软件界面设计:打造用户喜爱的交互体验

在数字化飞速发展的当下&#xff0c;软件已渗透进生活的各个角落&#xff0c;从日常使用的社交、购物软件&#xff0c;到专业领域的办公、设计软件&#xff0c;其重要性不言而喻。而软件界面作为用户与软件交互的桥梁&#xff0c;直接决定了用户对软件的第一印象与使用体验。出…...

7、linux基础操作2

一、linux调度 1、crontab [选项] 1.1、了解 定时任务调度:指每隔指定的时间&#xff0c;执行特定的命令或程序。 基本语法&#xff1a;crontab [选项] 常用选项&#xff1a; e&#xff1a; 编辑定时任务l&#xff1a;查询定时任务r&#xff1a;删除当前用户的所有定时任务…...

大数据管理专业想求职数据分析岗,如何提升面试通过率?

从技能到策略&#xff0c;解锁高薪岗位的六大核心逻辑 在数字化浪潮席卷全球的今天&#xff0c;数据分析岗位的竞争愈发激烈。对于大数据管理专业的学生而言&#xff0c;如何从众多求职者中脱颖而出&#xff1f;本文结合行业趋势与实战经验&#xff0c;提炼出提升面试通过率的…...