【java】抽象类和接口(了解,进阶,到全部掌握)

news2024/11/25 18:39:37

各位看官早安午安晚安呀

如果您觉得这篇文章对您有帮助的话

欢迎您一键三连,小编尽全力做到更好
欢迎您分享给更多人哦

大家好我们今天来学习Java面向对象的的抽象类和接口,我们大家庭已经来啦~

一:抽象类

1.1:抽象类概念

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的 如果 一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类 。 比如
在打印图形例子中 , 我们发现 , 父类 Shape 中的 draw 方法好像并没有什么实际工作 , 主要的绘制图形都是由 Shape的各种子类的 draw 方法来完成的 . 像这种没有实际工作的方法 , 我们可以把它设计成一个 抽象方 (abstract method) , 包含抽象方法的类我们称为 抽象类(abstract class)

1.2:抽象类语法

// 抽象类:被 abstract修饰的类, 抽象类也是类,也可以增加普通方法和属性
public abstract class Shape {
public int a;
// 抽象方法:被abstract修饰的方法,没有方法体
abstract public void draw ();
}

1.3 抽象类特性

1. 抽象类不能直接实例化对象

2. 抽象方法不能被 private,final,static修饰,因为抽象方法要被子类重写;private(只能在自己的类里面使用,密封方法) ,final(不能被继承)static(静态方法,不依赖对象)

3:抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用 abstract 修饰(子类的子类要重写你俩的抽象方法(出来混,迟早都要还的))

4:被重写的方法不能比父类的访问权限更低(这是重写的要求)

4. 抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类
5. 抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量
第三条我说明一下:
abstract class Shape{
    public int a;
    public abstract void draw();
    
}
abstract class A extends Shape{
 public abstract void test(); 
 
}
class B extends A{
    @Override
    public void test() {
        
    }

    @Override
    public void draw() {
        
    }
}

只单独一个抽象方法也可以:(不过这继承毫无意义呀)

abstract class A extends Shape{
    
}

1.4:抽象类的作用:

(抽象类就是为了被继承,多了一层校验)

抽象类本身不能被实例化, 要想使用, 只能创建该抽象类的子类. 然后让子类重写抽象类中的抽象方法.

有些同学可能会说了, 普通的类也可以被继承呀, 普通的方法也可以被重写呀, 为啥非得用抽象类和抽象方法呢?
确实如此. 但是使用抽象类相当于多了一重编译器的校验
使用抽象类的场景就如上面的代码 , 实际工作不应该由父类完成 , 而应由子类完成 . 那么此时如果不小心误用成父类 了, 使用普通类编译器是不会报错的 . 但是父类是抽象类就会在实例化的时候提示错误 , 让我们尽早发现问题 .
很多语法存在的意义都是为了 "预防出错", 例如我们曾经用过的 final 也是类似 . 创建的变量用户不去修改 , 不就相当于常量嘛? 但是加上 final 能够在不小心误修改的时候 , 让编译器及时提醒我们 .
充分利用编译器的校验, 在实际开发中是非常有意义的.

二:接口

2.1 接口的概念

(抽象类是特别类,接口是特殊的抽象类(限制更多)(就是利用向上转型,向下转型,动态绑定))

在现实生活中,接口的例子比比皆是,比如:笔记本上的 USB 口,电源插座等。

2.2:接口的语法

接口的定义格式与定义类的格式基本相同,将 class 关键字换成 interface 关键字,就定义了一个接口
public interface 接口名称 {
// 抽象方法
public abstract void method1 (); // public abstract 是固定搭配,可以不写(一般都不写,但是默认有)
成员变量默认被public static final 修饰
public void method2 ();
abstract void method3 ();
这两种真不好
void method4 ();
// 注意:在接口中上述写法都是抽象方法,跟推荐方式4,代码更简洁
}

2.3 接口使用

注意:子类和父类之间是 extends 继承关系,类与接口之间是 implements 实现关系。

我们一般说实现接口,继承父类

