Java面向对象(进阶)-- super关键字的使用与子类对象实例化全过程

news2024/11/27 3:56:43

文章目录

  • 一、super关键字的使用
    • (1)为什么需要super?
    • (2)super的理解
    • (3)super可以调用的结构
      • 1、super调用方法
        • 举例1
        • 举例2
        • 举例3
        • 小结
      • 2、super调用属性
        • 举例1
        • 举例2
        • 举例3
        • 小结
      • 3、super调用构造器
        • 引入
        • 举例1
        • 举例2
        • 举例3
        • 举例4
      • 4、总结
        • super调用方法、属性
        • super调用构造器
    • (4)小结:this与super
      • 1、this和super的意义
      • 2、this和super的使用格式
    • (5)练习
      • 1、练习1
      • 2、练习2
      • 3、练习3
    • (6)面试题
      • 1、第一题
      • 2、第二题
      • 3、第三题
      • 4、第四题
  • 二、子类对象实例化全过程
    • (1)介绍
    • (2)举例

一、super关键字的使用

(1)为什么需要super?

举例1:子类继承父类以后,对父类的方法进行了重写,那么在子类中,是否还可以对父类中被重写的方法进行调用?

可以!

举例2:子类继承父类以后,发现子类和父类中定义了同名的属性(若子类造对象,就会有两个同名属性),是否可以在子类中区分两个同名的属性?(方法可以覆盖,属性不能覆盖

可以!

如何调用? 使用super关键字即可。

(2)super的理解

super的理解:父类的

在子类中,若想调用父类中被重写的方法,就用super.方法即可;若想调用父类中的属性,就用super.属性即可。

若没有写super,调用的就是子类中重写的方法和子类里面声明的属性。

在Java类中使用super来调用父类中的指定操作:

  • super可用于访问父类中定义的属性
  • super可用于调用父类中定义的成员方法
  • super可用于在子类构造器中调用父类的构造器

注意:

  • 尤其当子父类出现同名成员时,可以用super表明调用的是父类中的成员
  • super的追溯不仅限于直接父类
  • super和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识

(3)super可以调用的结构

super可以调用的结构:属性、方法、构造器

具体的:

1、super调用方法

  • 如果子类没有重写父类的方法,只要权限修饰符允许,在子类中完全可以直接调用父类的方法;
  • 如果子类重写了父类的方法,在子类中需要通过super.才能调用父类被重写的方法,否则默认调用的子类重写的方法
举例1

观察下面代码的输出结果。

【Person.java】

package yuyi01;

public class Person {
    //属性
    String name;
    private int age;

    //方法
    public void eat(){
        System.out.println("人吃饭");
    }

    public void sleep(){
        System.out.println("人睡觉");
    }
}

【Student.java】

package yuyi01;

public class Student extends Person {
    //属性
    String school;

    //方法
    public void study(){
        System.out.println("学生学习");
    }

    //重写
    public void eat(){
        System.out.println("学生多吃有营养的食物");
    }

    public void sleep(){
        System.out.println("学生保证每天不低于七小时睡眠");
    }
}

【StudentTest.java】

package yuyi01;

public class StudentTest {
    public static void main(String[] args) {
        Student s1=new Student();
        s1.eat();
        s1.sleep();

    }
}

输出结果:
image.png


举例2

如何在子类方法(Student.java里面,还能够调用父类中被重写的方法呢?

如果此时在子类方法里面调用eat()方法,毫无疑问,这个eat()方法指的是自己类里面重写的方法。如下:

image.png

当然,使用eat()调用和this.eat()调用效果一样,前者只是省略了this.而已。

若现在想调用父类中的eat()方法,很简单,只需要在前面写super.即可。(以不影响封装性为前提)

【Student.java】

package yuyi01;

public class Student extends Person {
    //属性
    String school;

    //重写
    public void eat(){
        System.out.println("学生多吃有营养的食物");
    }
	//...
    public void show(){
        eat();  //省略了this
        this.eat();

        super.eat();    //父类中的eat()方法
    }
}

this.eat();直接在本类找,找到了,就直接调用本类的重写方法即可。

super.eat();直接在直接父类中找,找到了,就直接调用父类被重写的方法即可。

eat();是省略了this.,所以本质上也是调用本类中的方法,若本类中找不到,才会去父类中找。

测试类【StudentTest.java】

package yuyi01;

public class StudentTest {
    public static void main(String[] args) {
        Student s1=new Student();
        //...
        s1.show();
    }
}

运行结果:

image.png


举例3

父类【Person.java】

package yuyi01;

public class Person {
    //...
    public void doSport(){
        System.out.println("人运动");
    }
}

子类【Student.java】

package yuyi01;

public class Student extends Person {
    //...
    public void show1(){
        doSport();
    }
}

此时子类中调用的doSport()毫无疑问是父类中的方法,因为子类中没有重写它。

这时候它的前缀是啥呢?

若在本类中调用方法,前缀都会省略this.。调用show1()方法的时候,它会在本类中找doSport()方法,找不到就会去父类中找。

此时本类中没有doSport()方法,就会去父类中找,找到并调用。若父类中还没有,就会继续往上找,直到Object,还没有找到就会报错了。

画个图看看:

image.png

此时Sutdent类里面没有重写doSport(),所以只有一个父类Person中的doSport()而已,只能调用它。

从结果上说this.doSport()super.doSport()一致;但是从过程上来说this.doSport()先从本类开始找,super.doSport()直接向直接父类中找。

【Student.java】

package yuyi01;

public class Student extends Person {
    //...
    public void show1(){
        doSport();
        this.doSport();
        super.doSport();
    }
}

测试类【StudentTest.java】

package yuyi01;

public class StudentTest {
    public static void main(String[] args) {
        Student s1=new Student();
        //...
        s1.show1();
    }
}

运行结果:

image.png

小结
  • 方法前面没有super.和this.
    • 先从子类找匹配方法,如果没有,再从直接父类找,再没有,继续往上追溯
  • 方法前面有this.
    • 先从子类找匹配方法,如果没有,再从直接父类找,再没有,继续往上追溯
  • 方法前面有super.
    • 从当前子类的直接父类找,如果没有,继续往上追溯

2、super调用属性

  • 如果实例变量与局部变量重名,可以在实例变量前面加this.进行区别
  • 如果子类实例变量和父类实例变量重名,并且父类的该实例变量在子类仍然可见,在子类中要访问父类声明的实例变量需要在父类实例变量前加super.,否则默认访问的是子类自己声明的实例变量
  • 如果父子类实例变量没有重名,只要权限修饰符允许,在子类中完全可以直接访问父类中声明的实例变量,也可以用this.实例访问,也可以用super.实例变量访问
举例1

暂且不考虑权限的事情。此时父类Person和子类Student中有同名的属性id

父类【 Person.java】

package yuyi01;

public class Person {
    //属性
    String name;
    private int age;

    int id; //身份证号

}

子类【Student.java】

package yuyi01;

public class Student extends Person {
    //属性
    String school;
    int id; //学号

}

若此时创建子类Student的对象,那么它拥有几个属性呢?和父类同名的属性会不会被干掉?

来Debug一下:

image.png

所以,属性没有方法那样有覆盖之说

属性不会覆盖,而方法可以覆盖。


举例2

既然有两个同名的属性,那么该如何区分它们呢?

此时将父类和子类中的属性id都赋值。

父类【 Person.java】

package yuyi01;

public class Person {
    //属性
    String name;
    private int age;

    int id=1001; //身份证号

}

在子类中写一个show2()方法,输出id的结果是什么呢?

子类【Student.java】

package yuyi01;

public class Student extends Person {
    //属性
    String school;
    int id=1002; //学号

    public void show2(){
        System.out.println(id); //?
    }
}

此时输出语句并没有报错,这里遵循一个就近原则

就和之前说的get方法一样,比如:

image.png

再比如:

image.png

当时解决办法是这样:

image.png

具体关于this的讲解在这一篇博客:https://blog.csdn.net/m0_55746113/article/details/134089173?spm=1001.2014.3001.5502


所以此时的id会就近找一个一样的,然后就找到了本类的id。

若想要父类中的id,就需要加一个super.

子类【Student.java】

package yuyi01;

public class Student extends Person {
    //属性
    String school;
    int id=1002; //学号

    public void show2(){
        System.out.println(id); 	//1002
        System.out.println(this.id); 	//1002

        System.out.println(super.id); 	//1001
    }
}

测试类【StudentTest.java】

package yuyi01;

public class StudentTest {
    public static void main(String[] args) {
        Student s1=new Student();
    	//...
        System.out.println();
        s1.show2();
    }
}

运行结果:

image.png

举例3

父类【Person.java】

package yuyi01;

public class Person {
    //属性
    String name;
    //...
}

子类【Student.java】

package yuyi01;

/**
 * ClassName: Student
 * Package: yuyi04
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/10/29 0029 16:40
 */
public class Student extends Person {
    //属性
    String school;
    int id=1002; //学号

    //方法
    public void show3(){
        System.out.println(name);   //这样写就相当于省略了this
        System.out.println(this.name);
        System.out.println(super.name);
    }
}

name先在当前类里面找,若没有找到,就去父类中找。

从结果上,三个输出值是一样的;但从过程上来说,name先找本类再找父类,super.name直接找父类。

测试类【StudentTest.java】

package yuyi01;

public class StudentTest {
    public static void main(String[] args) {
        Student s1=new Student();

        s1.show3();
    }
}

输出结果:

image.png


加super与this,就是区分重名的属性,重写的方法。

若没有重名属性和重写的方法,this与super加不加无所谓,只不过一个本类找,一个直接父类找,过程上有区别,结果上没有区别。

若是父类中没有的属性(本类中有),用super直接父类中找是会报错的。

image.png

小结

总结:起点不同(就近原则)

  • 变量前面没有super.和this.
    • 在构造器、代码块、方法中如果出现使用某个变量,先查看是否是当前块声明的局部变量
    • 如果不是局部变量,先从当前执行代码的本类去找成员变量
    • 如果从当前执行代码的本类中没有找到,会往上找父类声明的成员变量(权限修饰符允许在子类中访问的)
  • 变量前面有this.
    • 通过this找成员变量时,先从当前执行代码的本类去找成员变量
    • 如果从当前执行代码的本类中没有找到,会往上找父类声明的成员变量(权限修饰符允许在子类中访问的)
  • 变量前面super.
    • 通过super找成员变量,直接从当前执行代码的直接父类去找成员变量(权限修饰符允许在子类中访问的)
    • 如果直接父类没有,就去父类的父类中找(权限修饰符允许在子类中访问的)

特别说明:应该避免子类声明和父类重名的成员变量

3、super调用构造器

引入

为何要调用构造器?

比如在Student类里new了一个Student对象,可以通过s1调用属性、方法。

【Student.java】

package yuyi01;

public class Student extends Person {
    //属性
    String school;
    int id=1002; //学号

}

若此时父类Person里面的name属性没有限制,那么在测试里面可以调用name属性。

image.png

这里我们知道内存中有name属性,才直接调用它。

可我们new的是Student,相当于调用的是Student的构造器,会加载Student的结构,那为啥还会加载父类的结构呢(为啥内存中有

name属性)?这里就涉及到super调用构造器的问题。

举例1

① 子类继承父类时,不会继承父类的构造器(构造器只有在同名的类里面才有)。只能通过“super(形参列表)”的方式调用父类指定的构造器。

父类【Person.java】

package yuyi01;

public class Person {
    //属性
    String name;
    private int age;
    int id=1001; //身份证号

    //构造器
    public Person() {

    }

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

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

子类【Student.java】

package yuyi01;

public class Student extends Person {
    //属性
    String school;
    int id=1002; //学号

    //测试super调用父类的构造器
    public Student(){

    }
    public Student(String name,int age){

    }
}

比如在子类中调用父类中的空参构造器:

image.png

举例2

父类【Person.java】

package yuyi01;

public class Person {
    //构造器
    public Person() {
        System.out.println("Person()...");
    }
}

子类【Student.java】

package yuyi01;

public class Student extends Person {
    //测试super调用父类的构造器
    public Student(){
        super();    //调用父类中空参的构造器
        System.out.println("Student()...");
    }
}

测试类【StudentTest.java】

package yuyi01;

public class StudentTest {
    public static void main(String[] args) {
        Student s2=new Student();
    }
}

输出结果:

image.png

当我们调用子类构造器创建对象的时候,先调用父类构造器,输出Person()...,然后再输出Student()...。如下:

image.png

可以在子类构造器中调用父类的构造器,格式就是super(形参列表)。

举例3

② 规定:“super(形参列表)”,必须声明在构造器的首行。(和this很像)

如下:

image.png


③ 我们前面讲过,在构造器的首行可以使用"this(形参列表)",调用本类中重载的构造器, 结合②,结论:在构造器的首行,“this(形参列表)” 和 "super(形参列表)"只能二选一。

比如:

image.png


④ 如果在子类构造器的首行既没有显示调用"this(形参列表)“,也没有显式调用"super(形参列表)”, 则子类此构造器默认调用"super()",即调用父类中空参的构造器。

父类【Person.java】

package yuyi01;

public class Person {
    //构造器
    public Person() {
        System.out.println("Person()...");
    }

}

子类【Student.java】

package yuyi01;

public class Student extends Person {
    public Student(String name,int age){
        //没有显示调用父类中空参的构造器
    }
}

测试类【StudentTest.java】

package yuyi01;

public class StudentTest {
    public static void main(String[] args) {
        Student s3=new Student("Tom",13);
    }
}

输出结果:

image.png


Student(String name,int age)构造器首行,并没有写this(形参列表),也没有写"super(形参列表)"。此时会默认是Super(),而且是空参的。

来Debug看一下:

image.png

进入构造器了,如下:

image.png

再下一步:

image.png

所以,在调Student构造器的时候,没有写this,也没有super语句,会默认父类空参构造器。

若此时将空参构造器注释掉,会发现子类中两个构造器都会报错。第一个是显示调用,但没有找到空参构造器,就会报错;第二个虽然没有显示调用谁,但是默认调用了空参构造器,也没有找到,所以也会报错。如下:

image.png


⑤ 由③和④得到结论:子类的任何一个构造器中,要么会调用本类中重载的构造器,要么会调用父类的构造器。 只能是这两种情况之一。

画个图瞅瞅:

image.png


⑥ 由⑤得到:一个类中声明有n个构造器,最多有n-1个构造器中使用了"this(形参列表)“(若有n个就会形成一个环,递归了),则剩下的那个一定使用"super(形参列表)”(显示或者默认)。

子类中的任何一个构造器,都会直接或间接地调用父类的构造器。如下:

image.png

开发中常见错误:

如果子类构造器中既未显式调用父类或本类的构造器,且父类中又没有空参的构造器,则编译出错。

调用父类构造器不是为了造对象,造对象需要搭配new,调用父类构造器是为了初始化信息–比如将父类的属性、方法加载到内存中。

image.png


举例4

父类【Person.java】

package yuyi01;

public class Person {
    //属性
    String name;
    private int age;

    int id=1001; //身份证号

    //方法
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    //构造器
    public Person() {
        System.out.println("Person()...");
    }
}

子类【Student.java】

package yuyi01;

public class Student extends Person {
    //属性
    String school;
    int id=1002; //学号

    public Student(String name,int age){
        //没有显示调用父类中空参的构造器
        setAge(age);
        super.name=name;	//当前类里面没有name属性,这里super也可以写成this
    }
}

上面的写法很Low,若父类Person中有这样的构造器:

package yuyi01;

public class Person {
    //属性
    String name;
    private int age;

    int id=1001; //身份证号

    //构造器
    public Person() {
        System.out.println("Person()...");
    }

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

}

子类可以这样写:

package yuyi01;

public class Student extends Person {
    //属性
    String school;
    int id=1002; //学号

    public Student(String name,int age){
       super(name,age);
    }
}

那么子类就可以直接调用父类中的构造器,如下:(若是没有写,调用的就是父类中的空参构造器Person()

image.png

以后声明子类构造器的时候,构造器的首行就可以调用父类指定的结构了。

4、总结

子类继承父类以后(super关键字使用的前提是基于继承),我们就可以在子类的方法或构造器中,调用父类中声明的属性或方法。(满足封装性的前提下)

super调用方法、属性

🗃️如何调用呢?

需要使用"super."的结构,表示调用父类的属性或方法。

一般情况下,我们可以考虑省略"super."的结构。

但是,如果出现子类重写了父类的方法子父类中出现了同名的属性时,则必须使用"super."的声明,显式地调用父类被重写的方法父类中声明的同名的属性

特别说明:应该避免子类声明和父类重名的成员变量(方法没法避开)

在阿里的开发规范等文档中都做出明确说明:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

super调用构造器

① 子类继承父类时,不会继承父类的构造器。只能通过“super(形参列表)”的方式调用父类指定的构造器。

② 规定:“super(形参列表)”,必须声明在构造器的首行。

③ 我们前面讲过,在构造器的首行可以使用"this(形参列表)",调用本类中重载的构造器,
结合②,结论:在构造器的首行,“this(形参列表)” 和 "super(形参列表)"只能二选一。

④ 如果在子类构造器的首行既没有显示调用"this(形参列表)“,也没有显式调用"super(形参列表)”,
则子类此构造器默认调用"super()",即调用父类中空参的构造器。

⑤ 由③和④得到结论:子类的任何一个构造器中,要么会调用本类中重载的构造器,要么会调用父类的构造器。
只能是这两种情况之一。

⑥ 由⑤得到:一个类中声明有n个构造器,最多有n-1个构造器中使用了"this(形参列表)“,
则剩下的那个一定使用"super(形参列表)”。

–> 我们在通过子类的构造器创建对象时,一定在调用子类构造器的过程中,直接或间接的调用到父类的构造器
正因为调用过父类的构造器,我们才会将父类中声明的属性或方法加载到内存中,供子类对象使用

情景举例1:

class A{

}
class B extends A{

}

class Test{
    public static void main(String[] args){
        B b = new B();
        //A类和B类都是默认有一个无参构造,B类的默认无参构造中还会默认调用A类的默认无参构造
        //但是因为都是默认的,没有打印语句,看不出来
    }
}

情景举例2:

class A{
    A(){
        System.out.println("A类无参构造器");
    }
}
class B extends A{

}
class Test{
    public static void main(String[] args){
        B b = new B();
        //A类显示声明一个无参构造,
        //B类默认有一个无参构造,
        //B类的默认无参构造中会默认调用A类的无参构造
        //可以看到会输出“A类无参构造器"
    }
}

情景举例3:

class A{
    A(){
        System.out.println("A类无参构造器");
    }
}
class B extends A{
    B(){
        System.out.println("B类无参构造器");
    }
}
class Test{
    public static void main(String[] args){
        B b = new B();
        //A类显示声明一个无参构造,
        //B类显示声明一个无参构造,        
        //B类的无参构造中虽然没有写super(),但是仍然会默认调用A类的无参构造
        //可以看到会输出“A类无参构造器"和"B类无参构造器")
    }
}

情景举例4:

class A{
    A(){
        System.out.println("A类无参构造器");
    }
}
class B extends A{
    B(){
        super();
        System.out.println("B类无参构造器");
    }
}
class Test{
    public static void main(String[] args){
        B b = new B();
        //A类显示声明一个无参构造,
        //B类显示声明一个无参构造,        
        //B类的无参构造中明确写了super(),表示调用A类的无参构造
        //可以看到会输出“A类无参构造器"和"B类无参构造器")
    }
}

情景举例5:

class A{
    A(int a){
        System.out.println("A类有参构造器");
    }
}
class B extends A{
    B(){
        System.out.println("B类无参构造器");
    }
}
class Test05{
    public static void main(String[] args){
        B b = new B();
        //A类显示声明一个有参构造,没有写无参构造,那么A类就没有无参构造了
        //B类显示声明一个无参构造,        
        //B类的无参构造没有写super(...),表示默认调用A类的无参构造
        //编译报错,因为A类没有无参构造
    }
}

image.png

情景举例6:

class A{
    A(int a){
        System.out.println("A类有参构造器");
    }
}
class B extends A{
    B(){
        super();
        System.out.println("B类无参构造器");
    }
}
class Test06{
    public static void main(String[] args){
        B b = new B();
        //A类显示声明一个有参构造,没有写无参构造,那么A类就没有无参构造了
        //B类显示声明一个无参构造,        
        //B类的无参构造明确写super(),表示调用A类的无参构造
        //编译报错,因为A类没有无参构造
    }
}

image.png

情景举例7:

class A{
    A(int a){
        System.out.println("A类有参构造器");
    }
}
class B extends A{
    B(int a){
        super(a);
        System.out.println("B类有参构造器");
    }
}
class Test07{
    public static void main(String[] args){
        B b = new B(10);
        //A类显示声明一个有参构造,没有写无参构造,那么A类就没有无参构造了
        //B类显示声明一个有参构造,        
        //B类的有参构造明确写super(a),表示调用A类的有参构造
        //会打印“A类有参构造器"和"B类有参构造器"
    }
}

情景举例8:

class A{
    A(){
        System.out.println("A类无参构造器");
    }
    A(int a){
        System.out.println("A类有参构造器");
    }
}
class B extends A{
    B(){
        super();//可以省略,调用父类的无参构造
        System.out.println("B类无参构造器");
    }
    B(int a){
        super(a);//调用父类有参构造
        System.out.println("B类有参构造器");
    }
}
class Test8{
    public static void main(String[] args){
        B b1 = new B();
        B b2 = new B(10);
    }
}

(4)小结:this与super

1、this和super的意义

this:当前对象

  • 在构造器和非静态代码块中,表示正在new的对象
  • 在实例方法中,表示调用当前方法的对象

super:引用父类声明的成员

2、this和super的使用格式

  • this
    • this.成员变量:表示当前对象的某个成员变量,而不是局部变量
    • this.成员方法:表示当前对象的某个成员方法,完全可以省略this.
    • this()或this(实参列表):调用另一个构造器协助当前对象的实例化,只能在构造器首行,只会找本类的构造器,找不到就报错
  • super
    • super.成员变量:表示当前对象的某个成员变量,该成员变量在父类中声明的
    • super.成员方法:表示当前对象的某个成员方法,该成员方法在父类中声明的
    • super()或super(实参列表):调用父类的构造器协助当前对象的实例化,只能在构造器首行,只会找直接父类的对应构造器,找不到就报错

(5)练习

1、练习1

🌋题目描述

修改方法重写的练习2中定义的类Kids中employeed()方法,在该方法中调用父类ManKind的employeed()方法,
然后再输出"but Kids should study and no job."

【Kids.java】

package yuyi02;

/**
 * ClassName: Kids
 * Package: yuyi05
 * Description:
 修改继承内容的练习1中定义的类Kids,在Kids中重新定义employeed()方法,
 覆盖父类ManKind中定义的employeed()方法,输出"Kids should study and no job."

 * @Author 雨翼轻尘
 * @Create 2023/10/30 0030 10:56
 */
public class Kids extends Mankind { //父类中声明的属性和方法都被继承到子类了,构造器就不提了。后边提super关键字的时候会提到,在子类当中调用父类中的构造器
    private int yearOld;

    public int getYearOld() {
        return yearOld;
    }

    public void setYearOld(int yearOld) {
        this.yearOld = yearOld;
    }

    public void printAge(){
        System.out.println("I am "+yearOld+" years old");
    }

    @Override
    public void employeed() {
        System.out.println("Kids should study and no job.");
    }

    //构造器
    public Kids(){

    }

    public Kids(int yearOld){
        this.yearOld=yearOld;
    }

    //把父类中的属性也做一个赋值,包括自己的属性
    public Kids(int sex, int salary,int yearOld){
        this.yearOld=yearOld;
        //sex、salary两个 属性是父类继承过来的,怎么给他们赋值?
        setSex(sex);
        setSalary(salary);
    }
}

【Mankind.java】

package yuyi02;

/**
 * ClassName: Mankind
 * Package: yuyi05
 * Description:
 * (1)定义一个ManKind类,包括
 *    成员变量int sex和int salary;
 * - 方法void manOrWoman():根据sex的值显示“man”(sex==1)或者“woman”(sex==0);
 *
 * - 方法void employeed():根据salary的值显示“no job”(salary==0)或者“ job”(salary!=0)。
 * @Author 雨翼轻尘
 * @Create 2023/10/30 0030 10:32
 */
public class Mankind {
    //属性
    private int sex;
    private int salary;

    //方法

    public int getSex() {
        return sex;
    }

    public void setSex(int sex) {
        this.sex = sex;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    public void manOrWoman(){
        if(sex==1){
            System.out.println("man");
        } else if (sex==0) {
            System.out.println("woman");
        }
    }

    public void employeed(){
        if(salary==0){
            System.out.println("no job");
        } else {
            System.out.println("job");
        }
    }

    //构造器

    public Mankind() {

    }

    public Mankind(int sex, int salary) {
        this.sex = sex;
        this.salary = salary;
    }
}

【KidsTest.java】

package yuyi02;

/**
 * ClassName: KidsTest
 * Package: yuyi05
 * Description:
 *(3)定义类KidsTest,在类的main方法中实例化Kids的对象someKid,用该对象访问其父类的成员变量及方法。
 * @Author 雨翼轻尘
 * @Create 2023/10/30 0030 10:58
 */
public class KidsTest {
    public static void main(String[] args) {
        Kids someKid=new Kids();
        someKid.setSex(1);
        someKid.setSalary(100);
        someKid.setYearOld(12);

        //Kids类自己声明的方法
        someKid.printAge();

        //来自于父类中声明的方法
        someKid.manOrWoman();
        someKid.employeed();

        //
        System.out.println("*************");
        someKid.employeed();

    }
}

🤺代码

【 Kids.java】

package yuyi02;

/**
 * ClassName: Kids
 * Package: yuyi05
 * Description:
 修改方法重写的练习2中定义的类Kids中employeed()方法,在该方法中调用父类ManKind的employeed()方法,
 然后再输出"but Kids should study and no job."

 * @Author 雨翼轻尘
 * @Create 2023/11/4 0030 10:56
 */
public class Kids extends Mankind { //父类中声明的属性和方法都被继承到子类了,构造器就不提了。后边提super关键字的时候会提到,在子类当中调用父类中的构造器
   //...
    
    @Override
    public void employeed() {
        //在子类中调用父类中被重写的方法
        super.employeed();    //先去调用父类中的employeed()方法
        System.out.println("but Kids should study and no job.");
    }
    
	//...
}

【Mankind.java】

package yuyi02;

public class Mankind {
    //...
    public void employeed(){
        if(salary==0){
            System.out.println("no job");
        } else {
            System.out.println("job");
        }
    }
}

【KidsTest.java】

package yuyi02;

public class KidsTest {
    public static void main(String[] args) {
        //...
        Kids someKid=new Kids();
        someKid.employeed();
    }
}

👻输出结果

image.png

2、练习2

🌋题目描述

在Cylinder类中修改求表面积的方法findArea()和求体积的方法findVolume(),使用上super。

【Circle.java】

package yuyi03;

/**
 * ClassName: Circle
 * Package: yuyi06
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/10/31 0031 10:07
 */
public class Circle {
    //属性
    private double radius;  //半径
    //方法
    public void setRadius(double radius){
        this.radius=radius;
    }
    public double getRadius(){
        return radius;
    }
    //求圆的面积
    public double findArea(){
        return Math.PI*radius*radius;
    }

    //构造器
    public Circle(){
        radius=1;
    }
}

【Cylinder.java】

package yuyi03;

/**
 * ClassName: Cylinder
 * Package: yuyi06
 * Description:
 *  圆柱类
 * @Author 雨翼轻尘
 * @Create 2023/10/31 0031 10:19
 */
public class Cylinder extends Circle {
    //属性
    private double length;  //高

    //方法
    public void setLength(double length){
        this.length=length;
    }
    public double getLength(){
        return length;
    }
    //求圆柱的体积
    public double findVolume(){
        return Math.PI*getRadius()*getRadius()*getLength(); //底面积*高
        //return findArea()*getLength();    //错误的
    }


    //构造器
    public Cylinder(){
        length=1;
    }

    //求表面积
    @Override
    public double findArea() {
        return Math.PI*getRadius()*getRadius()*2+
        2*Math.PI*getRadius()*getLength();

    }
}

【CylinderTest.java】

package yuyi03;

/**
 * ClassName: CylinderTest
 * Package: yuyi06
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/10/31 0031 10:29
 */
public class CylinderTest {
    public static void main(String[] args) {
        Cylinder cy=new Cylinder();
        cy.setRadius(2.3);
        cy.setLength(1.4);
        System.out.println("圆柱的体积为: "+cy.findVolume());
        System.out.println("圆柱的表面积为: "+cy.findArea());
    }
}

🤺代码

【Cylinder.java】

package yuyi03;

public class Cylinder extends Circle {
    //...

    //求圆柱的体积
    public double findVolume(){
        //return Math.PI*getRadius()*getRadius()*getLength(); //底面积*高  正确的
        //return findArea()*getLength();    //错误的
        return super.findArea()*getLength();
    }

    //...

    //求表面积
    @Override
    public double findArea() {
        return Math.PI*getRadius()*getRadius()*2+
        2*Math.PI*getRadius()*getLength();

    }
}

【Circle.java】

package yuyi03;

public class Circle {
    //...

    //求圆的面积
    public double findArea(){
        return Math.PI*radius*radius;
    }
}

【CylinderTest.java】

package yuyi03;

public class CylinderTest {
    public static void main(String[] args) {
        Cylinder cy=new Cylinder();
        cy.setRadius(2.3);
        cy.setLength(1.4);
        System.out.println("圆柱的体积为: "+cy.findVolume());
        System.out.println("圆柱的表面积为: "+cy.findArea());
    }
}

👻输出结果

image.png

3、练习3

🌋题目描述

①写一个名为Account的类模拟账户。该类的属性和方法如下图所示。

image.png

该类包括的属性:账号id,余额balance,年利率annualInterestRate;

包含的方法:访问器方法(getter和setter方法),返回月利率的方法getMonthlyInterest(),取款方法withdraw(),存款方法deposit()。

写一个用户程序测试Account类。在用户程序中,创建一个账号为1122、余额为20000、年利率4.5%的Account对象。

使用withdraw方法提款30000元,并打印余额。

再使用withdraw方法提款2500元,使用deposit方法存款3000元,然后打印余额和月利率。

提示:在提款方法withdraw中,需要判断用户余额是否能够满足提款数额的要求,如果不能,应给出提示。

运行结果如图所示。

image.png

②创建Account类的一个子类CheckAccount代表可透支的账户,该账户中定义一个属性overdraft代表可透支限额。

在CheckAccount类中重写withdraw方法,其算法如下:

————————————————————————————————————————

如果(取款金额<账户余额),

可直接取款

如果(取款金额>账户余额),

计算需要透支的额度

判断可透支额overdraft是否足够支付本次透支需要,如果可以

将账户余额修改为0,冲减可透支金额

如果不可以

提示用户超过可透支额的限额

————————————————————————————————————————

要求:写一个用户程序测试CheckAccount类。

在用户程序中,创建一个账号为1122、余额为20000、年利率4.5%,可透支限额为5000元的CheckAccount对象。

使用withdraw方法提款5000元,并打印账户余额和可透支额。

再使用withdraw方法提款18000元,并打印账户余额和可透支额。

再使用withdraw方法提款3000元,并打印账户余额和可透支额。

提示:

(1)子类CheckAccount的构造方法需要将从父类继承的3个属性和子类自己的属性全部初始化。

(2)父类Account的属性balance被设置为private,但在子类CheckAccount的withdraw方法中需要修改它的值,因此应修改父类的balance属性,定义其为protected。

运行结果如下图所示。

image.png


🤺代码①

【Account.java】

package yuyi04;

/**
 * ClassName: Account
 * Package: yuyi04
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/11/4 0004 8:29
 */
public class Account {
    //属性
    private int id; //账户
    private double balance; //余额
    private double annualInterestRate;  //年利率

    //构造器
    public Account(int id,double balance,double annualInterestRate){
        //super();
        this.id=id;
        this.balance=balance;
        this.annualInterestRate=annualInterestRate;
    }

    //方法
    public void setId(int id) {
        this.id = id;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }

    public int getId() {
        return id;
    }

    public double getBalance() {
        return balance;
    }

    public void setAnnualInterestRate(double annualInterestRate) {
        this.annualInterestRate = annualInterestRate;
    }

    /**
     * 获取月利率
     * @return
     */
    public double getMonthlyInterest(){
        return annualInterestRate / 12;
    }

    /**
     * 取钱曹操作
     * @param amount  要取的钱数
     */
    public void withdraw(double amount){
        if(balance>=amount){
            balance-=amount;
        }else{
            System.out.println("余额不足!");
        }
    }

    /**
     * 存钱操作
     * @param amount 要存的额度
     */
    public void deposit(double amount){
        if(amount>0){
            balance+=amount;
        }
    }
}

【AccountTest.java】

package yuyi04;

/**
 * ClassName: AccountTest
 * Package: yuyi04
 * Description:
 * 写一个用户程序测试Account类。在用户程序中,创建一个账号为1122、余额为20000、年利率4.5%的Account对象。
 *   使用withdraw方法提款30000元,并打印余额。
 *   再使用withdraw方法提款2500元,使用deposit方法存款3000元,然后打印余额和月利率。
 * @Author 雨翼轻尘
 * @Create 2023/11/4 0004 10:46
 */
public class AccountTest {
    public static void main(String[] args) {
        Account acct=new Account(1122,20000,0.045);
        acct.withdraw(30000);
        System.out.println("您的账户余额为:"+acct.getBalance());
        acct.withdraw(2500);
        acct.deposit(3000);
        System.out.println("您的账户余额为: "+acct.getBalance());
        System.out.println("月利率为: "+acct.getMonthlyInterest());
    }
}

👻运行结果①

image.png


🤺代码②

【Account.java】

package yuyi04;

/**
 * ClassName: Account
 * Package: yuyi04
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/11/4 0004 8:29
 */
public class Account {
    //属性
    private int id; //账户
    private double balance; //余额
    private double annualInterestRate;  //年利率

    //构造器
    public Account(int id,double balance,double annualInterestRate){
        //super();
        this.id=id;
        this.balance=balance;
        this.annualInterestRate=annualInterestRate;
    }

    //方法
    public void setId(int id) {
        this.id = id;
    }

    /*public void setBalance(double balance) {
        this.balance = balance;
    }*/

    public int getId() {
        return id;
    }

    public double getBalance() {
        return balance;
    }

    public void setAnnualInterestRate(double annualInterestRate) {
        this.annualInterestRate = annualInterestRate;
    }

    /**
     * 获取月利率
     * @return
     */
    public double getMonthlyInterest(){
        return annualInterestRate / 12;
    }

    /**
     * 取钱曹操作
     * @param amount  要取的钱数
     */
    public void withdraw(double amount){
        if(balance>=amount){
            balance-=amount;
        }else{
            System.out.println("余额不足!");
        }
    }

    /**
     * 存钱操作
     * @param amount 要存的额度
     */
    public void deposit(double amount){
        if(amount>0){
            balance+=amount;
        }
    }
}

【CheckAccount.java】

package yuyi04;

/**
 * ClassName: CheckAccount
 * Package: yuyi04
 * Description:
 *  创建Account类的一个子类CheckAccount代表可透支的账户,该账户中定义一个属性overdraft代表可透支限额。
 * @Author 雨翼轻尘
 * @Create 2023/11/4 0004 14:51
 */
public class CheckAccount extends Account{
    //属性
    private double overdraft;   //可透支限额

    //方法
    public double getOverdraft() {
        return overdraft;
    }

    public void setOverdraft(double overdraft) {
        this.overdraft = overdraft;
    }


    //重写withdraw方法
    /**
     * 针对于可透支的账户的取钱操作
     * @param amount  要取的钱数
     */
    public void withdraw(double amount){
        if(getBalance()>=amount){
            //错误的:(左右结果都是一个值,何来赋值一说)
            //getBalance()=getBalance()-amount;

            //正确的
            super.withdraw(amount); //super别去掉了,这里调用的是父类的withdraw方法
        } else if (getBalance()+overdraft>=amount) {
            overdraft-=amount-getBalance(); //可透支的限额剩余量
            super.withdraw(getBalance());   //把原本账户的钱取光
        }else{
            System.out.println("超过可透支限额");
        }
    }


    //构造器
    public CheckAccount(int id,double balance,double annualInterestRate){
        super(id,balance,annualInterestRate);
    }

    public CheckAccount(int id,double balance,double annualInterestRate,double overdraft){
        super(id,balance,annualInterestRate);
        this.overdraft=overdraft;
    }
}

【CheckAccountTest.java】

package yuyi04;

/**
 * ClassName: CheckAccountTest
 * Package: yuyi04
 * Description:
 *  要求:写一个用户程序测试CheckAccount类。
 *  在用户程序中,创建一个账号为1122、余额为20000、年利率4.5%,可透支限额为5000元的CheckAccount对象。
 *
 *  使用withdraw方法提款5000元,并打印账户余额和可透支额。
 *  再使用withdraw方法提款18000元,并打印账户余额和可透支额。
 *  再使用withdraw方法提款3000元,并打印账户余额和可透支额。
 *
 * @Author 雨翼轻尘
 * @Create 2023/11/4 0004 22:05
 */
public class CheckAccountTest {
    public static void main(String[] args) {
        CheckAccount checkAccount=new CheckAccount(1122,20000,0.045,5000);

        checkAccount.withdraw(5000);
        System.out.println("您的账户余额为: "+checkAccount.getBalance());
        System.out.println("您的可透支额为: "+checkAccount.getOverdraft());

        checkAccount.withdraw(18000);
        System.out.println("您的账户余额为: "+checkAccount.getBalance());
        System.out.println("您的可透支额为: "+checkAccount.getOverdraft());

        checkAccount.withdraw(3000);
        System.out.println("您的账户余额为: "+checkAccount.getBalance());
        System.out.println("您的可透支额为: "+checkAccount.getOverdraft());
    }
}

👻输出结果

image.png

⚡注意

【注意一】

当我们写完第一问的时候,第二问写CHeckAccount继承于Account,就会报错。

如下:

image.png

这是为哈呢?

在声明一个类没有显示写构造器的时候,会默认有一个空参的构造器。任何一个构造器的首行,要么写this(形参列表),要么是super(形参列表)。若现在构造器也没有写,那就是默认super()。

而现在父类Account里面根本没有提供空参构造器,所以会报错。

image.png

有两种解决办法。

第一种是给父类提供空参的构造器:

package yuyi04;

public class Account {
    //...
    //构造器
    //空参构造器
	public Account(){
        
    }
    
    public Account(int id,double balance,double annualInterestRate){
        //super();
        this.id=id;
        this.balance=balance;
        this.annualInterestRate=annualInterestRate;
    }
}

第二种可以直接调用有参的构造器:

image.png


【注意二】

CheckAccount类里面重写的withdraw方法。

package yuyi04;

public class CheckAccount extends Account{
    //...
    //重写withdraw方法
    /**
     * 针对于可透支的账户的取钱操作
     * @param amount  要取的钱数
     */
    public void withdraw(double amount){
        if(getBalance()>=amount){
            //错误的:(左右结果都是一个值,何来赋值一说)
            //getBalance()=getBalance()-amount;

            //正确的
            super.withdraw(amount); //super别去掉了,这里调用的是父类的withdraw方法
        } else if (getBalance()+overdraft>=amount) {
            overdraft-=amount-getBalance(); //可透支的限额剩余量
            super.withdraw(getBalance());   //把原本账户的钱取光
        }else{
            System.out.println("超过可透支限额");
        }
    }
}

这里很容易弄混:

image.png

【小Tips】

按住Ctrl+Shift+向上方向键:本行与上一行互换

【Super的使用】

①子类重写的方法里面,调用父类被重写的方法:

image.png

image.png

(6)面试题

1、第一题

如下代码输出结果是多少?

package com.atguigu05._super.interview;

/**
 * 判断运行结果
 *
 * @author 雨翼轻尘
 * @create 2023/11/5
 */
public class Interview01 {

    public static void main(String[] args) {
        new A(new B());
    }
}

class A {
    public A() {
        System.out.println("A");
    }

    public A(B b) {
        this();
        System.out.println("AB");
    }
}

class B {
   public B() {
       System.out.println("B");
   }
}

最终输出结果是:

image.png

分析一下,看图:

image.png

2、第二题

如下代码输出结果是多少?

package com.atguigu05._super.interview;

/**
 * 判断运行结果
 *
 * @author 雨翼轻尘
 * @create 2023/11/5
 */
public class Interview01 {

    public static void main(String[] args) {
        new A(new B());
    }
}

class A {
    public A() {
        System.out.println("A");
    }

    public A(B b) {
        this();
        System.out.println("AB");
    }
}

class B extends A{
    public B() {
        System.out.println("B");
    }
}

最终输出结果是:

image.png

分析一下,看图:

image.png

3、第三题

如下代码输出结果是多少?

package yuyi05;

/**
 * @author 雨翼轻尘
 * @create 2023/11/5
 */
public class Interview02{
        public static void main(String[] args) {
            Father f = new Father();
            Son s = new Son();
            System.out.println(f.getInfo());//atyuyi
            System.out.println(s.getInfo()); //atyuyi
            s.test();//atyuyi atyuyi
            System.out.println("-----------------");
            s.setInfo("轻尘");
            System.out.println(f.getInfo());//atyuyi
            System.out.println(s.getInfo());//轻尘
            s.test(); //轻尘 轻尘
    }
}
class Father{
    private String info = "atyuyi";
    public void setInfo(String info){
        this.info = info;
    }
    public String getInfo(){
        return info;
    }
}
class Son extends Father{
    private String info = "雨翼轻尘";
    public void test(){
        System.out.println(this.getInfo());
        System.out.println(super.getInfo());
    }
}

最终输出结果是:

image.png

分析一下,看图:


image.png


image.png


image.png


image.png

4、第四题

如下代码输出结果是多少?

package yuyi05;

/**
 * @author 雨翼轻尘
 * @create 2023/11/5
 */
public class Interview02{
    public static void main(String[] args) {
        Father f = new Father();
        Son s = new Son();
        System.out.println(f.getInfo());//返回最近的info,即本类的"atyuyi"
        System.out.println(s.getInfo()); //返回最近的info,即本类的"雨翼轻尘"
        s.test();//“雨翼轻尘” atyuyi
        System.out.println("-----------------");
        s.setInfo("轻尘");
        System.out.println(f.getInfo());//atyuyi
        System.out.println(s.getInfo());//雨翼轻尘
        s.test(); //雨翼轻尘 轻尘
    }
}
class Father{
    private String info = "atyuyi";
    public void setInfo(String info){
        this.info = info;
    }
    public String getInfo(){
        return info;
    }
}
class Son extends Father{
    private String info = "雨翼轻尘";
    public void test(){
        System.out.println(this.getInfo());
        System.out.println(super.getInfo());
    }
    //重写
    public String getInfo(){
        return info;
    }
}

最终输出结果是:

image.png

分析一下,看图:


image.png


image.png

二、子类对象实例化全过程

(1)介绍

调用子类构造器去创建对象的时候,会直接或间接地调用父类地构造器。

整个过程其实可以理解为关于某个类的对象,在创建这个对象的过程当中是什么样的场景。
image.png

Dog dog = new Dog("小花","小红");

image.png

(2)举例

代码举例:

class Creature{ //生物类
    //声明属性、方法、构造器
}

class Animal extends Creature{ //动物类

}

class Dog extends Animal{ //狗类

}

class DogTest{
    public static void main(String[] args){
        //子类对象DOg在实例化的过程当中整个过程是怎样的呢?
        Dog dog = new Dog();	//创建DOg的对象中,涉及到父类、父类的父类加载的过程?

        //通过dog调用属性、方法,只要是在Animal或Creature里面定义的属性、方法
        dog.xxx();
        
        dog.yyy = ...;
    }
}

image.png

  1. 从结果的角度来看:体现为类的继承性

当我们创建子类对象后,子类对象就获取了其父类(所有父类,包括直接父类、间接父类)中声明的所有的属性和方法,在权限允许的情况下,可以直接调用。

  1. 从过程的角度来看:(继承性它在内存层面是怎么保证它是能够调用的)

当我们通过子类的构造器创建对象时,子类的构造器一定会直接或间接地调用到其父类的构造器,而其父类的构造器同样会直接或间接地调用到其父类的构造器,…,直到调用了Object类中的构造器为止。

正因为我们调用过子类所有的父类的构造器,所以我们就会将父类中声明的属性、方法加载到内存中,供子类的对象使用

问题:在创建子类对象的过程中,一定会调用父类中的构造器吗? yes!
先有父类的加载,才有子类的加载

  1. 问题:创建子类的对象时,内存中到底有几个对象?
    就只有一个对象(只new了一次)!即为当前new后面构造器对应的类的对象。

①造对象–>new

②构造器–>初始化<init>


叨叨:
这一篇写累死我了,战线拉得很长,不过值得,有任何错误的地方欢迎指正

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

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

相关文章

解决gtihub访问不到的

解决gtihub访问不到的 小编一开始也是找不到git但是通过查询资料&#xff0c;最终也是找到了解决方式 据说git的ip地址通常会变化的&#xff0c;可以通过地址查询网站查询到git当前的ip https://sites.ipaddress.com/github.com/在输入框中github.com&#xff0c;然后搜索 在…

【大数据】常见的数据抽取方法

常见的数据抽取方法 1.基于查询式的数据抽取1.1 触发器方式&#xff08;又称快照式&#xff09;1.2 增量字段方式1.3 时间戳方式1.4 全表删除插入方式 2.基于日志的数据抽取 数据抽取 是指从源数据源系统抽取需要的数据。实际应用中&#xff0c;数据源较多采用的是关系数据库。…

【计算机网络笔记】传输层——拥塞控制原理与解决方法

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

爬虫项目-爬取股吧(东方财富)评论

1.最近帮别人爬取了东方财富股吧的帖子和评论&#xff0c;网址如下&#xff1a;http://mguba.eastmoney.com/mguba/list/zssh000300 2.爬取字段如下所示&#xff1a; 3.爬虫的大致思路如下&#xff1a;客户要求爬取评论数大于5的帖子&#xff0c;首先获取帖子链接&#xff0c…

淘宝预定商品收不到尾款通知 - 解决方案

问题 用户在使用淘宝购买预定商品后&#xff0c;待补尾款时&#xff0c;无法收到尾款通知&#xff0c;从而导致错过补齐尾款无法购买预定商品&#xff0c;下文介绍解决方案。 解决方案 进入淘宝后&#xff0c;购买预定商品时&#xff0c;在提交订单页面时&#xff0c;取消勾…

雨水收集设施模块收集和利用雨水成为解决城市供水矛盾的途径之一

雨水收集设施模块是一种高效、环保的雨水收集和利用系统&#xff0c;它通过收集和利用雨水来解决城市供水矛盾。 雨水收集设施模块主要由雨水收集器、储水池、过滤器和水泵等组成。当雨水流入雨水收集器时&#xff0c;经过过滤器的过滤&#xff0c;进入储水池中储存。当需要用…

算法模板之单调栈解密 | 图文详解

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;算法模板、数据结构 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. ⛳️单调栈讲解1.1 &#x1f514;单调栈的定义1.2 &#x1f514;如何维护一个单…

【错误解决方案】ModuleNotFoundError: No module named ‘selenium‘

1. 错误提示 ModuleNotFoundError: No module named selenium&#xff0c;这意味着你试图导入一个名为 selenium 的模块&#xff0c;但Python找不到这个模块 2. 解决方案 安装缺失的模块: 如果你确定模块名称正确但仍然收到这个错误&#xff0c;那么可能是你没有安装这个模块…

二维码智慧门牌管理系统升级:详细展示门牌信息,让你的生活更便捷

文章目录 前言一、旧问题的解决与升级特点二、满足信息平台要求 前言 随着科技的不断发展&#xff0c;我们的生活正日益智能化。其中&#xff0c;二维码智慧门牌管理系统成为了智能生活的一个重要组成部分。最近&#xff0c;这一系统经过新的升级&#xff0c;为我们的生活带来…

HTML5+CSS3实现小米商城(课程设计版)

前言 这个小米商城用到了htmlcssjs&#xff0c;内容是今年6月份的。 结构相对简单&#xff0c;比较容易理解。 如果想要纯htmlcss实现的小米商城&#xff0c;可以看我的这个作品 HTMLCSS实现小米商城 如果需要其他网页作品了&#xff0c;可以看主页其他作品。 HTMLCSS实现华为…

文档QA综述:关于多页文档,多模态,检索增强最新的进展

关于Document&#xff0c;Multimodal&#xff0c;RAG最新的进展 一&#xff1a;PDFTriage 一&#xff1a;PDFTriage 题目: PDFTriage: Question Answering over Long, Structured Documents 机构&#xff1a;斯坦福大学&#xff0c;Adobe Research 论文: https://arxiv.org/pd…

MAC苹果电脑系统清理垃圾软件CleanMyMac4.15

如今电脑成为大多数人工作的工具&#xff0c;使用得越久就越需要清理垃圾软件。系统垃圾、废纸娄垃圾、大型和旧文件这些通常都占用了我们的电脑几G的空间。 想要清除不必要的垃圾文件&#xff0c;可以使用mac卸载软件CleanMyMac X&#xff0c;这款清理垃圾软件可以智能扫描Ma…

探索Kosmos-2模型的神奇功能

Kosmos-2是一个多模态大语言模型&#xff0c;它可以理解和生成包含图像和文本的内容。它的特点是能够将文本中的指代表达式&#xff08;如“这个”、“那个”等&#xff09;与图像中的物体对应起来&#xff0c;实现局部理解和交互。如果你想使用Kosmos-2模型&#xff0c;你可以…

《人工智能算法图解》书籍推荐

书籍介绍 今天&#xff0c;人工智能在我们的生活中随处可见。它能推送我们喜欢的电视节目&#xff0c;帮助我们诊断疑难杂症&#xff0c;还能向我们推荐商品。因此&#xff0c;让我们掌握人工智能的核心算法&#xff0c;拥抱日新月异的智能世界吧。 与那些充斥着公式和术语的教…

超详细的wheel轮子下载和.whl安装

wheel安装 pip安装失败问题 基于Anaconda进行 pip install ,报如下 但基于此路径下安装.whl文件时候&#xff0c;会报如下 通过在可借鉴的博客上查找相关原因&#xff0c;发现原来是因为版本没有匹配的问题&#xff0c;基于此问题以及博客中的解决方案&#xff0c;进行亲测…

CDR2024免费版服装设计工具

cdr是CorelDRAW的简称&#xff0c;一款专注排版和矢量图形编辑的平面设计软件。这款软件的设计界面精微细致、简洁易懂。功能尤其强大&#xff0c;图标设计&#xff0c;印刷排版&#xff0c;服装设计等都可以胜任。还有多种模板使得设计相当的轻松&#xff0c;今天简单介绍一下…

ACTIVE_MQ学习

ActiveMq学习①___入门概述https://blog.csdn.net/qq_45905724/article/details/131796502 ActiveMq学习②__安装与控制台https://blog.csdn.net/qq_45905724/article/details/133893214 ActiveMq学习③___Java编码实现ActiveMQ通讯https://blog.csdn.net/qq_45905724/articl…

【漏洞复现】weblogic-CVE-2018-2894-任意文件上传漏洞复现

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 漏洞复现WebShell 复现环境&#xff1a;Vulhub 访问 http://192.168.80.141:7001/console/&#xff0c;即可看到后台登录页面 执行sudo docker-compose logs | grep password可…

基于nodejs+vue贝佳月子会所服务平台系统- 计算机毕业设计

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

CleanMyMac软件4.15免费苹果电脑文件清理工具

mac系统进行文件清理&#xff0c;一般是直接将文件拖动入“废纸篓”回收站中&#xff0c;然后通过清理回收站&#xff0c;就完成了一次文件清理的操作&#xff0c;但是这么做并无法保证文件被彻底删除了&#xff0c;有些文件通过一些安全恢复手段依旧是可以恢复的&#xff0c;那…