Java学习55-super关键字的使用

news2024/11/25 14:45:13

1.举例1:子类继承父类以后,对父类方法进行了重写,那么在子类中,是否还可以对父类中被重写的方法进行调用?
可以!
举例2:子类继承父类以后,发现子类和父类中定义了同名的属性,是否可以在子类中区分两个同名的属性?(比如子类父类都有叫做id的属性,调用时如何正确区分?)
当然可以,用super(详见-代码举例1)。

2.super的理解: 父类的

  1. super可以调用的结构:属性,方法,构造器
    具体的:
    3.1 super调用属性,方法
    子类继承父类之后,我们就可以在子类的方法或构造器中,调用父类中声明的属性或方法(满足封装性的前提下,因为没有权限调不成),调用时,需要使用"super."的结构,表示调用父类的属性或方法。

一般情况下,可以考虑省略super.结构,但是,如果出现了子类重写父类的方法或子父类中出现了同名的属性时,则必须使用super.声明,显示调用父类被重写的方法 或 父类中声明的同名属性。

3.2 super调用构造器

  1. 子类继承父类时,不会继承父类的构造器,只能通过super(形参列表)的方式调用父类指定的构造器。
  1. 规定super形参列表,必须声明在构造器的首行。
  1. 前面讲过,构造器的首行可以使用this(形参列表),调用本类中重载的构造器。 结合上面2得到结论,在构造器的首行,this和super只能二选一。
  1. 如果子类构造器的首行既没有使用this(形参列表)也没有调用super(形参列表),则此类构造器默认调用super(),即父类中空参的构造器。参考代码举例4.
  1. 由3&4得到:子类的任何一个构造器中,要么会调用本类中重载的构造器,要么会调用父类的构造器,只能是这两种情况之一。
    换言之,- 1. 子类构造器的首行,程序员自己写了调用this()那就强制调用了this(),系统不会再默认调用super()了;- 2. 子类构造器的首行,程序员自己写了调用super()那就按命令调用super(),系统不会再默认首行插入super()调用命令了; - 3. 子类构造器的首行,程序员啥也没写。系统默认首行插入super()调用命令,系统会强制调用super();- 4. this(),super()这两个调用,写在子类构造器的首行,只能出现一个。参考代码举例5
  1. 由5得到:一个类中声明有n个构造器,最多有n-1个构造器中使用了this(形参列表),则剩下的那个一定使用super(形参列表)。(可以是程序员自己写的super()也可以是系统默认插入的super())子类构造器们必须有至少一个去调用父类super,不然子类构造器们全都是this(),那子类构造器就一起形成一个闭环导致死循环啦!
    我们在通过子类的构造器创建对象时,一定在调用子类构造器的过程中,直接或间接的调用到父类的构造器,也正因为调用过父类的构造器,我们才会将父类中声明的属性或方法加载道内存中,供子类对象使用。

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

代码举例1,当子类Student调用Student定义的方法show(),方法里又调用了父类super.eat()方法,那么将会输出父类eat()方法:“人吃饭”。

代码:父类Person类,它有一个子类叫做Student

package this_super.supertest;

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

    public Person() {
    }

    public Person(String n) {
        this.name = n;
        this.eat();
    }

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


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

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

子类Student

package this_super.supertest;

public class Student extends Person{
    String school;

    public void study() {
        System.out.println("学生学习");
    }
    //对Person中已有的eat方法重写
    public void eat(){
        System.out.println("学生餐");
    }

    //对Person中已有的sleep方法重写
    public void sleep(){
        System.out.println("学生睡觉9小时保证时长");
    }

    public void show(){
        eat();//省略了this,和下面的this.eat()功能一样。
        this.eat();
        super.eat();
    }

}

StudentTest测试代码

package this_super.supertest;

public class StudentTest {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.eat();//调用Student定义的方法eat(),输出“学生餐”
        s1.sleep();//调用Student定义的方法sleep(),输出“学生睡觉9小时保证时长”

