【Java入门教程】Java 重温this、super、final和static关键字
我们前面刚学了面向对象的继承、封装、多态,那么接下来让我们重温一些这些关键字:this、super、final和static
1. Java的this关键字
在Java编程中,this关键字用于引用当前对象。它可以在实例方法、构造方法和内部类中使用。this关键字的主要作用是消除变量的歧义性,使得程序更加清晰易懂。
1.1 this关键字的作用
this关键字主要有以下几种作用:
-
引用当前对象:在类的实例方法中,this关键字引用的就是当前的对象。通过使用this关键字,我们可以在方法内部访问当前对象的属性和方法。
-
调用其他构造方法:this关键字可以用于在一个构造方法中调用同一类的其他构造方法。这种方式可以重用代码,减少重复性工作。
-
传递参数:this关键字可以用于传递对象自身作为参数,比如在方法调用中将当前对象传递给其他方法。
1.2 使用this关键字的示例
下面是一个使用this关键字的示例:
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void printInfo() {
System.out.println("Name: " + this.name);
System.out.println("Age: " + this.age);
}
public void changeName(String newName) {
this.name = newName;
}
public void updateAge() {
this.age++;
}
public static void main(String[] args) {
Person person = new Person("John", 25);
person.printInfo();
person.changeName("Mike");
person.updateAge();
person.printInfo();
}
}
在上述示例中,我们使用this关键字来引用当前对象的属性和方法。在printInfo方法中,使用this.name和this.age访问当前对象的name和age属性。在changeName和updateAge方法中,使用this关键字来更新当前对象的name和age属性。
1.3 注意事项
在使用this关键字时,需要注意以下几个方面:
-
this关键字只能在实例方法、构造方法和内部类中使用:在静态方法中无法使用this关键字,因为this关键字只能引用当前对象,而静态方法是属于类的而不是对象的。
-
this关键字必须在方法内部使用:this关键字必须在方法内部使用,不能在方法的参数列表中使用。
-
this关键字只能引用当前对象的成员:this关键字只能引用当前对象的成员,无法引用其他对象的成员。
2. Java的super关键字
super关键字是Java中的一个特殊关键字,用于引用当前对象的父类。通过super关键字,我们可以在子类中访问父类的成员变量、方法和构造方法。super关键字的使用可以增强代码的复用性和灵活性。
2.1 super关键字的作用
super关键字主要有以下几种用法:
-
访问父类的成员变量:通过使用super关键字,我们可以在子类中访问父类的成员变量,包括私有成员变量。
-
调用父类的构造方法:在子类的构造方法中,使用super关键字可以调用父类的构造方法。这样可以确保父类的初始化工作得以完成。
-
调用父类的方法:通过super关键字,子类可以调用父类的方法。这样可以在子类的方法中重写父类的方法,实现对父类方法的扩展或修改。
-
创建内部类对象:在内部类中使用super关键字可以引用外部类的对象,从而创建内部类对象。
2.2 使用super关键字的示例
下面是一个使用super关键字的示例:
public class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
public void eat() {
System.out.println("Animal is eating.");
}
}
public class Dog extends Animal {
private String breed;
public Dog(String name, String breed) {
super(name);
this.breed = breed;
}
@Override
public void eat() {
super.eat();
System.out.println("Dog is eating.");
}
public void displayInfo() {
System.out.println("Name: " + super.name);
System.out.println("Breed: " + this.breed);
}
public static void main(String[] args) {
Dog dog = new Dog("Bobby", "Labrador");
dog.eat();
dog.displayInfo();
}
}
在上述示例中,Animal类是一个父类,Dog类是一个继承自Animal类的子类。在Dog类的构造方法中,使用super关键字调用父类的构造方法来初始化父类的成员变量。在Dog类中,通过super.eat()调用父类的eat()方法,并在子类的eat()方法中对其进行了重写。在displayInfo方法中,使用super关键字访问父类的name成员变量。
2.3 注意事项
在使用super关键字时,需要注意以下几个方面:
-
super关键字只能在子类中使用:在父类中无法使用super关键字,因为super关键字用于引用当前对象的父类。
-
super关键字必须在子类的构造方法或方法内部使用:super关键字只能在子类的构造方法或方法内部使用,不能在方法的参数列表中使用。
-
super关键字必须在子类实例化之后使用:在子类的构造方法中使用super关键字调用父类的构造方法时,必须确保子类的实例化已经完成。
-
super关键字只能引用直接父类的成员:super关键字只能引用直接父类的成员,无法引用间接父类的成员。
3. Java的final关键字
final关键字是Java中的一个修饰符,用于修饰类、方法和变量。使用final关键字修饰的元素具有不可改变的特性,不能被继承、重写或重新赋值。
3.1 final关键字的作用
final关键字主要有以下几种作用:
-
修饰类:使用final关键字修饰的类不能被继承。这样可以确保类的完整性,防止被子类修改或扩展。
-
修饰方法:使用final关键字修饰的方法不能被子类重写。这样可以确保方法的逻辑不被修改,保证方法的稳定性。
-
修饰变量:使用final关键字修饰的变量不能重新赋值。这样可以确保变量的值不被修改,保持变量的不变性。
3.2 使用final关键字的示例
下面是一些使用final关键字的示例:
3.2.1 修饰类
public final class Circle {
private final double radius;
public Circle(double radius) {
this.radius = radius;
}
public double getArea() {
return Math.PI * radius * radius;
}
public static void main(String[] args) {
Circle circle = new Circle(5.0);
System.out.println("Area: " + circle.getArea());
}
}
在上述示例中,Circle类被final关键字修饰,因此不能被其他类继承。在Circle类的构造方法中,使用final关键字修饰了radius变量,保证了其不可修改性。
3.2.2 修饰方法
public class Shape {
public final void draw() {
System.out.println("Drawing shape...");
}
}
public class Circle extends Shape {
// 编译错误:无法重写final方法
// @Override
// public void draw() {
// System.out.println("Drawing circle...");
// }
}
在上述示例中,Shape类中的draw方法被final关键字修饰,因此不能被子类重写。在Circle类中,尝试重写draw方法会导致编译错误。
3.2.3 修饰变量
public class MathUtils {
public static final double PI = 3.141592653589793;
}
在上述示例中,MathUtils类中的PI变量使用final关键字修饰,保证了其不可重新赋值性质。这样可以确保PI的值不被修改,保持了常量的不变性。
3.3 注意事项
在使用final关键字时,需要注意以下几个方面:
-
final关键字只能用于修饰类、方法和变量:final关键字不能用于修饰接口、抽象类等其他元素。
-
final关键字的作用范围有限:final关键字修饰的类不能被继承,修饰的方法不能被重写,修饰的变量不能被重新赋值。但是,final关键字并不能保证类、方法和变量的内容不被修改,只是保证了其不可改变性。
-
final关键字的使用应遵循规范:使用final关键字应慎重,只在必要的情况下使用。过度使用final关键字可能会导致代码难以理解和维护。
4. Java的static关键字
static关键字是Java中的一个修饰符,用于修饰成员变量和方法。使用static关键字修饰的成员变量和方法属于类本身,而不属于类的实例。static关键字的使用可以简化代码的访问和调用,提高程序的性能和效率。
4.1 static关键字的作用
static关键字主要有以下几个作用:
-
静态变量:使用static关键字修饰的成员变量称为静态变量。静态变量属于类本身,不属于类的实例。所有的实例共享同一个静态变量,可以通过类名直接访问。
-
静态方法:使用static关键字修饰的方法称为静态方法。静态方法属于类本身,不属于类的实例。静态方法只能访问静态变量和调用其他静态方法,无法访问非静态变量和调用非静态方法。
-
静态代码块:使用static关键字定义的代码块称为静态代码块。静态代码块在类加载的时候执行,只执行一次。静态代码块主要用于初始化静态变量或执行其他静态操作。
-
静态内部类:使用static关键字修饰的内部类称为静态内部类。静态内部类属于外部类本身,不依赖于外部类的实例。静态内部类可以直接通过外部类名访问。
4.2 使用static关键字的示例
下面是一些使用static关键字的示例:
4.2.1 静态变量和静态方法
public class StringUtils {
public static final String DEFAULT_STRING = "default";
public static String reverse(String str) {
StringBuilder builder = new StringBuilder(str);
return builder.reverse().toString();
}
public static void main(String[] args) {
String reversedStr = StringUtils.reverse("hello");
System.out.println("Reversed string: " + reversedStr);
System.out.println("Default string: " + StringUtils.DEFAULT_STRING);
}
}
在上述示例中,StringUtils类包含一个静态变量DEFAULT_STRING和一个静态方法reverse。静态变量DEFAULT_STRING可以直接通过类名访问,无需实例化对象。静态方法reverse可以直接调用,无需创建StringUtils对象。
4.2.2 静态代码块
public class MathUtils {
public static final double PI;
static {
PI = 3.141592653589793;
}
public static void main(String[] args) {
System.out.println("PI: " + MathUtils.PI);
}
}
在上述示例中,MathUtils类使用静态代码块初始化静态变量PI。静态代码块在类加载的时候执行,只执行一次。在main方法中,可以直接通过MathUtils.PI访问静态变量。
4.2.3 静态内部类
public class Outer {
private static int count = 0;
public static class Inner {
public void displayCount() {
System.out.println("Count: " + Outer.count);
}
}
public static void main(String[] args) {
Outer.Inner inner = new Outer.Inner();
inner.displayCount();
}
}
在上述示例中,Outer类中定义了一个静态内部类Inner。静态内部类可以直接通过Outer.Inner创建对象,并访问外部类的静态变量count。
4.3 注意事项
在使用static关键字时,需要注意以下几个方面:
-
静态成员属于类本身:使用static关键字修饰的成员变量和方法属于类本身,而不属于类的实例。它们不依赖于对象的创建,可以通过类名直接访问。
-
静态成员无法访问非静态成员:静态成员只能访问静态成员,无法访问非静态成员。因为非静态成员的创建依赖于对象的实例化,而静态成员独立于对象的创建。
-
静态成员共享:通过使用静态成员,可以实现数据的共享。所有的实例共享同一个静态成员,可以避免重复创建实例。
-
静态代码块在类加载时执行:静态代码块在类加载的时候执行,只执行一次。静态代码块主要用于初始化静态变量或执行其他静态操作。
-
非静态类可以访问静态成员:非静态类可以访问静态成员,包括静态变量和静态方法。这是因为静态成员属于类本身,与对象的实例化无关。