this,super,static,final是四个常见的类的关键字,怎么样来描述类的属性和行为?
如果一个类从另外一个类继承,我们new这个子类的实例对象的时候,这个子类对象里面会有一个父类对象。怎么去引用里面的父类对象呢?使用super来引用,this指的是当前对象的引用,super是当前对象里面的父对象的引用。static和final可以用来修饰变量,方法,类,他们有各自的特点。

1. this

this代表对象的引用(谁调用就代表谁), 必须放在非静态方法里面,this是自身的一个对象,代表对象本身, 指向对象本身的一个指针。
参考 Java关键字this
主要作用:
Java 面向对象编程之四个关键字

(1)this调用本类中的属性,也就是类中的成员变量;

   Public Class Student { 
     String name; //定义一个成员变量name
     private void SetName(String name) { //定义一个参数(局部变量)name
      this.name=name; //将局部变量的值传递给成员变量
     }
   } //   this这个关键字其代表的就是对象中的成员变量或者方法。
 

(2)this调用本类中的其他方法;

public class Student { //定义一个类,类的名字为student。 
 public Student() { //定义一个方法,名字与类相同故为构造方法
  this(“Hello!”);
    }
 public Student(String name) { //定义一个带形式参数的构造方法
    }
}

(3)this调用本类中的其他构造方法,调用时要放在构造方法的首行。

ublic Class Student {
 String name; //定义一个成员变量name
 private void SetName(String name) { //定义一个参数(局部变量)name
this.name=name; //将局部变量的值传递给成员变量
}
Return this
}

2. super

super主要作用:

   1:主要存在于子类方法中,用于指向子类对象中父类对象。
   2:访问父类的属性
   3:访问父类的函数
   4:访问父类的构造函数

super主要有两种用法:
  1)super.成员变量/super.成员方法;
  2)super(parameter1,parameter2…)
第一种用法主要用来在子类中调用父类的同名成员变量或者方法;第二种主要用在子类的构造器中显示地调用父类的构造器,要注意的是,如果是用在子类构造器中,则必须是子类构造器的第一个语句。
super是一个关键字,代表父类的存储空间标识。(可以理解为父亲的引用)
程序实例:

//父类
class FatherClass {
    public int value;
    public void f() {
        value=100;
        System.out.println("父类的value属性值="+value);
    }
}
 // 子类ChildClass从父类FatherClass继承  
class ChildClass extends FatherClass {
    /**
     * 子类除了继承父类所具有的valu属性外,自己又另外声明了一个value属性,
     * 也就是说,此时的子类拥有两个value属性。
     */
    public int value;
      //在子类ChildClass里面重写了从父类继承下来的f()方法里面的实现,即重写了f()方法的方法体。     
    public void f() {
        super.f();//使用super作为父类对象的引用对象来调用父类对象里面的f()方法
        value=200;//这个value是子类自己定义的那个valu,不是从父类继承下来的那个value
        System.out.println("子类的value属性值="+value);
        System.out.println(value);//打印出来的是子类自定义的那个value的值,这个值是200
        /**
         * 打印出来的是父类里面的value值,由于子类在重写从父类继承下来的f()方法时,
         * 第一句话“super.f();”是让父类对象的引用对象调用父类对象的f()方法,
         * 即相当于是这个父类对象自己调用f()方法去改变自己的value属性的值,由0变了100。
         * 所以这里打印出来的value值是100。
         */
        System.out.println(super.value);
    }
}
/**测试类*/
public class tEST1 {
    public static void main(String[] args) {
        ChildClass cc = new ChildClass();
        cc.f();
    }
}

运行结果:
Java 面向对象编程之四个关键字

3. static

static关键字的中文意思是静态的, 可以修饰字段、方法、内部类。使用该关键字修饰的内容,在面向对象中static修饰的内容是隶属于类,而不是直接隶属于对象的,故而生命周期与类相同,即在整个程序执行周期有效。所以static修饰的成员变量一般称作类成员变量,而static修饰的方法一般称作静态方法,普通变量和方法属于对象。
主要有四种用法:
(1)用来修饰成员变量,将其变为类的成员,从而实现所有对象对于该成员的共享;
(2)用来修饰成员方法,将其变为类方法,可以直接使用“类名.方法名”的方式调用,常用于工具类;
(3)静态块用法,将多个类成员放在一起初始化,使得程序更加规整,其中理解对象的初始化过程非常关键;
(4)静态导包用法,将类的方法直接导入到当前类中,从而直接使用“方法名”即可调用类方法,更加方便。

public class Person {
    String name;
    static  int age;
    public String toString() {
        return "Name:" + name + ", Age:" + age;
    }
       public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "zhangsan";
        p1.age = 10;
        Person p2 = new Person();
        p2.name = "lisi";
        p2.age = 12;
        System.out.println(p1);
        System.out.println(p2);
    }
    /**Output
     * Name:zhangsan, Age:10
     * Name:lisi, Age:12
     *///
}

