根据b站韩顺平教育java教学视频学习的学习笔记。个人学习理解,如有疏漏,敬请改正。
1、this关键字
Java虚拟机会给每个对象分配this,代表当前对象(简单的说,哪个对象调用,this就代表哪个对象)
·this关键字可以用来访问本类的属性、方法、构造器
this.属性名:用来区分当前类的属性和方法内与属性同名的局部变量
public Season(String season,String desc){ this.season = season; this.desc = desc; }
this.方法名(参数列表):让类中的一个方法来访问类中的另一个方法或者实例变量
public void function1(){ System.out.println("方法一"); } public void function2(){ System.out.println("方法二"); //调用方法1的方式一 function1(); //调用方法1的方式二,当该类继承了一个类时,this就可以用来与继承的类里的方法区别 this.function1(); }
this(参数列表):this()可以用来访问本类的构造方法,依据参数列表判断调用的是哪个构造器
①this()不能在普通方法中使用,只能在构造方法中使用(即在一个构造器中调用另一个构造器)
②this()在构造方法中使用必须是第一条语句
③在一个类下两个构造方法中不能通过this()相互调用
④不能与super()同时使用public Season(){ this("SPRING","春"); System.out.println("无参构造器"); } public Season(String season,String desc){ this.season = season; this.desc = desc; System.out.println("芜湖!"); }
·this不能在类定义的外部使用,只能在类定义的方法中使用
2、super关键字
super代表父类的应用,用于访问父类的属性、方法、构造器
super.属性名:访问父类的属性,但不能访问父类的private属性
super.方法名(参数列表):访问父类的方法,但不能访问父类的private方法
Super(参数列表):访问父类的构造器
public class SuperDemo { public int n1; public int n2; public SuperDemo(int n1, int n2) { this.n1 = n1; this.n2 = n2; } public void info(){ System.out.println("我是父类"+n1); } } class SuperInfo extends SuperDemo{ public SuperInfo(int n1, int n2) { super(n1, n2); } @Override public void info(){ System.out.println(super.n1 + "我是子类"); super.info(); } }
super关键字的好处
·调用父类的构造器:分工明确,父类属性由父类初始化,子类的属性由子类初始化。
class SuperInfo extends SuperDemo{ public int n3; public SuperInfo(int n1, int n2,int n3) { super(n1, n2); this.n3 = n3; }
·当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。如果没有重名,使用super、this和直接访问是一样的效果。
·super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;如果多个基类(上级类)中都有同名的成员,使用super访问遵循就近原则。
类在查找某一属性或方法时,过程如下
①先找本类,如果有,则调用
②如果没有,则找父类(如果有并可以调用,则调用)
③如果父类没有则继续找父类的父类,一直如此直到Objeck类
super与this的比较
区别点 | This | Super | |
1 | 访问属性 | 访问本类中的属性,如果本类没有此属性则从父类中继续查找 | 访问父类中的属性 |
2 | 调用方法 | 访问本类中的方法,如果本类没有此方法则从父类中继续查找 | 直接访问父类中的方法 |
3 | 调用构造器 | 调用本类构造器,必须放在构造器首行 | 调用父类构造器,必须放在子类构造器的首行 |
4 | 特殊 | 表示当前对象 | 子类中访问父类对象 |
3、static关键字
static是静态修饰符,修饰变量、方法、常量
所谓静态就是指在编译后所分配的内存会一直存在,直到程序退出内存才会释放这个空间,也就是只要程序在运行,那么这块内存就会一直存在。用static修饰的成员属于类,不属于对象,被同一个类的各个对象所共享,可以通过类名直接访问这些成员。
·静态变量
静态变量可以被类内的方法赋值,构造器不可以(静态成员不属于对象)
·静态方法
在静态方法中只能访问静态变量和调用静态方法,普通方法可以调用静态方法
·静态常量
public final static String NAME = "MADDOX_ZDZ";
·静态块
静态块在类加载时最先执行且每次加载只执行一次,优先级高于构造器和普通代码块
·实例
public class StaticInfo { public static void main(String[] args) { StaticDemo zdz = new StaticDemo(21); System.out.println(StaticDemo.name); StaticDemo.info(); System.out.println(StaticDemo.SEX); zdz.demo(); System.out.println("----静态代码块不会再执行------"); StaticDemo xiaos = new StaticDemo(21); } } class StaticDemo{ public static String name;//静态变量,可以被类内的方法赋值 public final static String SEX = "男";//常量值不可变 public int age; public StaticDemo(int age) { this.age = age; System.out.println(age); } //代码块在静态代码块后执行 优先级同样高于构造器 { System.out.println("这是代码块"); } //静态块在类加载时最先执行且每次加载只执行一次,优先级高于构造器和普通代码块 static { System.out.println("这是静态代码块"); } public void demo(){ name = "Maddox";//对静态变量赋值 System.out.println("这是普通方法!"); System.out.println(name); info(); } public static void info(){ System.out.println("这是静态方法"); } }
运行截图
4、final关键字
可以修饰类、属性、方法和局部变量
使用final的场景
·当不希望类被继承时,可以用final修饰
final class Father{}
·当不希望父类的某个方法被子类覆盖/重写时,可以用final修饰
public final void hitSon(){}
·当不希望类的某个属性的值被修改,可以用final修饰(常量)
public final String NAME = "MADDOX_ZDZ";
·当不希望某个局部变量被修改,可以用final修饰
public void hitSon(){ final int num = 100; int count = 0; count++; System.out.println("I aming been hit!"); }
注意事项和细节
·final修饰的属性又叫常量,一般用XX_XX_XX(大写)来命名
·final修饰的属性在定义时,必须赋初值,并且以后不能再修改,赋值可以在如下位置之一
①定义时
②在构造器中
③在代码块中
public final String NAME = "MADDOX_ZDZ"; public final String CONTEXT; public Father(String CONTEXT){ CONTEXT = "Hello!"; } {CONTEXT = "Hello World!";}//代码块
·如果final修饰的属性是静态的,则初始化的位置只能是
①定义时
②在静态代码块
不能在构造器中赋值
·final类不能继承,但是可以实例化对象
·如果类不是final类,但是含有final方法,则该方法虽然不能重写但是可以被继承(不可以更改但是可以用)
·一般来说,如果一个类已经是final类了,就没有必要用final修饰方法了
·final不能修饰构造器
·final和static往往搭配使用,效率更高,不会导致类加载,底层编译做了优化处理
·包装类(Integer,Double,Float,Boolean等都是final),String也是final类。
final的本质就是最终、最后,不能再修改