this关键字
1. 什么是this关键字
this关键字总是指向调用该方法的对象。根据this出现位置的不同,this作为对象的默认引用有两种情形。
1. 构造器中引用该构造器正在初始化的对象;
2. 在方法中引用调用该方法的对象。
this关键字最大的作用就是让类中的一个方法,访问该类里的另一个方法或实例变量。
2. 例子
Dog.java
public class Dog {
public void jump() {
System.out.println("正在执行jump方法");
}
public void run() {
// Dog d = new Dog();
// d.jump();
this.jump();
System.out.println("正在执行run方法");
}
}
DogTest.java
public class DogTest {
public static void main(String[] args) {
Dog dog = new Dog();
dog.run();
}
}
大部分时候,一个方法访问该类中定义的其他方法、成员变量时加不加this前缀的效果是完全一样的。
注意:
对于static修饰的方法而言,则可以使用类来直接调用该方法,如果再static修饰的方法中使用this关键字,则这个关键字就无法指向合适的对象。所以,static修饰的方法中不能使用this引用
方法重载和方法重写
- 方法重载是overload
- 方法重写是override
- 重载和重写放在一起比较本身没有太大意义,本来就是两个不一样的东西
- 重载主要发生在同一类的多个同名方法之间,父类方法和子类方法之间也可能发生重载,因为子类会获得父类方法,如果子类定义了一个与父类方法有相同的方法名,但参数列表不同的方法,就会形成父类方法和子类方法的重载。
- 重写发生在子类和父类的同名方法之间
super限定
1. 什么是super
super是Java提供的一个关键字,super用于限定该对象调用它从父类继承得到的实例变量或方法。super也不能出现在static修饰的方法中。
2. 例子
class BaseClass {
public int a = 5;
}
public class SubClass extends BaseClass{
public int a = 7;
public void accessOwner() {
System.out.println(a);
}
public void accessBase() {
System.out.println(super.a);
}
public static void main(String[] args) {
SubClass sc = new SubClass();
sc.accessOwner();//7
sc.accessBase();//5
}
}
3. super可以调用父类中被覆盖(override)的方法
class Parent {
public String tag ="lalalala";
public String laser() {
return tag;
}
}
class Derived extends Parent {
private String tag = "hahahaha";
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
@Override
public String laser() {
return super.laser();
//return tag;
}
}
public class HideTest {
public static void main(String[] args) {
Derived d = new Derived();
//System.out.println(d.tag); //不可以访问私有变量,编译报错
System.out.println(d.getTag()); //hahahaha
System.out.println(d.laser()); //lalalala
System.out.println(((Parent) d).tag); //将d变量显式地向上转型为Parent后,即可访问ta实例变量
}
}
4. 调用父类构造器
子类构造器里可以调用父类构造器的初始化代码,一个构造器调用另一个重载的构造器。
在一个构造器中调用另一个重载的构造器使用this调用完成,在子类构造器中调用父类构造器使用super调用来完成。
class Base {
public double size;
public String name;
public Base(double size, String name) {
this.size = size;
this.name = name;
}
}
public class Sub extends Base{
public String color;
public Sub(double size, String name, String color) {
super(size, name);
this.color = color;
}
public static void main(String[] args) {
Sub s = new Sub(5.6, "测试对象", "红色");
System.out.println(s.size + "__" + s.name + "__" + s.color);
}
}
this调用和super调用不会同时出现
不管是否使用super调用来执行父类构造器的初始化代码,子类构造器总会调用父类构造器一次。
子类构造器调用父类构造器有三种情况
- 使用super显式调用父类构造器
- 使用this显式调用本类中重载的构造器
- 子类构造器执行体中没有super调用,也没有this调用,系统将会在执行子类构造器之前,隐式调用父类无参数的构造器。
class Creature {
public Creature() {
System.out.println("Creature无参数的构造器");
}
}
class Animal extends Creature {
public Animal(String name) {
System.out.println("Animal 带一个参数的构造器,"+"该动物的name为"+name);
}
public Animal(String name, int age) {
this(name);
System.out.println("Animal带两个参数的构造器," + "其age为" + age);
}
}
public class Wolf extends Animal{
public Wolf() {
super("灰太狼", 3);
System.out.println("Wolf无参数的构造器");
}
public static void main(String[] args) {
new Wolf();
}
}
创建任何对象总是从该类所在继承树最顶层类的构造器开始执行,然后一次向下执行,最后才执行本类的构造器。如果某个父类通过this调用了同类中重载的构造器,就会依次执行此父类的多个构造器。