内存分析:::
Java 面向对象编程之四个关键字

4. final

final是一个关键字,用于修饰类,成员变量,成员方法。
特点:它修饰的类不能被继承。它修饰的成员变量是一个常量。它修饰的成员方法是不能被子类重写的。
final修饰的常量定义一般都有书写规范,被final修饰的常量名称,所有字母都大写。
final修饰成员变量,必须初始化,初始化有两种,显示初始化;构造方法初始化,不能两个一起初始化

-final关键字 主要用法有以下四种:

(1)用来修饰数据,包括成员变量和局部变量,该变量只能被赋值一次且它的值无法被改变。对于成员变量来讲,我们必须在声明时或者构造方法中对它赋值;
(2)用来修饰方法参数,表示在变量的生存期中它的值不能被改变;
(3)修饰方法,表示该方法无法被重写;
(4)修饰类,表示该类无法被继承。
重写(覆盖):在子类中定义某方法与其父类有相同的名称,返回类型和参数(有继承关系)
重载:JAVA中一个类可以有多个同名方法,参数类型或个数等可以不同。(没有继承关系)

  • final和private的区别:
    1.final修饰的类可以访问;
    private不可以修饰外部类,但可以修饰内部类(其实把外部类私有化是没有意义的)。
    2.final修饰的方法不可以被子类重写;
    private修饰的方法表面上看是可以被子类重写的,其实不可以,子类是看不到父类的私有方法的。
    3.final修饰的变量只能在显示初始化或者构造函数初始化的时候赋值一次,以后不允许更改;
    private修饰的变量,也不允许直接被子类或一个包中的其它类访问或修改,但是他可以通过set和get 方法对其改值和取值。

- [ ]super和this的异同:

This指向本类,super指向父类
(1) super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句)
this(参数):调用本类中另一种形成的构造函数(应该为构造函数中的第一条语句)
(2)super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或 函数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名(实参)
this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)
(3)调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。
super()和this()类似,区别是,super()从子类中调用父类的构造方法,this()在同一类内调用其它方法。super()和this()均需放在构造方法内第一行。尽管可以用this调用一个构造器,但却不能调用两个。
this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。

class Person { 
    public static void prt(String s) { 
       System.out.println(s); 
    } 
       Person() { 
       prt("父类·无参数构造方法: "+"A Person."); 
    }//构造方法(1) 
        Person(String name) { 
       prt("父类·含一个参数的构造方法: "+"A person's name is " + name); 
    }//构造方法(2) 
} 
    public class tEST1 extends Person { 
    tEST1() { 
       super(); // 调用父类构造方法(1) 
       prt("子类·调用父类”无参数构造方法“: "+"A chinese coder."); 
    }     
    tEST1(String name) { 
       super(name);// 调用父类具有相同形参的构造方法(2) 
       prt("子类·调用父类”含一个参数的构造方法“: "+"his name is " + name); 
    }     
    tEST1(String name, int age) { 
       this(name);// 调用具有相同形参的构造方法(3) 
       prt("子类:调用子类具有相同形参的构造方法:his age is " + age); 
    }  
    public static void main(String[] args) { 
       tEST1 cn = new tEST1(); 
       cn = new tEST1("codersai"); 
       System.out.println();
       cn = new tEST1("codersai", 18); 
    } 
}

运行结果如下:
Java 面向对象编程之四个关键字

示例代码二:

public class Test {
    Person person = new Person("Test");
    static{
        System.out.println("test static");
    }
     public Test() {
        System.out.println("test constructor");
    }
         public static void main(String[] args) {
        new MyClass();
    }
} 
class Person{
    static{
        System.out.println("person static");
    }
    public Person(String str) {
        System.out.println("person "+str);
    }
}
class MyClass extends Test {
    Person person = new Person("MyClass");
    static{
        System.out.println("myclass static");
    }     
    public MyClass() {
        System.out.println("myclass constructor");
    }
}

运行结果如下:

test static
myclass static
person static
person Test
test constructor
person MyClass
myclass constructor

过程分析:首先加载Test类,因此会执行Test类中的static块。接着执行new MyClass(),而MyClass类还没有被加载,因此需要加载MyClass类。在加载MyClass类的时候,发现MyClass类继承自Test类,但是由于Test类已经被加载了,所以只需要加载MyClass类,那么就会执行MyClass类的中的static块。在加载完之后,就通过构造器来生成对象。而在生成对象的时候,必须先初始化父类的成员变量,因此会执行Test中的Person person = new Person(),而Person类还没有被加载过,因此会先加载Person类并执行Person类中的static块,接着执行父类的构造器,完成了父类的初始化,然后就来初始化自身了,因此会接着执行MyClass中的Person person = new Person(),最后执行MyClass的构造器。

引用:
https://www.cnblogs.com/dolphin0520/p/3799052.html

https://www.cnblogs.com/dotgua/p/6354151.html?utm_source=itdadao&utm_medium=referral

相关文章: