Q:为什么要将this与super一起总结?
A:是因为它们在使用上确实有“部分”的相同。
super
are exactly the same situations in which the keyword
this
may be used in a class declaration.
this
作用
①指代(指向)调用(this所在方法的)对象caller。invoker(祷告祈求者)
②指代(指向)子类自身的构造器
使用位置
(关键字this
只能在以下的环境中使用)
- 在实例方法或default方法的主体(函数体)中(§8.4.7,§9.4.3)
- 在类的构造函数(Constructor)中(§8.8.7)
- 在类的实例初始设定式(instance initializer :Block
{}
)中(§8.6) - 在类的实例变量初始化表达式(initializer of an instance variable)中(§8.3.2)
- 作为函数的接收器参数(receiver parameter)(§8.4.1)
如果它出现在其他任何地方,则会发生编译时错误。
简单的总结一下:
- this在类函数中使用
普通(非静态)类/内部类的构造函数、实例(非静态)函数
或者特殊的抽象类(接口)的default函数中。 - this在类实例变量初始化表达式中使用
- this在类实例初始设定式block使用
- this作为函数形参的使用
简记为:类的非静态函数,类的非静态变量,接收器参数
使用格式
① this.Identifier
② this()
③ Identifier.this
this实例:
//1.in the body of an instance method or default method (§8.4.7, §9.4.3)
//1.1在接口的默认方法(default method)中使用
public interface interface1 {
//nomal method
abstract public void inter();
//在接口的默认方法(default method)中使用
default public void inter2(){
int i = this.hashCode();
}
//注:默认方法提供了在接口内访问此功能的独特功能。因此,它可能具有接口类型。
//(所有其他接口方法都是抽象的或静态的,因此不能访问它。)
//在运行时,如果T是类,则引用的实际对象的类可以是T,或者是T的子类。
}
//1.2在普通类的实例方法中使用
public class Chinese extends YellowHuman{
protected int a = this.mimi;
public void superThis(){
this.a = super.mimi;
}
}
//2.in the body of a constructor of a class (§8.8.7)
//2.1在构造函数中使用this
public class Person{
private int i;
//在构造函数中使用
Person(){ //默认public,可省略
i = this.hashCode();
}
}
//2.2在构造函数中通过this引用其他类型构造函数
public class Person{
public Chinese(){
this("无参构造器调用有参构造函数中ing...");
}
public Chinese(String name){
System.out.println(name + "有参构造函数运行ing...");
}
}
//3.in an instance initializer of a class (§8.6)
//3.在类实例初始设定式(block)中使用
public class Person{
//在instance initializer(Person类)实例初始设定式(block)中使用
{
i = this.hashCode();
}
private int i;
}
//4.in the initializer of an instance variable of a class (§8.3.2)
//4.在类数据成员初始化表达式中使用
public class Person{
//在数据成员初始化表达式中使用。
private int i = this.hashCode();
}
//5.to denote a receiver parameter (§8.4.1)
//5.在接收器参数中使用
//顶级类Test
class Test {
//顶级类Test的构造函数
Test(/* ?? ?? */) {}
// No receiver parameter is permitted in the constructor of
// a top level class, as there is no conceivable type or name.
// 不能使用 接收器参数receiver parameter
// 因为没有可联想的类型或参数名称
void m(Test this) {}
// OK: receiver parameter in an instance method
// 允许在实例方法中使用 接收器参数
static void n(Test this) {}
// Illegal: receiver parameter in a static method
// 不合法,接收器参数不能用于类(静态)方法中
//内部类A
class A {
//内部类A的构造函数
A(Test Test.this) {}
// OK: the receiver parameter represents the instance
// of Test which immediately encloses the instance
// of A being constructed.
// 允许在Test内部类(次级类)类A的构造函数中使用接收器参数receiver parameter
// Test.this表示:Test顶级类实例
void m(A this) {}
// OK: the receiver parameter represents the instance
// of A for which A.m() is invoked.
// 允许在内部类(次级类)类A的实例函数中使用接收器参数
// A this表示:调用A.m()方法的实例A(类A的实例A)
//内部类A的内部类B
class B {
//内部类A的内部类B的构造函数
B(Test.A A.this) {}
// OK: the receiver parameter represents the instance
// of A which immediately encloses the instance of B
// being constructed.
// 允许在内部类A中的内部类B的构造函数中使用接收器参数receiver parameter
// Test.A A.this表示:内部类A的实例A,实例A立即装入这个正在构造的实例B
void m(Test.A.B this) {}
// OK: the receiver parameter represents the instance
// of B for which B.m() is invoked.
// 允许在内部类A中的内部类B的实例函数中使用接收器参数
// Test.A.B this表示:调用B.m()方法的实例B(类B的实例B)
}
}
}
最后补充lambda的this:
当且仅当在允许出现lambda表达式的环境下,this可以用于lambda表达式,否则这是一个编译错误。
在lambda体中this表示的对象与在周围上下文中this表示的对象相同。
super
作用
指向(子类继承的)父类内存空间 ! 而不是父类对象
调用父类属性及方法(public、protect、packagelocal)
使用位置
仅允许在下述4种情况使用
- 类实例函数
- 类实例初始设定式(Block)
- 类构造函数
- 类变量初始化表达式
简单总结一下
1.类函数
2.类变量
使用格式
① super.Identifier
② super()
③ T.super.Identifier
super实例
//1.super.Identifier
//1.父类.非私有成员函数/非私有数据成员(可调隐藏权限packagelocal属性及方法)
public class Chinese extends YellowHuman{
public void superTest(){
super.eat();
int i = super.mimi; //与在YellowHuman类中使用this.mimi是一个含义。
}
}
//2.T.super.Identifier
/** 看不懂
The form` T.super.Identifier` refers to the field named *Identifier* of the lexically enclosing instance corresponding to T, but with that instance viewed as an instance of the superclass of T.
Suppose that a field access expression T.super.f appears within class C, and the immediate superclass of the class denoted by T is a class whose fully qualified name is S. If f in S is accessible from C, then T.super.f is treated as if it had been the expression this.f in the body of class S. Otherwise, a compile-time error occurs.
Thus, T.super.f can access the field f that is accessible in class S, even if that field is hidden by a declaration of a field f in class T.
It is a compile-time error if the current class is not an inner class of class T or T itself.
**/
//3.super();
//3.父类构造器,可传参数
public class Chinese extends YellowHuman{
//子类无参
public Chinese(){
//调用子类自己的有参构造器
this("无参构造器运行中ing");
}
//子类有参
public Chinese(String name){
//调用父类的有参构造器
super(name);
//调用父类的eat方法
Chinese.super.eat();//2.T.super.Identifier
System.out.println(name + "有参构造器运行中ing");
}
}
abstract class YellowHuman extends Human2{
//父类无参构造器
public YellowHuman(){
System.out.println("YellowHuman");
}
//父类有参构造器
public YellowHuman(String name){
System.out.println(name + " is YellowHuman");
}
protected void eat() {
System.out.println("Eat Rise");
System.out.println(new InnerClass1().ageMax);
}
//内部类
class InnerClass1 {
public int ageMax = 150;
}
}
注意
注1:super不能在Object类中使用,因为Object类没有父类。
注2:super可以获取使用父类的隐藏访问权限(package local)的变量、函数。
注3:super与this不能同时使用,因为它们二者都要求在构造器的第一行。