        System.out.println("---------->");
        s1.show();//调用Student定义的方法show(),里面调用了super.eat()方法,将会输出父类eat()方法:"人吃饭"


    }
}

运行结果:

学生餐
学生睡觉9小时保证时长
---------->
学生餐
学生餐
人吃饭

Process finished with exit code 0

代码举例2
父类Person类其中包含id为身份证号默认值10086,它有一个子类叫做Student包含id为学生号默认值1000,输出这两个id。

Person.java

package this_super.supertest;



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


    public Person() {
    }

    public Person(String n) {
        this.name = n;
        this.eat();

    }

    public Person(String name, String email) {
        this.name = name;

    }


    public void eat(){
        System.out.println("人吃饭");

    }

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


Student.java

package this_super.supertest;

public class Student extends Person{
    String school;
    int id=1000;//学号
    public void study() {
        System.out.println("学生学习");
    }


    //对Person中已有的eat方法重写
    public void eat(){
        System.out.println("学生餐");
    }

    //对Person中已有的sleep方法重写
    public void sleep(){
        System.out.println("学生睡觉9小时保证时长");
    }

    public void show1(){
        eat();//省略了this,和下面的this.eat()功能一样。
        this.eat();
        super.eat();
    }

    public void show2(){
        System.out.println("student id = "+this.id);//1000
        System.out.println("Person id = "+super.id);//person_id=10086
    }


}

StudentTest.java

package this_super.supertest;

public class StudentTest {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.eat();//调用Student定义的方法eat(),输出“学生餐”
        s1.sleep();//调用Student定义的方法sleep(),输出“学生睡觉9小时保证时长”

        System.out.println("---------->");
        s1.show2();

    }
}


输出结果:

学生餐
学生睡觉9小时保证时长
---------->
student id = 1000
Person id = 10086

代码举例3,当子类中并不存在这个对象,默认会向父类去寻找,找到即可输出。如果还是没有,会继续向上层搜索,最终所有文件都找不到,就会报错。
Person.java

package this_super.supertest;



public class Person{
    String name= "LISA";
    int age; //属性为age
    int id=10086;//身份证号


    public Person() {
    }

    public Person(String n) {
        this.name = n;
        this.eat();

    }

    public Person(String name, String email) {
        this.name = name;

    }


    public void eat(){
        System.out.println("人吃饭");

    }

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

Student.java

package this_super.supertest;

public class Student extends Person{
    String school;
    int id=1000;//学号
    public void study() {
        System.out.println("学生学习");
    }


    //对Person中已有的eat方法重写
    public void eat(){
        System.out.println("学生餐");
    }

    //对Person中已有的sleep方法重写
    public void sleep(){
        System.out.println("学生睡觉9小时保证时长");
    }

    public void show1(){
        eat();//省略了this,和下面的this.eat()功能一样。
        this.eat();
        super.eat();
    }

    public void show2(){
        System.out.println("student id = "+this.id);//1000
        System.out.println("Person id = "+super.id);//person_id=10086
    }

    public void show3(){
        System.out.println(name);//这里要求输出name其实要求输出的是this.name
        System.out.println(this.name);//本例Student文件没有定义name,所以this.name并不存在。于是向上一级求索,找到Person文件里的name对象,最终找到可输出的对象Person.name。
        // 如果Person文件里也没有name对象,那么会一层一层往上找,直到找到name对象为止。如果实在找不到,最后会报错。
        System.out.println(super.name);//Person.name 对于本例而言,这三行输出是一模一样的,都是最终找到了super.name也就是Person.name进行输出的。
    }
}


StudentTest.java

package this_super.supertest;

public class StudentTest {
    public static void main(String[] args) {
        Student s1 = new Student();
        System.out.println("---------->");
        s1.show3();

    }
}


输出结果:

---------->
LISA
LISA
LISA

Process finished with exit code 0

代码举例4
当Person父类拥有一个Student子类时,子类Student新建对象时会先去运行父类Person的空参constructor,然后再去运行子类Student的空参constructor。
//空参constructor表示Person()或者Student()的括号里面是空的,没有输入参数的。

Person.java

package this_super.supertest;



public class Person{
    String name= "LISA";
    int age; //属性为age
    int id=10086;//身份证号


