一、Super关键字
1、非构造方法中的super关键字访问父类成员(变量和方法)
如果子类方法覆盖父类的方法,在子类中可以通过super关键字调用被重写的方法
class father {
//私有,子类不可访问
private String str = "let's play some dota";
public String str1 = "dota";
public void play() {
System.out.println(str);
}
}
class son extends father {
//继承father,super访问父类方法
public void fatherplay() {
super.play();
}
//继承father,super访问父类成员
private String str2 = super.str1;
public String str3 = super.str1;
}
public class SuperTest {
public static void main(String[] args) {
son o = new son();
//无法访问私有
// System.out.println(o.str);
System.out.println(o.str1);
// System.out.println(o.str2);
System.out.println(o.str3);
o.play();
o.fatherplay();
}
}
2、构造函数super关键字调用父类构造函数
通过使用super关键字调用父类的构造方法必须在子类构造方法的第一行。可以是调用无参的super();也可以是调用父类有参数的构造方法super(parameter,list);
class animal{
//带有参数的构造函数
animal(String s){
System.out.println(s);
}
}
class dog extends animal{
//如果不显示调用父类构造函数,Java编译器会调用super()
//如果父类没有无参数构造函数,则编译报错
dog(String str){
super(str);
}
public void wangwang(){
System.out.println("wangwang");
}
}
public class Supertest2 {
public static void main(String[] args) {
dog d=new dog("heihei");
d.wangwang();
}
}
注意:Java 程序在执行子类的构造方法之前,如果没有用 super()
来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”。因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用 super()
来调用父类中特定的构造方法,则编译时将发生错误,因为 Java 程序在父类中找不到没有参数的构造方法可供执行,这个就是在Java中定义一个不做事且没有参数的构造方法的作用
二、final关键字
在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)。final修饰的属性跟具体对象有关,在运行期初始化final修饰的属性,表示这个属性是常数(创建后不可更改),不同的对象有不同的final属性
1、final修饰类:表示这个类不能被继承,一般工具类会被设置成final的,如JDK中的String类
public final class FinalDemo {
public FinalDemo(){
}
public FinalDemo(int value){
System.out.println(value);
}
class FinalChild extends FinalDemo{
}
}
在FinalDemo类中如果没有默认构造函数,会报错(在前面的super关键字使用已经提过);上面的代码最下面的FinalDemo会有红色波浪下划线表示错误:Cannot inherit from final “ FinalDemo ”。
2、final修饰方法:表示这个方法不能被重写
类的private方法会被隐示的指定为final方法;如果父类中有final修饰的方法,子类无法继承重写
public class FinalDemo {
public FinalDemo(){
}
public FinalDemo(int value){
System.out.println(value);
}
public final void func(){
System.out.println("do sth");
}
class FinalChild extends FinalDemo{
// override 报错
public void func(){
System.out.println("do str");
}
// overloading 重载可以
public void func(String str){
System.out.println(str);
}
}
}
上面代码在 func() 报错 “ 'func()' cannot override 'func()' in 'FinalDemo' ; overridden method is final ”。 但是可以被重载
3、final修饰变量:final关键字用的最多的地方,只能赋值一次,赋值后不可更改
fina修饰基本数据类型会将其变成一个常数(创建后不可被修改);
fina修饰引用数据类型会将引用变成一个常数(创建后不可再指向其他对象),但是引用(指向的对象)的内容可以被修改。
fina修饰成员变量,注意必须要显示初始化,一种是直接在声明的时候初始化,一种是在该类的构造函数初始化(所有构造函数都要有final的初始化)
public class FinalDemo {
private final int value;
public FinalDemo(){
this.value=12;
}
public FinalDemo(int value){
this.value=value;
}
public static void main(String[] args) {
FinalDemo test=new FinalDemo();
System.out.println(test.value);
FinalDemo testtmp=new FinalDemo(123);
System.out.println(testtmp.value);
final int[] arr1={1,2,3};
int[] arr2={2,43,4};
// arr1=arr2.clone();,报错 不可更改引用即指向的对象
arr1[0]=12; // 但是指向的对象的内容可以更改
System.out.println(arr1[0]);
}
}
三、static关键字
在Java中,static关键字可以用来修饰属性,方法,代码段,内部类(静态内部类或嵌套内部类),static修饰的属性初始化是在编译器(类加载的时候),初始化后可以被改变,static关键字最重要的作用就是方便在没有对象的情况调用。
- static修饰的成员变量和方法,属于类,被所有对象共有(理所当然可以被对象访问)
- 静态方法不可以调用非静态成员
- 普通的成员变量和方法,属于对象,是对象独有的
- static代码块:属于类初始化操作,将一些必要的初始化放入static代码块用于提高性能
- static不可以用于修饰局部变量(对于Java,这是乌龟的屁股——规定)
public class StaticFinal {
// 被所有对象共有
private static int res = 0;
// 被所有对象共有,且唯一不可改变
private static final int tmp=12;
public StaticFinal(int value) {
res += value;
}
public static void main(String[] args) {
StaticFinal test = new StaticFinal(23);
System.out.println(test.res);
StaticFinal test2 = new StaticFinal(32);
System.out.println(test2.res);
}
}
前面介绍final关键字的时候,修饰成员变量可以声明后在所有构造函数中赋初值,这里如果用 static final 来修饰的话,必须在声明的时候赋初值,因为此时的成员变量是所有对象共有,且只能初始化一次的。
注:static修饰的属性重点在于它们只有一个,被所有对象共享,属于类的;final修饰的属性重点在于它们是个常数,不可被修改,static final修饰的属性重点在于它们被所有对象共享,属于类的,且不可更改,可以通过类名直接访问。