零基础学Java,肝了bilibili的6百多集JavaSE教程传送门的学习笔记!!!
下面博客分为两部分:
- ① super关键字的要点(想快速了解super关键字的小伙伴选择)
- ② 案例代码,对①中的知识点进行解释(需要再花费8分钟学习的小伙伴选择)
一、super关键字的要点
1、super是一个关键字
2、super和this对比着学习:
this:
this出现在实例方法和构造方法中。
this的使用: "this. " 、 “this()”
this不能出现在静态方法中
"this. "大部分情况下可以省略,但是在区分局部变量和实例变量的时候不能省略。
“this()”,出现在构造方法第一行,调用其它的构造方法,实现代码复用。super:
super出现在实例方法和构造方法中。
super的使用: "super. " 、 “super()”
super不能使用在静态方法中
"super. "大部分情况下是可以省略的"super()"只能出现在构造方法第一行,通过当前的构造方法去调用"父类"中的构造方法。
目的是: 创建子类对象之前,先初始化父类型特征。
3、super()
表示通过子类的构造方法调用父类的构造方法
模拟现实世界中的这种场景: 要想有儿子、必须先有父亲。
4、重要结论:
当一个构造方法第一行:
既没有this()又没有super()的话,默认会有一个super();
表示通过当前子类的构造方法调用父类的无参数构造方法。
使用必须保证父类的无参数构造方法是存在的。
5、注意: this()和super()不能共存,因为它们都必须在构造方法第一行
6、无论代码这么折腾,父类的构造方法是一定会执行的。
二、案例代码
① SuperTest01.java
初步使用super()
public class SuperTest01 {
public static void main(String[] args) {
// 创建子类对象
new B();
/**输出结果:
* A类的无参数构造方法!
* B类的无参数构造方法!
*
*/
}
}
class A {
public A() {
System.out.println("A类的无参数构造方法!");
}
}
class B extends A {
public B() {
// super(); // 实际上这行代码是存在的,不过给省略了。
System.out.println("B类的无参数构造方法!");
}
/**
* super()的作用是调用父类的构造方法,
* ()里为空代表的是调用父类的无参数构造方法。
*
* 此时,如果A类中只有个有参数构造方法,
* 例如public A(int a) {}, 那么此时运行代码就会报错!
* 因为省略的super()无法调用到A类中的无参数构造方法。
*
*/
}
② SuperTest02.java
运行代码得出一个重要结论:
子类构造方法执行时必然调用父类构造方法
所以在java语言中不管时new什么对象,最后老祖宗的Object类的无参数构造方法 一定会执行。
并且Object类中的无参数构造方法是出于"栈顶部"
的,栈顶是最后被调用,最先执行结束的
。
所以下面的运行结果,是先执行完Object的无参数构造方法,才执行System.out.println(“1: A2的无参数构造方法执行!”);
注意:
写代码的时候,建议把类的无参数构造方法一起写出来
如果没有写的话,可能会影响到"子类对象的创建"
public class SuperTest02 {
public static void main(String[] args) {
new C2();
/**运行结果:
* 1: A2的无参数构造方法执行!
* 3: B2的有参数构造方法执行(String)
* 6: C2的有参数构造方法执行(String, int)
* 5: C2的有参数构造方法执行(String)
* 4: C2的无参数构造方法执行!
*
*/
}
}
class A2 {
public A2() {
System.out.println("1: A2的无参数构造方法执行!");
}
}
class B2 extends A2 {
public B2() {
System.out.println("2: B2的无参数构造方法执行!");
}
public B2(String name) {
System.out.println("3: B2的有参数构造方法执行(String)");
}
}
class C2 extends B2 {
public C2() {
this("zhangsan");
System.out.println("4: C2的无参数构造方法执行!");
}
public C2(String name) {
this("zhangsan", 18);
System.out.println("5: C2的有参数构造方法执行(String)");
}
public C2(String name ,int age) {
super(name);
System.out.println("6: C2的有参数构造方法执行(String, int)");
}
}
③ SuperTest03.java
super(实参)的用法
1、注意:在构造方法执行过程中一连串调用父类的构造方法,父类的构造方法又继续向下调用它的父类的构造方法,但是实际上对象只创建一个。
2、思考:super(实参) 到底是干什么的?
初始化当前对象的父类型特征。
并不是创建创建新对象,实际上对象只创建一个。
3、super关键字代表“当前对象”
的那部分父类型特征。
public class SuperTest03 {
public static void main(String[] args) {
CreditAccount ca1 = new CreditAccount();
System.out.println(ca1);
CreditAccount ca2 = new CreditAccount("201801",1024.00,99.9);
System.out.println(ca2);
}
}
class Account {
private String actno;
private double balance;
public Account() {
}
public Account(String actno, double balance) {
this.actno = actno;
this.balance = balance;
}
// get and set
public String getActno() {
return actno;
}
public void setActno(String actno) {
this.actno = actno;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
@Override
public String toString() {
return "Account{" +
"actno='" + actno + '\'' +
", balance=" + balance +
'}';
}
}
class CreditAccount extends Account {
private double credit;
public CreditAccount() {
}
public CreditAccount(String actno, double balance, double credit) {
super(actno, balance); // 关键知识点!
this.credit = credit;
}
// get and set
public double getCredit() {
return credit;
}
public void setCredit(double credit) {
this.credit = credit;
}
@Override
public String toString() {
return "CreditAccount{" +
"credit=" + credit +
'}';
}
}
④ SuperTest04.java
super关键字代表“当前对象”的那部分父类型特征
public class SuperTest04 {
public static void main(String[] args) {
Vip v = new Vip("zhangsan");
v.shopping();
}
}
class Customer {
String name;
public Customer() {
}
public Customer(String name) {
this.name = name;
}
}
class Vip extends Customer {
public Vip() {
}
public Vip(String name) {
super(name);
}
// 注意:this和super都不能出现在静态方法里。
public void shopping() {
// this表示当前对象。
System.out.println(this.name + " shopping!");
// super表示当前对象的父类型特征。
System.out.println(super.name + " shopping!");
System.out.println(name + " shopping!");
}
}
⑤ SuperTest05.java
super什么时候不能省略?
当子类和有一个和父类一样的同名属性
public class SuperTest05 {
public static void main(String[] args) {
Vip2 v = new Vip2("zhangsan");
v.shopping();
}
}
class Customer2 {
String name;
public Customer2() {
}
public Customer2(String name) {
this.name = name;
}
}
class Vip2 extends Customer2 {
// 假设子类和有一个和父类一样的同名属性。
String name;
public Vip2() {
}
public Vip2(String name) {
super(name);
// this.name = null; // 本类的name
}
// 此时输出结果就和SuperTest04的不一样了。
// this.name和super.name表示的内容不一样了
public void shopping() {
System.out.println(this.name + " shopping!"); // null
System.out.println(super.name + " shopping!"); // zhangsan
System.out.println(name + " shopping!"); // null
}
}
⑥ SuperTest06.java
进一步了解super:
super 不是引用
super也不保存内存地址,super也不指向任何对象
public class SuperTest06 {
// 实例方法
public void doSome() {
System.out.println(this);
// 输出"引用"的时候,会自动调用引用的toString()方法。
// 编译报错,不能单独使用super,需要使用"super. ".
// System.out.println(super);
}
// 静态方法,主方法
public static void main(String[] args) {
SuperTest06 superTest06 = new SuperTest06();
superTest06.doSome();
}
}
⑦ SuperTest07.java
super调用父类对象
public class SuperTest07 {
public static void main(String[] args) {
Cat c = new Cat();
c.doSome();
}
}
class Animal {
public void move() {
System.out.println("Animal move!");
}
}
class Cat extends Animal {
@Override
public void move() {
System.out.println("Cat move!");
}
// 子类特有方法
public void doSome() {
this.move();
move();
super.move();
}
}