    public Person() {
        System.out.println("Person() 父类空参处...");
    }

    public Person(String n) {
        this.name = n;
        this.eat();

    }

    public Person(String name, String email) {
        this.name = name;

    }

    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 this_super.supertest;

public class Student extends Person{
    String school;
    int id=1000;//学号

    //测试super调用父类的构造器

    public Student() {
        super();//this和super必须出现在首行,并且只能二选一
        System.out.println("Student()...子类空参处");
    }

    public Student(String name, int age) {
        super();
        System.out.println("Student()...子类有参处");
    }

}

StudentTest.java

package this_super.supertest;

public class StudentTest {
    public static void main(String[] args) {
        System.out.println("---------->");
        Student s2 = new Student();
        System.out.println("*****");
    }
}

会输出

---------->
Person() 父类空参处...
Student()...子类空参处
*****

现在修改Student.java文件,将其中的 //super();删除或注释掉,文件空参构造器应变为

  public Student() {
        System.out.println("Student()...子类空参处");
    }

Student.java文件应变为:

package this_super.supertest;

public class Student extends Person{
    String school;
    int id=1000;//学号

    public Student() {
        System.out.println("Student()...子类空参处");
    }

    public Student(String name, int age) {
        super();
        System.out.println("Student()...子类有参处");
    }

}


运行发现,结果输出并无变化

---------->
Person() 父类空参处...
Student()...子类空参处
*****

Process finished with exit code 0

以上程序运行可以看出,就算用户并不在子类构造器中明确写出,调用super(); 子类默认一定会去调用父类的空参构造器。

现在将StudentTest文件改写,再新增一新增一个Student对象s3,观察结果输出:

package this_super.supertest;

public class StudentTest {
    public static void main(String[] args) {
   

        System.out.println("---------->");



        Student s2 = new Student();
        System.out.println("*****");
        Student s3 = new Student();

    }
}


运行结果

---------->
Person() 父类空参处...
Student()...子类空参处
*****
Person() 父类空参处...
Student()...子类空参处

Process finished with exit code 0

以上运行可以发现,每新建一个Student object 就调用一次父类和子类的空参构造器,新建了两个Student object,实际调用父类和子类的空参构造器各两次。

系统默认在第一行添加的super()

代码举例5
当子类Student新建一个带参数的对象s3,新建这个对象时,系统会自动追溯到Student.java里面的有参构造器,(我们已经知道,在子类Student的无参构造器第一行,系统会隐藏着默认去调用父类Person的无参构造器,即在子类Student的无参构造器第一行,系统会在构造器第一行帮你偷偷写入super()😉,下面这个例子展示了类似的结论:在子类Student的有参构造器第一行,无论程序员写不写,系统会在第一行偷偷写入super(); 去默认调用父类Person无参构造器。

Person.java

package this_super.supertest;

public class Person{
    String name= "LISA";
    int age; //属性为age
    int id=10086;//身份证号


    public Person() {
        System.out.println("Person() 父类空参处...");
    }

    public Person(String n) {
        this.name = n;
        this.eat();

    }

    public Person(String name, String email) {
        this.name = name;
        System.out.println("Person() 父类有参name email处...");

    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("Person() 父类有参name age处...");
    }

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

}


Student.java

package this_super.supertest;

public class Student extends Person{
    String school;
    int id=1000;//学号
    public void study() {
        System.out.println("学生学习");
    }

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

    public Student(String name, int age) {
        //super();无论程序员写不写,系统默认这里会加这一句
        System.out.println("Student()...子类有参处");
    }

}


StudentTest.java

package this_super.supertest;

public class StudentTest {
    public static void main(String[] args) {
        System.out.println("---------->");
        Student s3 = new Student("lisa",22);

    }
}

运行结果

---------->
Person() 父类空参处...
Student()...子类有参处

Process finished with exit code 0

结论:可以观察到 尽管子类使用的是有参构造器,系统在有参构造器第一行默认添加的仍是空参super();

练习题目一:
修改下面Kids类中employeed()方法,当前运行时仅仅会输出一行星号;
目标:希望Kids中的该employeed()方法,先调用父类ManKInd的employeed()方法,然后再输出“but Kids should study and no job”

子类Kids.java

package this_super.Kids;

public class Kids extends Mankind {
    private int yearsOld;

    public Kids() {

    }

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

    public Kids(int sex, int salary, int yearsOld) {
        this.yearsOld = yearsOld;
        setSex(sex);
        setSalary(salary);
    }

    public int getYearsOld(){return yearsOld;}

    public void setYearsOld(int yearsOld) {
        this.yearsOld = yearsOld;
    }

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

    public void employeed(){
     
    }

}


父类Mankind.java

package this_super.Kids;

public class Mankind {
    private int sex;	//性别
    private int salary;	//薪资

    public void ManKind() {

    }

    public void ManKind(int sex, int salary) {
        this.sex = sex;
        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 if(salary!=0){
            System.out.println("job");
        }
    }

    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;
    }
}


KidsTest.java

package this_super.Kids;

public class KidsTest {

