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

各位看官早安午安晚安呀

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

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

大家好我们今天来学习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{@Overridepublic void test() {}@Overridepublic 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 {@Overridepublic void openDevice() {System.out.println("打开鼠标");}@Overridepublic void closeDevice() {System.out.println("关闭鼠标");}public void click(){System.out.println("鼠标点击");}
}
// 键盘类,实现USB接口
class KeyBoard implements USB {@Overridepublic void openDevice() {System.out.println("打开键盘");}@Overridepublic 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);}@Overridepublic void run() {System.out.println(this.name + "正在用猫腿跑");}
}
, 是会游的.
class Fish extends Animal implements ISwimming {public Fish(String name) {super(name);}@Overridepublic void swim() {System.out.println(this.name + "正在用尾巴游泳");}
}

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

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

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

class Duck extends Animal implements IRunning, ISwimming, IFlying {public Duck(String name) {super(name);}@Overridepublic void fly() {System.out.println(this.name + "正在用鸭翅膀飞");}@Overridepublic void run() {System.out.println(this.name + "正在用鸭腿跑");}@Overridepublic 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{@Overridepublic 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));//falseSystem.out.println(person1.equals(person3));地址相等才相等(你来指向一个对象)}

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

 @Overridepublic boolean equals(Object obj) {//返回true或者falseif (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;}@Overridepublic 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;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic 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>{@Overridepublic int compare(Student o1, Student o2) {return o1.name.compareTo(o2.name);}
}
class AgeComparator implements Comparator<Student>{@Overridepublic 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 ;}@Overrideprotected 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;@Overrideprotected 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;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}

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

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python|基于Kimi大模型,实现上传文档并进行“多轮”对话(7)

前言 本文是该专栏的第7篇,后面会持续分享AI大模型干货知识,记得关注。 假设有这样的需求,需要你通过python基于kimi大模型,上传对应的文档并根据对应的prompt提示词,进行多轮对话。此外,还需要将kimi大模型生成的内容进行存储。具体场景,如下图所示: 也就是说,当我们…

这种V带的无极变速能用在新能源汽车上吧?

CVT的无极变速器的结构能用在电动汽车上吗&#xff1f;

【优选算法篇】在分割中追寻秩序:二分查找的智慧轨迹

文章目录 C 二分查找详解&#xff1a;基础题解与思维分析前言第一章&#xff1a;热身练习1.1 二分查找基本实现解题思路图解分析C代码实现易错点提示代码解读 1.2 在排序数组中查找元素的第一个和最后一个位置解题思路1.2.1 查找左边界算法步骤&#xff1a;图解分析C代码实现 1…

LeetCode94:二叉树的中序遍历

文章目录 &#x1f60a;1.题目&#x1f609;2.解法1.递归2.迭代 &#x1f60a;1.题目 尝试一下该题 &#x1f609;2.解法 1.递归 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* …

企业级 RAG 全链路优化关键技术

2024 云栖大会 - AI 搜索企业级 RAG 全链路优化关键技术 在2024云栖大会上&#xff0c;阿里云 AI 搜索研发负责人之一的邢少敏先生带领大家深入了解如何利用 RAG 技术优化决策支持、内容生成、智能推荐等多个核心业务场景&#xff0c;为企业数字化转型与智能化升级提供强有力的…

【Linux】了解pthread线程库,清楚并没有线程创建接口,明白Linux并不存在真正意义的线程(附带模型图详解析)

前言 大家好吖&#xff0c;欢迎来到 YY 滴Liunx系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《Lin…

ECHO-GL:盈利电话驱动的异质图学习股票 走势预测

目录 简单概括1 背景知识相关的工作图学习在股票预测中的应用股票预测中的收益电话会议 方法异质股票图结构建造时间分配机制滑动窗机构库存空间关系模块异构边缘类型消息传递音频引导的注意聚合财报电话会议后股票动态模块预测和优化 实验消融研究 (for Q2)模拟交易 (for Q3) …

vue组件传值之$attrs

1.概述&#xff1a;$attrs用于实现当前组件的父组件&#xff0c;向当前组件的子组件通信&#xff08;祖-》孙&#xff09; 2.具体说明&#xff1a;$attrs是一个对象&#xff0c;包含所有父组件传入的标签属性。 注意&#xff1a;$attrs会自动排除props中声明的属性&#xff0…

【不要离开你的舒适圈】:猛兽才希望你落单,亲人总让你回家,4个维度全面构建舒适圈矩阵

