细节3:static、final、this、super关键字

1、static
   static关键字修饰的变量或者函数是属于整个类的,调用方式,类名.变量/方法
   静态函数中,只能调用静态的变量或者函数
   静态的变量只会运行一次

   public class Test {
    public static void main(String[] args)  {
            MyClass myClass1 = new MyClass();
            MyClass myClass2 = new MyClass();

            System.out.println(myClass1.j);
            System.out.println(myClass2.j);
 
    }
   }
 
   class MyClass {
    public static double j = Math.random();
   }

   两次的j的值相同

2、final

   1.修饰类
   当用final修饰一个类时,表明这个类不能被继承

   2.修饰方法
   把方法锁定,以防任何继承类修改它的含义

   3.修饰变量
   ①对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改

   当用final作用于类的成员变量时,成员变量(注意是类的成员变量,局部变量只需要保证在使用之前被初始化赋值即可)必须在定义时或者构造器中进行初始化赋值,而且final变量一旦被初始化赋值之后,就不能再被赋值了

   ②如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象

   当用final修饰引用变量时
   public class Test {
    public static void main(String[] args)  {
        final MyClass myClass = new MyClass();
        System.out.println(++myClass.i);
 
     }
   }
 
   class MyClass {
    public int i = 0;
   }

   输出结果为1

   这说明引用变量被final修饰之后,虽然不能再指向其他对象,但是它指向的对象的内容是可变的

   ③final和static

   static作用于成员变量用来表示只保存一份副本,而final的作用是用来保证变量不可变

   public class Test {
    public static void main(String[] args)  {
            MyClass myClass1 = new MyClass();
            MyClass myClass2 = new MyClass();
            System.out.println(myClass1.i);
            System.out.println(myClass1.j);
            System.out.println(myClass2.i);
            System.out.println(myClass2.j);
 
    }
   }
 
   class MyClass {
    public final double i = Math.random();
    public static double j = Math.random();
   }

   运行这段代码就会发现,每次打印的两个j值都是一样的,而i的值却是不同的

   ④使用final修饰方法参数的目的是防止修改这个参数的值,同时也是一种声明和约定,强调这个参数是不可变的
3、this关键字
   this:当前对象
   this():当前类的无参构造方法,也可以指定有参的构造方法this(a)
   1、如果一个类的方法需要访问该类本身的成员变量或其它方法,可以使用this引用
   2、每个对象可以使用this关键字引用它本身,如:
      我们可以将this引用作为参数给一个方法,通过这种方式,一个对象可以将它本身的引用传给其它对象
   3、可以在构造方法中调用本类的其它构造方法,但是必须放在构造方法的第一行

4、super关键字
   super:直接父类对象
   super():直接父类的无参构造方法,也可以指定有参构造方法super(a)

   1、当子类成员变量b覆盖父类成员变量b时,使用super.b调用父类被隐藏的成员变量
   public class Person {

    String  name = "张三";

   }
   public class Teacher extends Person{

    String name = "李四";

    public Teacher() {
        System.out.println(name);     //name = "李四"
        System.out.println(super.name);  //super.name = "张三"
    }
   }

   2、当子类重写了父类方法method时,使用super.method()调用父类被隐藏的方法

   3、实例化子类对象时,必定会调用父类构造方法,如果没有写super(),则默认调用父类构造方法
      如果父类谢了有参构造方法,编译器就不会为父类创建无参构造方法,此时super()没有被定义,则必须在子类构造方法中写明super(参数),或在父类中显示的写出父类的无参构方法(一般使用这种方法)
      
   public class Person {

    String  name;

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

   在编写一个类去继承Person类的时候会产生编译错误
   解决方法一:在子类构造方法中编写super(参数),且必须放在子类构造方法的第一行

   public class Teacher extends Person{

    String name;

    public Teacher(String name) {
        super(name);
        System.out.println(name);
    }
   }

   解决方法二:在父类中显示的写出父类的无参构方法(一般使用这种方法)
   public class Person {
    String  name;
    public Person() {}

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

猜你喜欢

转载自www.cnblogs.com/snzd9958/p/9446474.html