    public static void main(String[] args) {


        Kids kid = new Kids();

        System.out.println("*************");
        kid.employeed();

    }
}


当前KidsTest主程序运行后,系统会输出*************

按照题目要求,修改Kids.java文件,代码如下

package this_super.Kids;

public class Kids extends Mankind {
    private int yearsOld;

    public Kids() {

    }

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

    public Kids(int sex, int salary, int yearsOld) {
        this.yearsOld = yearsOld;
        setSex(sex);
        setSalary(salary);
    }

    public int getYearsOld(){return yearsOld;}

    public void setYearsOld(int yearsOld) {
        this.yearsOld = yearsOld;
    }

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

    public void employeed(){

        super.employeed();
        System.out.println("but Kids should study and no job");
    }

}


运行结果:

no job
but Kids should study and no job

Process finished with exit code 0

练习题目二:
在CylinderTest中创建Cylinder圆柱类的对象,设置圆柱的底面半径和高,并输出圆柱的体积。
注意在Cylinder()类中设计求表面积的方法findArea()和求体积的方法findVolume(),使用上super.
圆柱类为Circle类的子类。

在这里插入图片描述

Circle.java

package this_super.Cylinder;
import java.lang.Math;

public class Circle {
    double radius =1; //半径R


    public Circle() {

    }
    public Circle(double radius) {
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    public double findArea(double radius) {
        //计算圆的面积 PI*R^2

        System.out.println("findArea is "+ Math.PI *radius*radius);
        return Math.PI *radius*radius;
    }

}


Cylinder.java

package this_super.Cylinder;

public class Cylinder extends Circle {
    double length = 1;
    double radius = 1;

    public Cylinder() {

    }

    public Cylinder( double radius , double length) {
        this.length = length;
        this.radius = radius;
    }

    public double getLength() {
        return length;
    }

    public void setLength(double length) {
        this.length = length;
    }

    public double findVolume() {
        double radius = this.radius;
        double length = this.length;
        return super.findArea(radius)*length;
    }

}


CylinderTest.java

package this_super.Cylinder;

public class CylinderTest {

    public static void main(String[] args) {
        double radius=5;
        double length=3;

        //from calculator: 25×3.14×3 = 235.5

        Cylinder cy1 = new Cylinder(radius, length);

        System.out.println(cy1.findVolume());
    }



}


运行结果

findArea is 78.53981633974483
235.61944901923448

Process finished with exit code 0

练习题目三:
写一个名为Account的类模拟账户。该类的属性和方法如下图所示。
该类包括的属性,账号id余额balance年利率annualInterestRate
包含的方法:访问器方法(getter和setter方法),返回月利率的方法getMonthlyInterest(),取款方法withdraw

写一个用户测试Account类,在用户程序中,创建一个账号为1122,余额为20000,年利率为4.5%的Account对象。
使用withdraw方法提款30000元,并打印余额。
再使用withdraw方法提款2500元,使用deposit方法存款3000元,然后打印余额和月利率

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

Account.java

package this_super.Accounting;

public class Account {
    private int id;
    private double balance;
    double annualInterestRate;