单打独斗的英雄时代已经落幕 抱团取暖才是社会寒冬的良策 自然界中&#xff0c;每个物种都占据着自己的领地和生存空间。 生态位的差异决定了它们的生存方式&#xff0c;一旦离开领地&#xff0c;失去群体的庇护&#xff0c;就会沦为野兽的美餐。 人类社会同样存在隐形圈层…

【C++】踏上C++学习之旅(三):“我“ 与 “引用“ 的浪漫邂逅

文章目录 前言1. "引用"的概念1.1 "引用"的语法 2. "引用"的特性3. "引用"的使用场景3.1 "引用"做参数3. 2 "引用"做返回值3.2.1 "引用"做返回值时需要注意的点 4. 常引用5. "引用"在底层的实…

自动化数据处理:使用Selenium与Excel打造的数据爬取管道

随着互联网信息爆炸式增长&#xff0c;获取有效数据成为决策者的重要任务。人工爬取数据不仅耗时且效率低下&#xff0c;因此自动化数据处理成为一种高效解决方案。本文将介绍如何使用Selenium与Excel实现数据爬取与处理&#xff0c;结合代理IP技术构建一个可稳定运行的数据爬取…

RocketMQ快速开始

前置推荐阅读&#xff1a;RocketMQ简介-CSDN博客 本地部署 RocketMQ 这一节介绍如何快速部署一个单节点单副本 RocketMQ 服务&#xff0c;并完成简单的消息收发。 系统要求 64位操作系统&#xff0c;推荐 Linux/Unix/macOS64位 JDK 1.8 1.下载安装Apache RocketMQ​ RocketMQ…

aws 把vpc残留删除干净

最近忘了把vpc 删干净导致又被收了冤大头钱 在删除vpc 的收发现又eni在使用&#xff0c;但是忘了是哪个资源在占用 先用命令行把占用的资源找出来停掉 使用 AWS 命令行界面&#xff08;CLI&#xff09;来查看 VPC 的使用情况 列出子网&#xff1a; aws ec2 describe-subnets …

抖音列表页采集-前言

准备工作&#xff1a; 1.关于selenium介绍&#xff1a; python自动化入门的话&#xff0c;selenium绝对是最方便的选择&#xff0c;基本逻辑即为&#xff1a;程序模拟人的行为操作浏览器&#xff0c;这样的操作需要借用浏览器驱动&#xff0c;我选用的是chrome浏览器&#xff…

浮动练习(3)

##每台电脑分辨率不同&#xff0c;数值高度宽度需要自己调&#xff0c;仅供参考 <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title></title> <style> div{ …

港大和字节提出长视频生成模型Loong,可生成具有一致外观、大运动动态和自然场景过渡的分钟级长视频。

HKU, ByteDance&#xff5c;⭐️ 港大和字节联合提出长视频生成模型Loong&#xff0c;该模型可以生成外观一致、运动动态大、场景过渡自然的分钟级长视频。选择以统一的顺序对文本标记和视频标记进行建模&#xff0c;并使用渐进式短到长训练方案和损失重新加权来克服长视频训练…

MATLAB(Octave)混电动力能耗评估

&#x1f3af;要点 处理电动和混动汽车能耗的后向和前向算法模型(simulink)&#xff0c;以及图形函数、后处理函数等实现。构建储能元数据信息&#xff1a;电池标称特性、电池标识符等以及静止、恒定电流和恒定电压等特征阶段。使用电流脉冲或要识别的等效电路模型类型配置阻抗…

多功能纤维上线,大脑肠道 “无线畅聊” 不是梦

大家好&#xff01;今天来了解一篇多功能微电子纤维研究——《Multifunctional microelectronic fibers enable wireless modulation of gut and brain neural circuits》发表于《Nature Biotechnology》。我们都知道大脑和内脏器官的沟通对生存至关重要&#xff0c;可一直以来…

为您的 WordPress 网站打造完美广告布局 A5广告单元格插件

一个为 WordPress 网站量身定制的强大工具,它将彻底改变您展示广告的方式 灵活多变的布局设计 A5 广告单元格插件的核心优势在于其无与伦比的灵活性。无论您是想要创建整齐的网格布局,还是希望打造独特的不规则设计,这款插件都能满足您的需求。 自定义网格数量&#xff1a;从 2…

生命科学的前沿挑战与未来机遇

生命科学的前沿挑战与未来机遇 一、引言 21世纪被誉为生命科学的世纪&#xff0c;生命科学的迅猛发展为人类的健康、环境和社会经济带来了巨大的变革。从基因编辑技术的突破&#xff0c;到合成生物学的兴起&#xff0c;再到生物医药的快速进步&#xff0c;生命科学的前沿挑战…