接口不能直接使用,必须要有一个 " 实现类 " " 实现 " 该接口,实现接口中的所有抽象方法
public class 类名称 implements 接口名称 {
// ...
}
接下来我们利用接口实现一个操作:
请实现笔记本电脑使用 USB 鼠标、 USB 键盘的例子
1. USB 接口:包含打开设备、关闭设备功能
2. 笔记本类:包含开机功能、关机功能、使用 USB 设备功能
3. 鼠标类:实现 USB 接口,并具备点击功能
4. 键盘类:实现 USB 接口,并具备输入功能
// USB接口
//
interface USB {
    void openDevice();//默认被 public abstract修饰
    void closeDevice();
}
// 鼠标类,实现USB接口
class Mouse implements USB {
    @Override
    public void openDevice() {
        System.out.println("打开鼠标");
    }
    @Override
    public void closeDevice() {
        System.out.println("关闭鼠标");
    }
    public void click(){
        System.out.println("鼠标点击");
    }
}
// 键盘类,实现USB接口
class KeyBoard implements USB {
    @Override
    public void openDevice() {
        System.out.println("打开键盘");
    }
    @Override
    public void closeDevice() {
        System.out.println("关闭键盘");
    }
    public void inPut(){
        System.out.println("键盘输入");
    }
}
// 笔记本类:使用USB设备
class Computer {
    public void powerOn(){
        System.out.println("打开笔记本电脑");
    }
    public void powerOff(){
        System.out.println("关闭笔记本电脑");
    }
    public void useDevice(USB usb){//传鼠标或者键盘的引用,向上转型
        usb.openDevice();
        if(usb instanceof Mouse){//
            Mouse mouse = (Mouse)usb;//向下转型
            mouse.click();//实现鼠标特有的功能
        }else if(usb instanceof KeyBoard){
            KeyBoard keyBoard = (KeyBoard)usb;//向下转型
            keyBoard.inPut();//实现键盘特有的功能
        }
        usb.closeDevice();
    }
}
// 测试类:
public class TestUSB {
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.powerOn();//打开笔记本电脑
// 使用鼠标设备
        computer.useDevice(new Mouse());//
// 使用键盘设备
        computer.useDevice(new KeyBoard());
        computer.powerOff();//关闭笔记本电脑
    }
}

2.4.接口特点:

抽象类前4条她都有(但是接口有更多的特点,不然怎么是特殊的抽象类呢(小编自己说的))

前四条(差不多)
1. 接口类型是一种引用类型,但是不能直接 new 接口的对象(不能实例化对象)
2. 如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类(和抽象类差不多)
3:  抽象方法不能被 private,final,static修饰
4:. 重写接口中方法时,不能使用默认的访问权限(不能比接口里面的方法的访问权限更低)
5:接口中的方法默认被public abstract 修饰,成员变量默认被 public static final 修饰(不加也默认),其他修饰符会报错
6. 接口中不能有静态代码块和构造方法(这一点抽象类可以有这些)

7. 接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是 .class
USB接口
8. jdk8中:接口中还可以包含 default 方法。

2.5:实现多个接口

Java 中,类和类之间是单继承的,一个类只能有一个父类, Java中不支持多继承,但是一个类可以实现多个接 。下面通过类来表示一组动物

