final关键字代表最终的、不可改变的
常见的四种用法:
① 可以用来修饰一个类
② 可以用来修饰一个方法
③ 可以用来修饰一个局部变量
④ 可以用来修饰一个成员变量
public final class 类名称 {
...
}
作用:使当前这个类不能有任何子类。(“太监类”)
注意:一个类如果是final的,那么其中所有的成员方法都无法进行覆盖重写
修饰符 final 返回值类型 方法名称(参数列表) {
方法体
}
作用:当final关键字用来修饰一个方法的时候,这个方法就是最终方法,不能够被覆盖重写
注意:对于类、方法来说,abstract关键字和final关键字不能同时使用,因为作用相互矛盾
// ① 第一种基本数据类型情况下的格式
final 基本数据类型 数据名称 = 值;
// ② 引用数据类型情况下的格式
final 类型 对象名 = new 类名();
//例如:final Student stu = new Student();
作用:当final关键字用于修饰局部变量的时候,这个局部变量就不能更改,“一次赋值,终生不变”
注意:对于 基本类型 来说,不可改变指的是变量当中的数据不可改变,但是对于 引用类型 来说,不可改变的指的是变量当中的地址值不可改变
对于成员变量来说,如果使用了final关键字修饰,那么这个变量也照样是不可变的
① 由于成员变量具有默认值,所以用了final之后必须手动赋值,不会再给默认值了
② 对于final的成员变量,要么使用直接赋值,要么通过构造方法赋值,只能二选一
③ 必须保证类当中所有重载的构造方法,都最终会对final的成员变量进行赋值
this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针。
this不能出现在静态方法中
this的用法在java中大体可以分为3种:
this.方法
让类中一个方法,访问该类里的另一个方法或实例变量。
// 定义一个run()方法,run()方法需要借助jump()方法
public void run() {
// 使用this引用调用run()方法的对象
this.jump();
System.out.println("正在执行run方法");
}
注意:这也可以不用写this,因为调用的是本类中的其他方法,不需要区分
this.属性
当局部变量与全局变量同名时,总是指向局部的变量(就近原则)。若要指向全局变量,就用 this.属性名 指向成员变量。
若不同名无冲突,则可以省略this。
public Person(String name, int age) {
this.name = name;
this.age = age;
}
引用本类的构造函数:this([参数1,参数2,…])
调用本类中的其他构造方法,调用时要放在构造方法的首行,目的是:代码复用。
this( ) 不能在普通方法中使用,只能写在构造方法中。
class Person{
private String name;
private int age;
public Person() {
}
public Person(String name) {
this.name = name;
}
public Person(String name, int age) {
this(name); // 引用本类的构造方法
this.age = age;
}
}
super和this类似,它指向了当前对象自己的父类型特征(也就是继承过来的那些东西)。
super和this区别是:this可以看做一个引用变量,保存了该对象的地址,是当前对象整体,而super代表的是父类型特征,是子类局部的一些东西,这些继承过来的东西已经在子类里面了,你可以输出整体this,但不能输出父类型特征super。因为super指向的东西不是一个整体,没法打印输出。
System.out.println(this); //输出this.toString()的值
System.out.println(super); //编译报错,需要'.'
当在子类对象中,子类想访问父类的东西,可以使用“super.”的方式访问。例如:方法覆盖后,子类内部虽然重写了父类的方法,但子类也想使用一下父类的被覆盖的方法,此时可以使用“super.”的方式。当子类中出现和父类一样的属性或者方法,此时,你要想去调用父类的那个属性或者方法,此时“super.”不能省略。
this和super都只能在对象内部使用。this代表当前对象本身,super代表当前对象的父类型特征。
“this.”是一个实例对象内部为了区分实例变量和局部变量。
“super.”是一个实例对象为了区分是子类的成员还是父类的成员。
普通的直接引用
与this类似,super相当于是指向当前对象的父类的引用,这样就可以用super.xxx来引用父类的成员。
子类中的成员变量或方法与父类中的成员变量或方法同名时,用super进行区分
引用父类构造函数
示例
public class superthis {
public static void main(String[] args) {
Student s0 = new Student();
s0.getInfo();
s0.printinfo();
Student s1 = new Student("子类属性");
s1.getInfo();
s1.printinfo();
Student s2 = new Student("Father","Child");
s2.getInfo();
s2.printinfo();
}
}
class Person{
protected String name;
public Person(){
System.out.println("父类无惨构造方法");
}
public Person(String name) {
this.name = name;
}
}
class Student extends Person{
private String name; // 与父类同名属性
public Student(){ // 子类构造方法会隐式调用父类的无参构造方法super()
System.out.println("子类无参构造方法");
}
public Student(String name1) { // 子类构造方法会隐式调用父类的无参构造方法super()
this.name = name1;
}
public Student(String name, String name1) {
super(name); // 子类构造方法已经调用了父类构造方法,则不会再隐式调用父类的无参构造方法super()
this.name = name1;
}
public void getInfo(){
System.out.println(this.name); //Child
System.out.println(super.name); //Father
}
public void printinfo(){
//System.out.println(super); // 这一行会编译报错:java:需要.
System.out.println(this);
}
}
输出:
父类无惨构造方法 // 子类构造方法会隐式调用父类的无参构造方法super()
子类无参构造方法
null
null
com.fazi.Student@1b6d3586
父类无惨构造方法 // 子类构造方法会隐式调用父类的无参构造方法super()
子类属性
null
com.fazi.Student@4554617c
Child
Father
com.fazi.Student@74a14482
static修饰的东西一般情况下跟对象无关。可以使用的场景:
被static修饰的变量或者方法是独立于该类的任何对象,也就是说,这些变量和方法不属于任何一个实例对象,而是被类的所有的实例对象所共享。
修饰成员变量,这个变量就不属于对象了,而属于类本身,我们就可以通过“类名.属性名”
只要通过我这个类创建的对象,这些对象都可以共享这个属性
当其中一个对象对类变量进行更改后,其他对象的这个类变量也会更改,以最后的为准
类变量是随着类的加载而加载
类变量放在方法区的静态域里面
public class staticDm {
public static void main(String[] args) {
Person.country = "国家"; // 中国 ->国家
Person per2 = new Person("小泉",50);
Person.country = "小日本"; // 国家 ->小日本
Person per1 = new Person( "张三",18);
Person.country = "祖国"; // 最后的赋值:小日本 -> 祖国,所有的类变量都是最后的赋值
per1.show();
per2.show();
System.out.println("类属性cuntry为:" + Person.country); // 直接调用类属性
}
}
class Person {
String name;
int age;
static String country = "中国";
public Person(String name,int age){
this.name = name;
this.age = age;
}
void show() {
System.out.println("姓名为:" + name + ",年龄为:" + age + ",国籍为:" + country);
}
}
输出:
姓名为:张三,年龄为:18,国籍为:祖国
姓名为:小泉,年龄为:50,国籍为:祖国
类属性cuntry为:祖国
final和static的区别
修饰方法,这个方法就属于类本身了,我可以通过"类名。方法名()"就行调用
随着类而加载
在静态方法里面只能调用静态变量和静态方法,相反在普通方法里可以调用静态方法和静态变量
不能使用this和supper关键字。
加了static的方法,不能再方法内部访问非static的属性和行为;
原因:1、在静态方法的内部无法确认非static的内容属于哪个对象,它是通过类名调用,这时没有对象----这就相当于工具类
2、static修饰的方法,在类加载的时候是被首先加载的,然后加载非static内容,所以加载static时 是不知道非static内容的
**总结:**只有调用的时候无需考虑对象时,才定义为static—工具类的工具方法,可以被定义为static方法
工具类:没有产生对象的必要,只要实现某个功能即可,哪个对象完成的都没有影响,比如:分页,转换时间,连接数据库等
工具方法:该方法在完成功能的时候,不会对对象的数据产生任何影响
static修饰代码块
代码块的作用完成初始化
非静态代码块:
可以给类的属性进行初始化操作,同时还可以调用类的方法(静态的,非静态的)
里面可以有输出语句
每创建完一个对象,非静态代码块就加载一次
静态代码块:
里面可以有输出语句
随着类加载而加载,只会执行一次,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行
静态代码的加载时机早于非静态代码块
静态代码块里只能调用类变量和类方法(静态属性和方法)
作用:jdbc 驱动 用户名 密码 数据库的链接地址
对属性赋值的方法:(1)默认初始化(2)显式的初始化(3)通过set方法或者构造方法(4)代码块
static修饰内部类
static不能修饰普通类,只能修饰内部类,被static修饰的内部类的创建方式: new OuterClass.InnerClass()