    public Account() {
    }

    public int getId() {
        return this.id;
    }

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

    public double getBalance() {
        return this.balance;
    }

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

    public double getAnnualInterestRate() {
        return this.annualInterestRate;
    }

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

    public double getMonthlyInterest() {
        return this.annualInterestRate/12;
    }

    public double withdraw(double req_amt) {

        double temp = this.balance-req_amt;
        if(temp >0){
            System.out.println("取款成功");
            setBalance(temp);
            return temp;
        }
        else {
            System.out.println("取款失败,余额不足");
            return -1;
        }

    }

    public double deposit(double req_amt) {
        double balance=this.balance+req_amt;
        setBalance(balance);
        return balance;
    }

}


AccountTest.java

package this_super.Accounting;

public class AccountTest {
    public static void main(String[] args) {

        Account a1 = new Account();
        a1.setId(1122);
        a1.setBalance(20000);
        a1.setAnnualInterestRate(0.045);

        a1.getBalance();
        a1.withdraw(30000);
        System.out.println("当前账户余额: "+a1.getBalance());//

        System.out.println("申请取款2500元: 最新balance为: "+a1.withdraw(2500));//17500
        System.out.println("申请存储3000元,最新balance为: "+a1.deposit(3000));//20500

        System.out.print("最新余额为:");
        a1.getBalance();
        System.out.println("月利率为"+a1.getMonthlyInterest());//0.00375
    }
}


运行结果

取款失败,余额不足
当前账户余额: 20000.0
取款成功
申请取款2500元: 最新balance为: 17500.0
申请存储3000元,最新balance为: 20500.0
最新余额为:月利率为0.00375

Process finished with exit code 0

练习题目四:在练习题目三的基础上,创建Account类中的一个子类CheckAccount代表可透支的账户,该账户中定义一个属性overdraft代表可透支限额,在CheckAccount类中重写withdraw方法,其算法如下:

如果(取款金额<账户余额) 可直接取款
如果(取款金额>账户余额) 计算要透支的额度

判断可透支额度overdraft是否足够支付本次透支需要,如果可以将账户余额修改为0,冲减可透支金额
如果不可以,提示用户超过可透支的限额

测试:要求写一个用户程序测试CheckAccount类。
在用户程序中,创建一个账号为1122,余额为2000,年利率为4.5%,可透支限额为5000元的CheckAccount对象。
使用withdraw方法提款5000元,打印账户余额和可透支额。
再使用withdraw方法提款18000元,打印账户余额和可透支额。
再使用withdraw方法提款2000元,打印账户余额和可透支额。

提示:子类CheckAccount的构造方法需要将父类继承的3个属性和子类自己的属性全部初始化。
父类Account的属性balance被设置为private,但在子类CheckAccount的withdraw方法中需要修改它的值

在这里插入图片描述

Account.java父类文件不变

package this_super.Accounting;

public class Account {
    private int id;
    private double balance;
    private double annualInterestRate;

    public Account() {
    }

    public Account(int id, double balance, double annualInterestRate) {
        this.id = id;
        this.balance = balance;
        this.annualInterestRate = annualInterestRate;
    }

    public int getId() {
        return this.id;
    }

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

    public double getBalance() {
        return this.balance;
    }

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

    public double getAnnualInterestRate() {
        return this.annualInterestRate;
    }

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

    public double getMonthlyInterest() {
        return this.annualInterestRate/12;
    }

    public double withdraw(double req_amt) {

        double temp = this.balance-req_amt;
        if(temp >0){
            System.out.println("取款成功");
            setBalance(temp);
            return temp;
        }
        else {
            System.out.println("取款失败,余额不足");
            return -1;
        }

    }

