Java基础笔记三

一、this关键字

1.当用于成员方法中

有如下程序包含A类和B类,请说出A类中System.out.println的输出结果:

class B {
    int x = 100, y = 200;
    public void setX(int x) {
        x = x; 
    }
    public void setY(int y) {
        this.y = y;
    }
    public int getXYSum() {
        return x + y;
    }
}
public class A {
    public static void main(String[] args) {
        B b = new B();
        b.setX(-100);
        b.setY(-200);
        System.out.println("sum=" + b.getXYSum());
    }
}
点击查看答案
class B {
    int x = 100, y = 200;
    public void setX(int x) {
        x = x; //相当于将传入的一个值赋值给类变量x
    }
    public void setY(int y) {
        this.y = y;//相当于将传入的一个值赋值给对象的成员变量y
    }
    public int getXYSum() {
        return x + y;//两个变量都是从属于类的变量
    }
}
public class A {
    public static void main(String[] args) {
        B b = new B();
        b.setX(-100);  //将b的成员变量设置为-100
        b.setY(-200); //将B的类变量设置为-200
        System.out.println("sum=" + b.getXYSum());
        //打印出的值为-100
    }
}

只要坚持一个原则:
当this用于一个成员方法的内部,指代当前对象(当前对象指的是调用当前正在执行方法的那个对象)

或者有一个更加通俗的解释:
将this理解为对象的一个属性(成员变量),一个隐藏的属性。

public void setY(int y) {
     this.y = y;
    System.out.println(getType(this)); 
}

public static String getType(Object o) { //获取变量类型方法
    return o.getClass().toString(); //使用getClass()方法
}

再添加上面的代码将会打印出this的类型:
软件包名 + class B

2.当用于构造方法中

  1. 作用:
    如果有一个类带有几个构造方法,想复制其中一个构造方法的某些功能到另一个构造方法中,可以通过使用关键字this作为一个方法调用来达到这个目的。
  2. 例如:
public class Employee {
    private String name;
    private int salary;
    public Employee(String n, int s) {
        name = n;
        salary = s;
    }
    public Employee(String n) {
        this(n, 0);
    }
    public Employee() {
        this("Unknown ");
    }
}

其中含有三个构造函数,第二个构造函数中this相当于第一个构造函数,第三个构造函数相当于第二个构造函数;
3. 限制

  • 必须写在构造方法的第一行;
  • 可在同一类内调用其它的构造方法,不能调用其他类的构造方法;
  • 在每个构造方法中只能出现一次。

二、super关键字

1. super关键字主要有以下两种用途:

(1)操作被隐藏的成员变量和被覆盖的成员方法
(2)调用父类的构造方法

2. super关键字来访问父类的成员时注意:

(1)不能访问父类的private成员
(2)只能出现在子类的方法和构造方法中

3. super用于构造方法的规则

public class A {
    public A(String s) {
        //有参数的构造方法
    }
}

class B extends A {
    String name = "I am B";

    public B(String s) {
        super(s);//调用父类的有参构造方法
    }
}
  • 必须写在子类构造方法的第一行;
  • 从子类中调用父类的构造方法
  • 在每个构造方法中只能出现一次。
  • 如果父类中没有无参构造方法,必须在子类中使用super();

下面两种方式都是错误的:

image

image

4.super访问父类成员

当子类的成员变量或方法与父类同名时,可以使用 super 关键字来访问。如果子类重写了父类的某一个方法,即子类和父类有相同的方法定义,但是有不同的方法体,此时,我们可以通过 super 来调用父类里面的这个方法。

使用 super 访问父类中的成员与 this 关键字的使用相似,只不过它引用的是子类的父类

  1. super调用成员属性
    在下面的例子中,父类和子类都有一个成员变量 age。我们可以使用 super 关键字访问 Person 类中的 age 变量。
class Student extends Person {
    int age = 18;

    void display() {
        System.out.println("学生年龄:" + super.age);
    }
}

class Test {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.display();
    }
}

当super调用成员方法时,也是会调用父类的方法。

5.注意

this()和super()均不可以在static变量、static方法、static语句块中使用。

static关键字

在类中,使用 static 修饰符修饰的属性(成员变量)称为静态变量,也可以称为类变量,常量称为静态常量,方法称为静态方法或类方法,它们统称为静态成员,归整个类所有

静态成员不依赖于类的特定实例,被类的所有实例共享,就是说 static 修饰的方法或者变量不需要依赖于对象来进行访问,只要这个类被加载,Java 虚拟机就可以根据类名找到它们。

调用静态成员的语法形式如下:

类名.静态成员

  • static 修饰的成员变量和方法,从属于类。
  • 普通变量和方法从属于对象。
  • 静态方法不能调用非静态成员,编译会报错。

静态变量

类的成员变量可以分为以下两种:

  • 静态变量(或称为类变量),指被 static 修饰的成员变量。
  • 实例变量,指没有被 static 修饰的成员变量。

静态变量与实例变量的区别如下:

静态变量 实例变量
运行时 Java 虚拟机只为静态变量分配一次内存,在加载类的过程中完成静态变量的内存分配 Java 虚拟机就会为实例变量分配一次内存
类的内部 可以在任何方法内直接访问静态变量 可以在非静态方法中直接访问实例变量
其他类中 可以通过类名访问该类中的静态变量 需要通过类的实例对象进行访问

静态变量在类中的作用如下:

  • 静态变量可以被类的所有实例共享,因此静态变量可以作为实例之间的共享数据,增加实例之间的交互性。
  • 如果类的所有实例都包含一个相同的常量属性,则可以把这个属性定义为静态常量类型,从而节省内存空间。

静态方法

与成员变量类似,成员方法也可以分为以下两种:

  • 静态方法(或称为类方法),指被 static 修饰的成员方法。
  • 实例方法,指没有被 static 修饰的成员方法。

静态方法与实例方法的区别如下:
静态方法不需要通过它所属的类的任何实例就可以被调用,因此在静态方法中不能使用 this 关键字,也不能直接访问所属类的实例变量和实例方法,但是可以直接访问所属类的静态变量和静态方法。另外,和 this 关键字一样,super 关键字也与类的特定实例相关,所以在静态方法中也不能使用 super 关键字
在实例方法中可以直接访问所属类的静态变量、静态方法、实例变量和实例方法。

静态代码块

静态代码块指 Java 类中的 static{ } 代码块,主要用于初始化类,为类的静态变量赋初始值,提升程序性能

静态代码块的特点如下:

  • 静态代码块类似于一个方法,但它不可以存在于任何方法体中。

  • 静态代码块可以置于类中的任何地方,类中可以有多个静态初始化块。

  • Java 虚拟机在加载类时执行静态代码块,所以很多时候会将一些只需要进行一次的初始化操作都放在 static 代码块中进行。

  • 如果类中包含多个静态代码块,则 Java 虚拟机将按它们在类中出现的顺序依次执行它们,每个静态代码块只会被执行一次。

  • 静态代码块与静态方法一样,不能直接访问类的实例变量和实例方法,而需要通过类的实例对象来访问。

posted @ 2024-03-17 00:09  YJQING  阅读(17)  评论(0)    收藏  举报