this,super,static,final是四个常见的类的关键字,怎么样来描述类的属性和行为?
如果一个类从另外一个类继承,我们new这个子类的实例对象的时候,这个子类对象里面会有一个父类对象。怎么去引用里面的父类对象呢?使用super来引用,this指的是当前对象的引用,super是当前对象里面的父对象的引用。static和final可以用来修饰变量,方法,类,他们有各自的特点。
1. this
this代表对象的引用(谁调用就代表谁), 必须放在非静态方法里面,this是自身的一个对象,代表对象本身, 指向对象本身的一个指针。
参考 Java关键字this
主要作用:
(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();
}
}
运行结果:
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
*///
}
内存分析:::
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);
}
}
运行结果如下:
示例代码二:
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