首先我定义一个动物类(就只定义变量(大家公用嘛),活动让子类通过实现接口来重写

class Animal {
    protected String name;
    public Animal(String name) {
        this.name = name;
    }
}

然后我定义游泳,跑步,飞的接口方法我没有方法体,让动物们来实现

interface IFlying {
    void fly();
}
interface IRunning {
    void run();
}
interface ISwimming {
    void swim();
}
接下来我要定义几个动物:猫, 是会跑的
class Cat extends Animal implements IRunning {
    public Cat(String name) {
        super(name);
    }
    @Override
    public void run() {
        System.out.println(this.name + "正在用猫腿跑");
    }
}
, 是会游的.
class Fish extends Animal implements ISwimming {
    public Fish(String name) {
        super(name);
    }
    @Override
    public void swim() {
        System.out.println(this.name + "正在用尾巴游泳");
    }
}

青蛙还是两栖的呢:既会跑又会游泳(那就实现两个接口)

class Frog extends Animal implements IRunning, ISwimming {
    public Frog(String name) {
        super(name);
    }
    @Override
    public void run() {
        System.out.println(this.name + "正在蛙跳");
    }
    @Override
    public void swim() {
        System.out.println(this.name + "正在蹬腿游泳");
    }
}

鸭子:会跑,会游泳,会飞(实现三个接口)

class Duck extends Animal implements IRunning, ISwimming, IFlying {
    public Duck(String name) {
        super(name);
    }
    @Override
    public void fly() {
        System.out.println(this.name + "正在用鸭翅膀飞");
    }
    @Override
    public void run() {
        System.out.println(this.name + "正在用鸭腿跑");
    }
    @Override
    public void swim() {
        System.out.println(this.name + "正在漂在水上");
    }
}
上面的代码展示了 Java 面向对象编程中最常见的用法 : 一个类继承一个父类, 同时实现多种接口
超级重要!!!!!!
接下来就是向上转型 (只要是你实现了这个IRunning接口,就可以被IRunning引用你的对象,你只需要把你的引用传过来,就发生了向上转型)
然后我传过去猫猫,青蛙,鸭子这些对象的引用(利用向上转型), 一个引用,传递过来的对象不同,所表现的行为不同,这就是多态的思想
public class TestInterface {
    public static void running(IRunning iRunning){
       iRunning.run();
    }
    public static void main(String[] args) {
        Cat cat = new Cat("猫猫");
        running(cat);
        Duck duck = new Duck("鸭子");
        running(duck);
        Frog frog = new Frog("青蛙");
        running(frog);
    }
}

甚至机器人只要实现了这个接口,他也可以通过这个引用实现这个动作(只要实现了这个接口和是不是动物没关系)

 Robot robot = new Robot();
        running(robot);

class Robot implements IRunning{
    @Override
    public void run(){
        System.out.println("正在用机器腿跑");
    }
}

这样设计有什么好处呢 ? 时刻牢记多态的好处 , 让程序猿 忘记类型 . 有了接口之后, 类的使用者就不必关注具体类型, 而只关注某个类是否具备某种能力

2.6 接口间的继承

类与类之间的继承只能单继承,但是接口之间的继承可以多继承(相当于把多个接口合并在了一起)(一个类也能继承多个接口)

说到合并(静态代码块也是合并)

接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字

interface IRunning {
    void run();
}
interface ISwimming {
    void swim();
}
// 两栖的动物, 既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {
}
class Frog implements IAmphibious {
...
}

2.7抽象类和接口的区别

抽象类和接口都是 Java 中多态的常见使用方式, 二者的区别前面我也讲述了一下(下面呢)
通过表格再说一下
核心区别 :
抽象类中可以包含普通方法和普通字段,这样的普通方法和字段可以被子类直接使用 ( 不必重写 )而且抽象类里面有构造方法 
而接口中不能包含普通方法, 子类必须重写所有的抽象方法,(而且成员变量都是全局常量)接口里面没有构造方法
如之前写的 Animal 例子 . 此处的 Animal 中包含一个 name 这样的属性 , 这个属性在任何子类中都是存在的 . 因此 此处的 Animal 只能作为一个抽象类 , 而不应该成为一个接口
class Animal {
    protected String name;
    public Animal(String name) {
        this.name = name;
    }
}

三:object类

Object Java 默认提供的一个类。 Java里面除了Object 类,所有的类都是存在继承关系的。默认会继承 Object类 。即所有类的对象都可以使用Object 的引用进行接收。

例如:

所以在开发之中, Object 类是参数的最高统一类型。但是 Object 类也存在有定义好的一些方法。如下:

我们先了解这几种方法

3.1:equals方法

首先我们看一下object类里面实现的equals方法(很显然就是两个引用在比较,就是比较两个地址是否一样)

既然是这样那么这个equals方法就和普通的比较没什么区别了(所以只要我们要用的话就只能重写这个方法(除非你就想这么用))

  public static void main(String[] args) {
        Person person1 = new Person("zhangsan",18);
        Person person2 = new Person("zhangsan",18);
        Person person3 = person1;
        System.out.println(person1 == person2);//其实就是两个引用在比较
        
        //那我们换equals方法来比较呢?
        System.out.println(person1.equals(person2));//false
        System.out.println(person1.equals(person3));地址相等才相等(你来指向一个对象)
    }

那么我们就重新写一下这个方法:

 @Override
    public boolean equals(Object obj) {//返回true或者false
        if (obj == null) {
            return false ;
        }
        if(this == obj) {
            return true ;
        }
// 不是Person类对象
        if (!(obj instanceof Person)) {//判断obj是否是Person的实例(obj这个引用是否指向了Person类的对象)
            return false ;
        }
        Person person = (Person) obj ; // 向下转型,比较属性值
        return this.name.equals(person.name) && this.age==person.age ;
    }

}

接下来再运行一下:

显然就可以了

3.2.hascode方法:

回忆刚刚的toString方法的源码:
public String toString () {
return getClass (). getName () + "@" + Integer . toHexString ( hashCode ());(进化过处理的地址)
}
hashCode() 这个方法,帮我们算了一个具体的 对象位置 ,这里面涉及数据结构,但是我们还没学数据结构,没法讲述,所以我们只能说它是个内存地址。然后调用Integer.toHexString() 方法,将这个地址以 16 进制输出
hashcode方法源码:(该方法是一个 native 方法,底层是由 C/C++ 代码写的。我们看不到)
示例:
        Person person1 = new Person("zhangsan",18);
        Person person2 = new Person("zhangsan",18);

        System.out.println(person1.hashCode());
        System.out.println(person2.hashCode());


但是我们想要把两个名字相同,年龄相同的对象,存储在同一个位置,这个时候我们就要重写hashcode()方法了

结果:
总结:
hashcode方法用来确定对象在内存中存储的位置是否相同,equals方法用来确定该对象的内容是否一样(我们重写的)

四:比较两个对象的大小以及排序对象数组:

4.1:比价两个对象的大小

引用类型不能直接这么比较

public class Test{
    public static void main(String[] args) {
        Student student1 = new Student("zhangsan",18);
        Student student2 = new Student("zhangsan",18);
        //System.out.println(student1 > student2);//引用类型不能这样比较
        
    }   
}

如果要比较的话:要实现一个接口(并且重写它的比较方法)

class Student implements Comparable<Student> {
        String name;
        int age;
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }

    @Override
    public int compareTo(Student o) {
        return this.age - o.age;
    }
}
        Student student1 = new Student("zhangsan",18);
        Student student2 = new Student("zhangsan",12);
        System.out.println(student1.compareTo(student2));
        //结果为6

比较名字大小的时候我们直接可以用String类的CompareTo进行比较(String类已经对它进行重写了(后面在认识String类的时候我会讲到))

 System.out.println(student1.name.compareTo(student2.name));

4.2:排序对象数组

我们就用数组排序的方法Arrays.sort排序

  public static void main(String[] args) {
        Student []students = new Student[3];

       students[0] = new Student("zhangsan",18);
       students[1] = new Student("wangwu",20);
       students[2] = new Student("lisi",17);

       Arrays.sort(students);
        System.out.println(Arrays.toString(students));
}

但是编译器报错了,你要排序但是你要按照什么排序呢?年龄?还是名字?

这里我们可以看到他要把数组里边的元素类型强转为Comparable类型(所以我们就要去建立这个联系,实现这个接口)

sort 方法中会自动调用 compareTo 方法. compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象.

package Demo1;

import java.util.Arrays;

class Student implements Comparable<Student> {
        String name;
        int age;
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    @Override
    public int compareTo(Student o) {
        return this.age - o.age;
    }
}
public class Test {
    public static void main(String[] args) {
        Student[] students = new Student[3];
        students[0] = new Student("zhangsan", 18);
        students[1] = new Student("wangwu", 20);
        students[2] = new Student("lisi", 17);
        Arrays.sort(students);
        System.out.println(Arrays.toString(students));
    }
}

结果:

sort 方法中会自动调用 compareTo 方法. compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象.

4.3:我们自己实现一个(模拟实现一个)冒泡排序呢

注意,单独比较年龄或者姓名之后,这个类整体会被交换(而不是单独交换年龄或者姓名)(你们一起被交换)

public class Test {

    public static void bubbleSort(Comparable []comparables){
        for (int i = 0; i < comparables.length-1; i++) {
            int flag = 1;
            for (int j = 0; j < comparables.length-1-i; j++) {
                //这个明显是错误的(要去全部转换啊,)(Comparable 类型没有age这个变量,这个就是一个向上转型)
                /*int tmp = 0;
                tmp = comparables[i].age;
                comparables[i].age = comparables[i+1].age;
                comparables[i+1].age = tmp;
               flag = -1;*/
                if( comparables[i].compareTo(comparables[i+1]) > 0){
                    Comparable tmp = comparables[i];
                    comparables[i+1] = comparables[i];
                    comparables[i] = tmp;
                    flag = -1;
                }
            }
            if(flag ==1){
                break;
            }
        }
    }
    public static void main(String[] args) {
        Student[] students = new Student[3];
        students[0] = new Student("zhangsan", 18);
        students[1] = new Student("wangwu", 20);
        students[2] = new Student("lisi", 17);
        bubbleSort(students);
        System.out.println(Arrays.toString(students));
        /*Arrays.sort(students);
        System.out.println(Arrays.toString(students));*/
    }
}

或者我们根本就不用实现接口呢(其实是因为String类帮我们实现过了)
用String类的compareTo方法
public class Test {
    public static void bubbleSort1(Student[]students){
        for (int i = 0; i <students.length-1; i++) {
            int flag = 1;
            for (int j = 0; j < students.length - 1 - i; j++) {
                if (students[j].name.compareTo(students[j + 1].name) > 0) {
                    Student tmp = students[j];
                    students[j] = students[j + 1];
                    students[j + 1] = tmp;
                    flag = -1;
                }
            }
            if(flag ==1){
                break;
        }
        }
    }

Comparable接口的耦合性是比较强的

当一个类实现了 Comparable 接口,它的比较逻辑就被硬编码在了类的定义中。这意味着如果需要改变比较逻辑,你必须修改这个类的源代码。这种实现方式的耦合性较强

目前我理解的是因为:Comparable的里的方法是compareTo,但是要比较名字的时候,Student实现Comparable接口,重写compareTo方法,你怎么在这个方法里面去比较字符串大小?(字符串大小比较需要String类重写的 compareTo方法去比较)

总不能compareTo里面嵌套compareTo吧?

这个时候我们就需要一个实现 另一个接口:Comparator接口(提供了更大的灵活性和解耦能力)
具体实现:
class NameComparator implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }
}
class AgeComparator implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2) {
        return o1.age - o2.age;
    }
}




 public static void main(String[] args) {
        Student[] students = new Student[3];
        students[0] = new Student("zhangsan", 18);
        students[1] = new Student("wangwu", 20);
        students[2] = new Student("lisi", 17);
        AgeComparator ageComparator = new AgeComparator();
        System.out.println(ageComparator.compare(students[0], students[1]));
        NameComparator nameComparator = new NameComparator();
        System.out.println(nameComparator.compare(students[0], students[1]));
    }
}

冒泡呢?(就改了比较大小的呗,交换的步骤都不变)

 public static void bubbleSort2(Student[]students){
        for (int i = 0; i <students.length-1; i++) {
            int flag = 1;
            for (int j = 0; j < students.length - 1 - i; j++) {
                NameComparator nameComparator= new NameComparator();
                if (nameComparator.compare(students[j],students[j+1]) > 0) {
                    Student tmp = students[j];
                    students[j] = students[j + 1];
                    students[j + 1] = tmp;
                    flag = -1;
                }
            }
            if(flag ==1){
                break;
            }
        }
    }

五:克隆:

浅拷贝:

深拷贝:


