面向对象 - super、方法重写Override
继续深入认识面向对象
狂神说Java BV12J41137hu
super
super 可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类。
如 面向对象 - 内存分析、封装、继承 所写,继承的成员变量或者方法前缀修饰关键词必须是 public 和 protected
引用父类成员变量及方法
Person.java
package oop.app.mysuper;
public class Person {
protected String name = "PersonName";
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
protected void printName() {
System.out.println(this.name);
}
}
Student.java
package oop.app.mysuper;
public class Student extends Person{
public String name = "StudentName";
public Student() {
}
public void printName() {
System.out.println("name\t" + name);
System.out.println("this.name\t" + this.name);
System.out.println("super.name\t" + super.name);
}
public void getFatherMethod() {
super.printName();
}
}
Application.java
package oop.app.mysuper;
public class Application {
public static void main(String[] args) {
Student student = new Student();
System.out.println("引用父类成员变量");
student.printName();
//引用父类成员变量
//name StudentName
//this.name StudentName
//super.name PersonName
System.out.println("引用父类方法");
student.getFatherMethod();
//引用父类方法
//PersonName
}
}
引用父类构造器
只贴相关的代码块
Person.java
package oop.app.mysuper;
public class Person {
public Person() {
System.out.println("Person类 无参构造器");
}
}
Student.java
package oop.app.mysuper;
public class Student extends Person{
public Student() {
System.out.println("Student类 无参构造器");
}
}
Application.java
package oop.app.mysuper;
public class Application {
public static void main(String[] args) {
Student student = new Student();
//Person类 无参构造器
//Student类 无参构造器
}
}
根据 Application.java
的运行结果,明显可以看出,在 Student
类实例化过程中,其无参构造器首先执行了父类Person
的无参构造器,并且这一执行过程是最高优先级的,也即:
Student.java
源代码
package oop.app.mysuper;
public class Student extends Person{
public Student() {
super();
System.out.println("Student类 无参构造器");
}
}
上述代码块中的 super();
如果手写,必须在子类无参构造器的第一行(当然不用写,默认就是在第一行),不放在第一行必然报错
构造器中的 this() 和 super()
-
调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用 super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。
-
super() 和 this() 类似,区别是,super() 从子类中调用父类的构造方法,this() 在同一类内调用其它方法。
-
super() 和 this() 均需放在构造方法内第一行。
-
尽管可以用this调用一个构造器,但却不能调用两个。
-
this 和 super 不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有 super 语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
-
this() 和 super() 都指的是对象,所以,均不可以在 static 环境中使用。包括:static 变量,static 方法,static 语句块。
-
从本质上讲,this 是一个指向本对象的指针, 然而 super 是一个 Java 关键字。
这个东西尤其是 this() 还很复杂,源码里面 this() 暂时还看不懂!
方法重写(Override)
重写,都是指方法的重写,和属性(成员变量)无关
在Java中,子类继承父类,父类的引用可以指向子类
这里必须保证: 父类子类的方法名一致、方法名前的修饰关键字一致
修饰关键字见结论
案例 (忽略构造器等,用不到的就懒得写了)
Person.java
package oop.app.myoverride;
public class Person {
public void test() {
System.out.println("Person => test()");
}
}
Student.java
package oop.app.myoverride;
public class Student extends Person{
public void test() {
System.out.println("Student => test()");
}
}
Application.java
package oop.app.myoverride;
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test(); //Student => test()
Person studentOverride = new Student();
studentOverride.test(); //Student => test()
}
}
鼠标在IDEA中悬停,发现
student
是 Student类 ---- public class Student extends Person
studentOverride
是 Person类 ---- public class Person
,
也就是方法的调用(对象的生成)只和 new 左边的类型有关。
IDEA中的快速重写方法
在子类(当前案例是 Student)中,使用快捷键 Alt + Insert
呼出 Generate 快捷菜单,选择 Override Methods
或者直接使用快捷键 Ctrl + O
选中上图的 test()
方法后, Student 自动生成了代码块
Student.java
package oop.app.myoverride;
public class Student extends Person{
// public void test() {
// System.out.println("Student => test()");
// }
@Override
public void test() {
super.test();
}
}
暂时理解为帮我写了注解 @Override
然后在当前的 test()
方法中做对应修改
@Override
public void test() {
System.out.println("Student => test()");
}
然后就发现执行结果与第一完全不一样
Student => test()
Student => test()
而当把父子类中的 test()
方法都定义为静态方法时,Student 类不支持 IDEA快捷重写了,只能手写,
当然结果当然是会变的:
Student => test()
Person => test()
结论
-
当重写方法是静态方法 static时:方法没有被重写,对象的创建取决于
= new
左边 -
当重写方法非静态方法时:父类方法已经被子类覆盖了,而对象的创建依然取决于
= new
左边 -
修饰符:范围可以扩大但不能缩小
- public > protected > default > private
-
抛出的异常:范围可以缩小,但不能扩大* 我不理解
为什么需要重写?
- 父类的功能子类不一定需要,或者父类的功能不满足子类的需求;