    public double deposit(double req_amt) {
        double balance=this.balance+req_amt;
        setBalance(balance);
        return balance;
    }

}


CheckAccount.java作为子类

package this_super.Accounting;

public class CheckAccount extends Account{

    private int id=0;
    private double balance=0;
    private double annualInterestRate=0;
    private double overdraft=0;

    public CheckAccount() {

    }

    @Override
    public void setId(int id) {
        super.setId(id);
    }

    @Override
    public void setAnnualInterestRate(double annualInterestRate) {
        super.setAnnualInterestRate(annualInterestRate);
    }

    @Override
    public int getId() {
        return super.getId();
    }

    @Override
    public double getBalance() {
        return super.getBalance();
    }

    @Override
    public double getAnnualInterestRate() {
        return super.getAnnualInterestRate();
    }


    public double getOverdraft() {
        return this.overdraft;
    }

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


    @Override
    public void setBalance(double balance) {
        super.setBalance(balance);
        //update client's balance, no overdraft
    }

    @Override
    public double withdraw(double req_amt) {
        double org_balance=this.getBalance();
        System.out.println("org_balance:"+org_balance);
        if(req_amt<=org_balance){
            System.out.println("余额可用,取款成功");
            this.setBalance(org_balance - req_amt);
            return org_balance - req_amt; //返回账户余额
        }
        else {
            if(org_balance + overdraft >= req_amt){
                System.out.println("余额不足,透支成功");
                this.setOverdraft(org_balance + overdraft - req_amt);
                this.setBalance(0);
                return 0; //返回账户余额
            }
            else {
                System.out.println("余额透支不足,取款失败");
                this.setBalance(org_balance);
                return org_balance; //返回账户余额
            }
        }


    }
}

测试文件

package this_super.Accounting;

public class TestCheckAccount {
    public static void main(String[] args) {
        //在用户程序中,创建一个账号为1122,余额为2000,年利率为4.5%,可透支限额为5000元的CheckAccount对象。

        CheckAccount ca1 = new CheckAccount();
        ca1.setId(1122);
        ca1.setBalance(2000);
        ca1.setAnnualInterestRate(0.045);
        ca1.setOverdraft(5000);



        System.out.println("----提款5000元------->");
        System.out.println("账户余额为: "+ca1.withdraw(5000));
        System.out.println("可透支余额为: "+ca1.getOverdraft());
        System.out.println("----提款18000元------->");
        System.out.println("账户余额为: "+ca1.withdraw(18000));
        System.out.println("可透支余额为: "+ca1.getOverdraft());
        System.out.println("----提款2000元------->");
        System.out.println("账户余额为: "+ca1.withdraw(2000));
        System.out.println("可透支余额为: "+ca1.getOverdraft());
    }
}

运行结果:

----提款5000元------->
org_balance:2000.0
余额不足,透支成功
账户余额为: 0.0
可透支余额为: 2000.0
----提款18000元------->
org_balance:0.0
余额透支不足,取款失败
账户余额为: 0.0
可透支余额为: 2000.0
----提款2000元------->
org_balance:0.0
余额不足,透支成功
账户余额为: 0.0
可透支余额为: 0.0

Process finished with exit code 0

课后练习:
请探讨下面程序的输出结果,并说明为什么

子类程序

package this_super.test01;

public class Son extends Father{
    private String info = "上学啦";
    public void test(){
        System.out.println(this.getInfo());
        System.out.println(super.getInfo());
    }
}


父类程序

package this_super.test01;

public class Father {
    private String info ="上班狗";
    public void setInfo(String info){
        this.info=info;
    }
    public String getInfo(){
        return info;
    }
}

主程序:

package this_super.test01;

public class question02 {
    public static void main(String[] args) {
        Father f = new Father();
        Son s = new Son();
        System.out.println(f.getInfo());//上班狗
        System.out.println(s.getInfo());//上班狗
        s.test();//上班狗 上班狗
        System.out.println("------->");
        s.setInfo("逛吃逛吃");
        System.out.println(f.getInfo());//上班狗
        // 这里优点绕,注意根据s子类改变的father父类的info,实际只会影响s自己调用父类getInfo方法时候的结果,
        // 本身father内部原来的info的数值并不会改变。


        System.out.println(s.getInfo());//逛吃逛吃
    }
}

运行结果

上班狗
上班狗
上班狗
上班狗
------->
上班狗
逛吃逛吃

Process finished with exit code 0

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

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

相关文章

示例:WPF中在没有MouseDoubleClick的控件中如何识别双击

一、目的&#xff1a;由于MouseDoubleClick控件是在Control中实现&#xff0c;那么在底层控件如Grid中想要类似功能如何实现&#xff0c;这里通过MouseDown的事MouseButtonEventArgs参数去实现 二、实现 定义Grid并注册Grid的MouseDown事件 <Grid Background"Transpa…

Android如何简单快速实现RecycleView的拖动重排序功能

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 要实现这个拖动重排序功能&#xff0c;主要是用到了RecycleView的ItemTouchHelper类 首先是定义一个接口 interface ItemTouchHelperAdapter …

哈尔滨等保测评如何办理

随着人们对网络安全的认识日益加深&#xff0c;越来越多的企业和组织开始重视网络安全等级保护工作。在哈尔滨地区&#xff0c;为了保证网络的安全&#xff0c;等保测评是保障网络安全的重要一环。本文对哈尔滨等保测评的流程、测评具体内容以及注意事项进行了详细地阐述。 一…

0X0-基于Sklearn的机器学习入门:聚类(上)

本节及后续章节将介绍深度学习中的几种聚类算法&#xff0c;所选方法都在Sklearn库中聚类模块有具体实现。本节为上篇&#xff0c;将介绍几种相对基础的聚类算法&#xff0c;包括K-均值算法和均值漂移算法。 目录 X.1 聚类概述 X.1.1 聚类的种类 X.1.2 Sklearn聚类子模块 …

纯css实现炫光流彩Button

正文 先看效果 实现思路 不仔细看的话还以为只需要通过animation与text-shadow、box-shadow、background-image就可以实现 仔细看的话会发现&#xff0c;其实按钮的颜色不是简单的渐变&#xff0c;而是从一侧颜色开始变化&#xff0c;渐渐的颜色蔓延到另一侧&#xff0c;之后…

【机器学习】第10章 聚类算法

一、概念 1.聚类 &#xff08;1&#xff09;是无监督学习&#xff0c;其实无监督学习就是无中生有&#xff0c;不给你标准答案&#xff08;标签啊啥的&#xff09;&#xff0c;然后让你自己来。 &#xff08;2&#xff09;聚类就是这样&#xff0c;让机器自己根据相似特征把相…

WACV2024 分割相关论文摘要小结速览67篇

WACV2024 分割相关论文摘要小结速览 Paper1 Robust Source-Free Domain Adaptation for Fundus Image Segmentation 摘要小结: 无监督域自适应&#xff08;UDA&#xff09;是一种学习技术&#xff0c;它将源域中从标记训练数据学习到的知识转移到只有未标记数据的目标域。这对…

星际航行概论分享

作者最近看到了一篇钱学森的著作《星际航行概论》 PDF格式下载&#xff1a; 星际航行概论.pdf: https://url83.ctfile.com/f/45573183-1272939884-48f07e?p7526 (访问密码: 7526)

【GlobalMapper精品教程】085:coverage格式转shp案例教程

文章目录 一、Coverage格式介绍二、globalmapper转换shp1. 加载coverage2. coverage转shp一、Coverage格式介绍 Coverage 是一种用于存储矢量数据的地理相关数据模型,它包含地理要素的空间(位置)数据和属性(描述性)数据。Coverage 使用一组要素类来表示地理要素。每个要素…

【包管理】Node.JS与Ptyhon安装

文章目录 Node.JSPtyhon Node.JS Node.js的安装通常包括以下几个步骤&#xff1a; 访问Node.js官网&#xff1a; 打开Node.js的官方网站&#xff08;如&#xff1a;https://nodejs.org/zh-cn/download/&#xff09;。 下载安装包&#xff1a; 根据你的操作系统选择对应的Node…

在Windows环境下设置定时任务(任务计划程序)(Python)

文章目录 前言一、准备执行的test.py文件二、准备test.bat批处理文件&#xff08;系统环境变量&#xff09;三、设置定时任务&#xff08;任务计划程序&#xff09; 前言 计划任务是系统的常见功能&#xff0c;利用任务计划功能&#xff0c;可以将任何脚本、程序或文档安排在某…

《Windows API每日一练》4.5 GDI映射模式

上一节讲述设置绘图模式时&#xff0c;包括设置背景模式、混合模式&#xff0c;还有一个就是映射模式。本节我们将详细讲述映射模式。 本节必须掌握的知识点&#xff1a; 设备坐标和逻辑坐标 视口和窗口 MM_TEXT映射模式 度量映射模式 自定义映射模式 第27练&#xff1a;GDI映…

Aigtek高压放大器在柔性爬行机器人驱动性能研究中的应用

实验名称&#xff1a;柔性爬行机器人的材料测试 研究方向&#xff1a;介电弹性体的最小能量结构是一种利用DE材料的电致变形与柔性框架形变相结合设计的新型柔性驱动器&#xff0c;所谓最小能量是指驱动器在平衡状态时整个系统的能量最小&#xff0c;当系统在外界的电压刺激下就…

归并排序个人见解

归并排序个人见解 思路实现代码实现题目 思路实现 归并排序属于分治算法&#xff0c;分治算法有三个步骤&#xff1a; 分&#xff1a;将问题划分为多个规模较小的子问题&#xff0c;这些子问题与原始问题相似。治&#xff1a;递归地解决这些子问题。如果子问题足够小&#xf…

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第42课-多人联机-实时互动

【WEB前端2024】3D智体编程&#xff1a;乔布斯3D纪念馆-第42课-多人联机-实时互动 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界…

【JVM结构、JVM参数、JVM垃圾回收】

JVM&#xff1a;Java Virtual Machine java虚拟机 虚拟机&#xff1a;使用软件技术模拟出与具有完整硬件系统功能、运行在一个隔离环境中的计算机系统。 JVM官方文档&#xff1a;https://docs.oracle.com/javase/specs/jvms/se8/html/index.html java 一些命令 javac 将文件编…

【Netty】nio处理acceptreadwrite事件

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;Netty ⛺️稳中求进&#xff0c;晒太阳 1.处理accept 1.1客户端代码 public class Client {public static void main(String[] args) {try (Socket socket new Socket("localhost…

秋招突击——6/16——复习{整理昨天的面试资料}——新作{删除链表倒数第n个节点}

文章目录 引言复习新作删除链表倒数第N个节点题目描述个人实现参考实现 总结 引言 主管面&#xff0c;面的很凄惨&#xff0c;不过无所谓了&#xff0c;我已经尽力了。上午都在整理的面经&#xff0c;没有复习算法&#xff0c;而且这两天要弄一下论文&#xff0c;二十号就要提…

Aspice介绍——测试流程

文章目录 ASPICE简介一、V字模型的示意二、测试领域2.1 SWE.6&#xff1a;软件合格性测试过程目的过程成果基本实践&#xff08;BP&#xff09; 2.2 SYS.4:系统集成和集成测试过程目的过程成果基本实践&#xff08;BP&#xff09; 2.3 SYS.5&#xff1a;系统合格性测试过程目的…

AI早班2024.6.18

先一步知道AI未来&#xff01; 全球AI新闻速递 1.绿米 AI 智能存在传感器 FP1E开售。 2.摩尔线程 师者AI&#xff1a;完成70亿参数教育AI大模型训练测试。 3.Google 在 AI 功能推出新功能&#xff0c;需要明确说明可能出错的地方。 4.北大、快手攻克复杂视频生成难题&#…