class Money implements Cloneable{
    int m;
    public Money(int m) {
        this.m =m ;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

public class clonePreviousTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("liHua", 18,new Money(10));
        Person person2 = (Person) person1.clone();
        person1.money.m = 100;
        System.out.println(person1.money.m);
        System.out.println(person2.money.m);
    }
}
class Person implements Cloneable {
    String name;
    int age;
    Money money;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tmp = (Person) super.clone();
        tmp.money = (Money) this.money.clone();
        return tmp;
    }

    public Person(String name, int age,Money money) {
        this.name = name;
        this.age = age;
        this.money = money;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

深拷贝这里就是全部都进行了拷贝,包括我们自定义的类型的值,由于异常我们现在还没有学习,具体的克隆我们放在异常的那一节进行讲解~~~

上述就是 Java面向对象之多态的全部内容了,能看到这里相信您一定对小编的文章有了一定的认可接口的出现,其实也是一个老大带几个小弟的过程,我们的大家庭就这么水灵灵的又增加啦~

有什么问题欢迎各位大佬指出
欢迎各位大佬评论区留言修正

您的支持就是我最大的动力​​​!!!!

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

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

相关文章

练习题(动态规划)

一&#xff0c;最长上升子序列2 题目&#xff1a; 思路分析&#xff1a; 之前的最长上升子序列的时间度是O(n^2)&#xff0c;同时集合划分是按以第 i - 1 个数是几来划分的&#xff0c;状态转移方程也很简单是 f[i] f[j] 1 &#xff0c;最后取所有一个max 那怎么优化呢&am…

ST7789读取ID错误新思路(以STC32G为例)

1.前言 前两天刚把ST7789写入搞定&#xff0c;这两天想折腾一下读取。最开始是读ID&#xff0c;先是用厂家送的程序&#xff0c;程序里面用的是模拟I8080协议&#xff0c;一切正常。后来我用STC32G的内置LCM模块&#xff0c;发现读取不出来。更神奇的是ID读不出来&#xff0c;…

【AIGC】AI如何匹配RAG知识库: Embedding实践,语义搜索

引言 RAG作为减少模型幻觉和让模型分析、回答私域相关知识最简单高效的方式&#xff0c;我们除了使用之外可以尝试了解其是如何实现的。在实现RAG的过程中Embedding是非常重要的手段。本文将带你简单地了解AI工具都是如何通过Embedding去完成语义分析匹配的。 Embedding技术简…

HTB:Headless[WriteUP]

目录 连接至HTB服务器并启动靶机 1.Which is the highest open TCP port on the target machine? 2.What is the title of the page that comes up if the site detects an attack in the contact support form? 使用浏览器访问靶机5000端口 3.What is the name of the …

海量数据在有限资源上处理的方法

1. 使用哈希 适用场景&#xff1a;需要处理的数据中&#xff0c;相同的数据可以分配到同样的机器/文件进行处理。 技巧总结&#xff1a;相同的数会哈希到同一个位置上 这类题目一般面试官给的描述都不是很清晰&#xff0c;需要自己去问条件、然后给出方案。 回答思路是&#…

hdfs的客户端(big data tools插件)

1.下载hadoop的压缩包在Windows,后解压 2.下载hadoop.dll文件和winutil.exe文件(网上自行查找) 下载完把这两个文件放入hadoop的bin目录 3.设置环境变量: $HADOOP_HOME指向hadoop的文件夹 4.在jetbrains公司的软件里下载big data tools插件:(在此展示的idea的) 下载完重启ide…

AI金融攻防赛:YOLO模型的数据增强与性能优化(DataWhale组队学习)

引言 大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者。本系列文章是我跟随DataWhale 2024年10月学习赛的AI金融攻防赛学习总结文档。在前一篇文章中&#xff0c;我们详细介绍了如何在金融场景凭证篡改检测中应用YOLO算法。本文将在此基础…

深入了解Spring重试组件spring-retry

在我们的项目中&#xff0c;为了提高程序的健壮性&#xff0c;很多时候都需要有重试机制进行兜底&#xff0c;最多就场景就比如调用远程的服务&#xff0c;调用中间件服务等&#xff0c;因为网络是不稳定的&#xff0c;所以在进行远程调用的时候偶尔会产生超时的异常&#xff0…

渗透测试实战—教育攻防演练中突破网络隔离

免责声明&#xff1a;文章来源于真实渗透测试&#xff0c;已获得授权&#xff0c;且关键信息已经打码处理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本…

3.matplotlib基础及用法(全)

一.基础绘图 折线图plot散点图scatter柱状图bar饼图pie 二.图表设置 设置标题设置线条设置坐标轴添加图例添加注释设置画布大小与分辨率 三.高级功能 绘制子图保存图形 一.基础绘图 1.折线图plot import matplotlib.pyplot as plt x [1, 2, 3, 4, 5] y [2, 3, 5, 7, 11] pl…

如何选择合适的电感器来匹配感性负载?

在匹配感性负载时&#xff0c;选择合适的电感器是至关重要的。电感器的主要作用是抑制电流变化&#xff0c;从而维持电路的稳定性。为了确保电路的稳定运行&#xff0c;需要考虑以下因素&#xff1a; 1. 电流和电压&#xff1a;首先&#xff0c;需要确定电感器的额定电流和额定…

GJS-WCP

不懂的就问&#xff0c;但我也是二把手......哭死 web GJS-ezssti 很常规的ssti模板注入&#xff0c;只过滤了"/","flag"。 过滤了/,flag 可以利用bash的特性绕过&#xff0c;如字符串截取&#xff0c;环境变量等等。payload1: {{url_for.__globals__[…

【uniapp】微信小程序使用echarts图表记录

1、插件引入 在Dcloud插件市场下载echarts插件&#xff1a;插件地址 或去相关代码库下载js&#xff1a;gitee地址 将static文件夹下中的echarts.min.js和ecStat.min.js复制到自己项目的static文件夹内或到echarts官方定制自己需要的图表类型下载js文件并放入相关目录。echart…

让你的 IDEA 使用更流畅 | IDEA内存修改

随着idea使用越来越频繁&#xff0c;笔者最近发现使用过程中有时候会出现卡顿现象&#xff0c;例如&#xff0c;启动软件变慢&#xff0c;打开项目的速度变慢等&#xff1a; 因此如果各位朋友觉得最近也遇到了同样的困惑&#xff0c;不妨跟着笔者一起来设置IDEA的内存大小吧~ …

【C#】在 WinForms 中使用 MVVM(Model-View-ViewModel) 设计模式

结合当前的 DevExpress 项目&#xff0c;在 WinForms 中使用 MVVM&#xff08;Model-View-ViewModel&#xff09; 设计模式。这个例子将通过数据绑定、命令绑定来展示 MVVM 模式的运用。 1. 项目结构 假设我们要实现一个简单的应用程序&#xff0c;它有一个文本框和一个按钮&…

【C++指南】类和对象(四):类的默认成员函数——全面剖析 : 拷贝构造函数

引言 拷贝构造函数是C中一个重要的特性&#xff0c;它允许一个对象通过另一个已创建好的同类型对象来初始化。 了解拷贝构造函数的概念、作用、特点、规则、默认行为以及如何自定义实现&#xff0c;对于编写健壮和高效的C程序至关重要。 C类和对象系列文章&#xff0c;可点击下…

【计网】理解TCP全连接队列与tcpdump抓包

希望是火&#xff0c;失望是烟&#xff0c; 生活就是一边点火&#xff0c;一边冒烟。 理解TCP全连接队列与tcpdump抓包 1 TCP 全连接队列1.1 重谈listen函数1.2 初步理解全连接队列1.3 深入理解全连接队列 2 tcpdump抓包 1 TCP 全连接队列 1.1 重谈listen函数 这里我们使用…

【JAVA】第三张_Eclipse下载、安装、汉化

简介 Eclipse是一种流行的集成开发环境&#xff08;IDE&#xff09;&#xff0c;可用于开发各种编程语言&#xff0c;包括Java、C、Python等。它最初由IBM公司开发&#xff0c;后来被Eclipse Foundation接手并成为一个开源项目。 Eclipse提供了一个功能强大的开发平台&#x…

IDEA如何查看所有的断点(Breakpoints)并关闭

前言 我们在使用IDEA开发Java应用时&#xff0c;基本上都需要进行打断点的操作&#xff0c;这方便我们排查BUG&#xff0c;也方便我们查看设计的是否正确。 不过有时候&#xff0c;我们不希望进入断点&#xff0c;这时候除了点击断点关闭外&#xff0c;有没有更快速的方便关闭…

深度解析机器学习的四大核心功能:分类、回归、聚类与降维

深度解析机器学习的四大核心功能&#xff1a;分类、回归、聚类与降维 前言分类&#xff08;Classification&#xff09;&#xff1a;预测离散标签的艺术关键算法与代码示例逻辑回归支持向量机&#xff08;SVM&#xff09; 回归&#xff08;Regression&#xff09;&#xff1a;预…