1 this和super关键字
1.this和super的意义
this:当前对象
-
在构造器和非静态代码块中,表示正在new的对象
-
在实例方法中,表示调用当前方法的对象
super:引用父类声明的成员
无论是this和super都是和对象有关的。
2.this和super的使用格式
-
this
-
this.成员变量:表示当前对象的某个成员变量,而不是局部变量
-
this.成员方法:表示当前对象的某个成员方法,完全可以省略this.
-
this()或this(实参列表):调用另一个构造器协助当前对象的实例化,只能在构造器首行,只会找本类的构造器,找不到就报错
-
-
super
-
super.成员变量:表示当前对象的某个成员变量,该成员变量在父类中声明的
-
super.成员方法:表示当前对象的某个成员方法,该成员方法在父类中声明的
-
super()或super(实参列表):调用父类的构造器协助当前对象的实例化,只能在构造器首行,只会找直接父类的对应构造器,找不到就报错
-
this 和 super * ①this: * 1.使用场景:构造器,非静态代码块,用于实例初始化 * 2.this指代new的对象 * 3.表示调用方法的对象,谁调用就指向谁 * 4. * this.成员变量 * this.成员方法 * this()或着this(实参列表)出现在构造器中 * ②super * 1.使用场景 继承类中表示父类 * 2. * super.成员变量 * super.成员方法 * super()和super(实参列表) * super()当调用子类的构造器时,如果没有进行super()书写,那么就会在自动在构造器的首行 * 添加super()进行使用对应init初始化的方法 * super()无论在什么情况下,需要在首行进行书写
-
3.避免子类和父类声明重名的成员变量
特别说明:应该避免子类声明和父类重名的成员变量
因为,子类会继承父类所有的成员变量,所以:
-
如果重名的成员变量表示相同的意义,就无需重复声明
-
如果重名的成员变量表示不同的意义,会引起歧义
在阿里的开发规范等文档中都做出明确说明
4.解决成员变量重名问题
-
如果实例变量与局部变量重名,可以在实例变量前面加this.进行区别
-
如果子类实例变量和父类实例变量重名,并且父类的该实例变量在子类仍然可见,在子类中要访问父类声明的实例变量需要在父类实例变量前加super.,否则默认访问的是子类自己声明的实例变量
-
如果父子类实例变量没有重名,只要权限修饰符允许,在子类中完全可以直接访问父类中声明的实例变量,也可以用this.实例访问,也可以用super.实例变量访问
-
总结:起点不同(就近原则)
-
变量前面没有super.和this.
-
在构造器、代码块、方法中如果出现使用某个变量,先查看是否是当前块声明的==局部变量==,
-
如果不是局部变量,先从当前执行代码的==本类去找成员变量==
-
如果从当前执行代码的本类中没有找到,会往上找==父类声明的成员变量==(权限修饰符允许在子类中访问的)
-
-
变量前面有this.
-
通过this找成员变量时,先从当前执行代码的==本类去找成员变量==
-
如果从当前执行代码的本类中没有找到,会往上找==父类声明的成员变量(==权限修饰符允许在子类中访问的)
-
-
变量前面super.
-
通过super找成员变量,直接从当前执行代码的直接父类去找成员变量(权限修饰符允许在子类中访问的)
-
如果直接父类没有,就去父类的父类中找(权限修饰符允许在子类中访问的)
-
5.解决成员方法重写后调用问题
-
如果子类没有重写父类的方法,只有权限修饰符运行,在子类中完全可以直接调用父类的方法;
-
如果子类重写了父类的方法,在子类中需要通过super.才能调用父类被重写的方法,否则默认调用的子类重写的方法
总结:
-
方法前面没有super和this.
-
先从子类找匹配方法,如果没有,再从直接父类找,再没有,继续往上追溯
-
-
方法前面有this.
-
先从子类找匹配方法,如果没有,再从直接父类找,再没有,继续往上追溯
-
-
方法前面有super.
-
从当前子类的直接父类找,如果没有,继续往上追溯
-
2 native关键字(了解)
1.native的意义
native:本地的,原生的
2.native的语法
native只能修饰方法,表示这个方法的方法体代码不是用Java语言实现的,而是由C/C++语言编写的。但是对于Java程序员来说,可以当做Java的方法一样去正常调用它,或者子类重写它。
/* * native:原生的
*
*表示这个方法的方法体代码不是用Java语言实现的,java中看不到这个方法体,而是由C/C++语言编写的。
*/
public class TestNative {
public static void main(String[] args) {
Person p1=new Person();
System.out.println(p1);//day0418.classcode.keyword.Person@1b6d3586
// 它是一串数字,将对象的地址值转换为十六进制
System.out.println(p1.hashCode());//460141958
//按住ctrl键,可以追踪源码
/* Person p1=new Person();
System.out.println(p1);//day0418.classcode.keyword.Person@1b6d3586
// 它是一串数字,将对象的地址值转换为十六进制
System.out.println(p1.hashCode());//460141958
//按住ctrl键,可以追踪源码*/
/* Person p1=new Person();
System.out.println(p1);//day0418.classcode.keyword.Person@1b6d3586
// 它是一串数字,将对象的地址值转换为十六进制
System.out.println(p1.hashCode());//460141958
//按住ctrl键,可以追踪源码*/
}
}
class Person{}
3 final关键字
1.final的意义
final:最终的,不可更改的
2.final修饰类
表示这个类不能被继承,没有子类
3.final修饰方法
表示这个方法不能被子类重写
4.final修饰变量
final修饰某个变量(成员变量或局部变量),表示它的值就不能被修改,即常量,常量名建议使用大写字母。
如果某个成员变量用final修饰后,没有set方法,并且必须初始化(可以显式赋值、或在初始化块赋值、实例变量还可以在构造器中赋值)
/* final 最终的
* 1.final修饰类 太监类 不能继承
* 2.final 修饰方法 不能进行重写
* 3.final 修饰变量(通常称为常量)不能进行修改 常量通常大写
*
*
*/
final class Person1{
}
class Father{
}
class Son1 extends Father{
}
/*
报错
class Son2 extends Person1{
}*/
class Father2{
public final void method(){
System.out.println("父类方法");
}
}
class Son2 extends Father2{
//报错 final方法不能继承
// @Override
/* public void method() {
super.method();
}*/
}
/*
class Father2{
public final void method(){
System.out.println("父类方法");
}
}
class Son2 extends Father2{
//报错 final方法不能继承
// @Override
/* public void method() {
super.method();
}
}
*/
/*
class Father2{
public final void method(){
System.out.println("父类方法");
}
}
class Son2 extends Father2{
//报错 final方法不能继承
// @Override
/* public void method() {
super.method();
}
}
*/
public class TestFinal {
}