javaSE_13_关键字super丶final

知识框架

super 概述(理解)

super 和 this 可以对比着学习:

this

  • this 是一个引用,保存内存地址指向自己。
  • this 出现在实例方法中,谁调用这个实例方法,this 就代表谁,this 代表当前正在执行这个动作的对象。
  • this 不能出现在静态方法中。
  • this 大部分情况下可以省略,在方法中区分实例变量和局部变量的时候不能省略。
  • “this(实际参数列表)”出现在构造方法第一行,通过当前的构造方法去调用本类当中其它的构造方法。

super

  • super能出现在实例方法和构造方法中。
  • super的语法是:“super.”、“super()”
  • super不能使用在静态方法中。
  • super. 大部分情况下是可以省略的。
  • super.什么时候不能省略呢? ???????
  • super() 只能出现在构造方法第一行,通过当前的构造方法去调用“父类”中的构造方法,目的是:创建子类对象的时候,先初始化父类型特征。
  • super()表示通过子类的构造方法调用父类的构造方法。模拟现实世界中的这种场景:要想有儿子,需要先有父亲。

重要的结论:

当一个构造方法第一行:既没有this()又没有super()的话,默认会有一个super();表示通过当前子类的构造方法调用父类的无参数构造方法。所以必须保证父类的无参数构造方法是存在的。 注意:this()和super() 不能共存,它们都是只能出现在构造方法第一行。
  • 无论是怎样折腾,父类的构造方法是一定会执行的。
  • 在构造方法执行过程中一连串调用了父类的构造方法,父类的构造方法又继续向下调用它的父类的构造方法,但是实际上对象只创建了一个。

三种用法

      

this和super的区别

       

继承中构造方法的访问特点

  • 子类中所有的构造方法默认都会访问父类中无参的构造方法
  • ​子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化,原因在于,每一个子类构造方法的第一条语句默认都是:super()
  • 构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的
  • 对象在堆内存中,会单独存在一块super区域,用来存放父类的数据

问题:如果父类中没有无参构造方法,只有带参构造方法,该怎么办呢?

  • 通过使用super关键字去显示的调用父类的带参构造方法
  • 在父类中自己提供一个无参构造方法

关键字final

final 表示不可改变的含义
  • 采用 final 修饰的类不能被继承
  • 采用 final 修饰的方法不能被覆盖
  • 采用 final 修饰的变量不能被修改
  • final 修饰的变量必须显示初始化如果修饰的引用,那么这个引用只能指向一个对象,也就是说这个引用不能再次赋值,但被指向的对象是可以修改的
构造方法不能被 final 修饰会影响 JAVA类的初始化:final 定义的静态常量调用时不会执行 java 的类初始化方法,也就是说不会执行 static 代码块等相关语句,这是由 java 虚拟机规定的。我们不需要了解的很深,有个概念就可以了。final修饰的实例变量一般和static联合使用,称为常量。public static final double PI = 3.1415926;

采用 final 修饰的类不能被继承

格式:

  • 含义:当前这个类不能有任何的子类。(太监类)
  • 注意:一个类如果是final的,那么其中所有的成员方法都无法进行覆盖重写(因为没儿子。)
package cn.itcast.day11.demo01;
 
/*
当final关键字用来修饰一个类的时候,格式:
public final class 类名称 {
    // ...
}
 */
public final class MyClass /*extends Object*/ {
 
    public void method() {
        System.out.println("方法执行!");
    }
 
}

采用 final 修饰的方法不能被覆盖

格式:

  • 含义:当final关键字用来修饰一个方法的时候,这个方法就是最终方法,也就是不能被覆盖重写。
  • 注意:对于类、方法来说,abstract关键字和final关键字不能同时使用,因为矛盾。
class A1 {
     public final void test1() {
     }
}

final修饰局部变量

  • 基本类型不能被修改
public class PackTest {
    public static void main(String[] args) {
        // 声明变量,使用final修饰 
        final int a;
        // 第一次赋值 
        a = 10;
 
        // 第二次赋值 a = 20; // 报错,不可重新赋值
        // 声明变量,直接赋值,使用final修饰
        
        final int b = 10;
        // 第二次赋值 b = 20; // 报错,不可重新赋值 
    }
}

final修饰局部变量

  • 引用类型的局部变量,被final修饰后,只能指向一个对象,地址不能再更改。但是不影响对象内部的成员变量值的修改,代码如下:
public class PackTest {
    public static void main(String[] args) {
        // 创建 User 对象 
        final User u = new User();
        // 创建 另一个 User对象u = new User(); // 报错,指向了新的对象,地址值改变。 
        // 调用setName方法
        u.setName("张三"); // 可以修改 
       
    }
}

final修饰成员变量 

对于成员变量来说,如果使用final关键字修饰,那么这个变量也照样是不可变。

  • 由于成员变量具有默认值,所以用了final之后必须手动赋值,不会再给默认值了。
  • 对于final的成员变量,要么使用直接赋值,要么通过构造方法赋值。二者选其一。
  • 必须保证类当中所有重载的构造方法,都最终会对final的成员变量进行赋值。

显示初始化:

public class PackTest {
    final String USERNAME = "张三";
    private int age;
 
}

构造方法初始化:

public class PackTest {
    final String USERNAME;
    private int age;
 
    public PackTest(String username, int age) {
        this.USERNAME = username;
        this.age = age;
    }
}
原文地址:https://www.cnblogs.com/wurengen/p/13258629.html