Super关键字
1、 super是一个关键字,全部小写
2、 super和this对比:
this:
this能出现在实例方法和构造方法中。
this的语法是:”this.”、”this()”
this不能使用在静态方法中。
this.大部分情况下是可以省略的,在区分局部变量和实例变量的时候不能省略。
public void setName(String name){
this.name = name
}
this()只能出现在构造方法第一行,通过当前的构造方法去调用"本类"中其它的构造方法,目的是:代码复用。
super:
super能出现在实例方法和构造方法中。
super的语法是:“super.”、“super()”
super不能使用在静态方法中。
super.大部分情况下是可以省略的
super()只能出现在构造方法第一行,通过当前的构造方法去调用"父类"中其它的构造方法,目的是:创建子类型
对象的时候,先初始化父类型特征。
3、super()
表示通过子类的构造方法父类的构造方法。
模拟现实世界中的这种场景:要想有儿子,需要先有父亲
4、重要结论
当一个构造方法第一行:
既没有this()又没有super()的话,默认会有一个super();
表示通过当前子类的构造方法调用父类的无参数构造方法。所以必须保证父类的无参构造方法是存在的。
注意:this()和super()不能共存,它们都是只能出现在构造方法第一行。
无论如何,父类的构造方法是一定会执行的
public class SuperTest01 {
public static void main(String[] args){
//创建子类对象
new B();
/*
A类的无参数构造方法
B类的无参数构造方法
*/
}
}
class A
{
public A()
{
System.out.println("A类的无参数构造方法");
}
public A(int i)
{
System.out.println("A类的有参数构造方法");
}
}
class B extends A
{
public B()
{ this("zhangsan");//输出结果:A类的无参数构造方法 B类的有参数构造方法(String) B类的无参数构造方法
//默认存在super()调用父类的无参构造
//super(123);//这里调用父类的有参数构造,此时super()不会再调用
System.out.println("B类的无参数构造方法");
/*
A类的有参数构造方法
B类的无参数构造方法
*/
}
public B(String name){
//默认存在super()
System.out.println("B类的有参数构造方法(String)");
}
}
5、补充
5.1、在恰当的时间使用:super(实际参数列表)
注意:在构造方法执行的过程中一连串调用了父类的构造方法,父类的构造方法
又继续调用它的父类的构造方法,但是实际上对象只创建了一个。
5.2、super(实参)的作用是:初始化当前对象的父类型特征,并不是创建新对象。实际上对象只创建了一个。
5.3、super关键字代表的就是"当前对象"的那部分父类型特征。
5.4、java是怎么来区分子类和父类的同名属性的?
(假设子类和父类中都有name属性)
this.name:当前对象的name属性
super.name:当前对象的父类型特征中的name属性
"super."和"this.“大部分情况下是可以省略的
5.5、this.什么时候不能省略?
public void setName(String name){
this.name = name
}
5.6、super.什么时候不能省略?
父中有,子中又有,如果在子中访问"父的特征”,super.不能省略。
5.7
在父和子中有同名的属性,或者说有相同的方法,
如果此时想在子类中访问父中的数据,必须使用"super."加以区分
super的使用:
super.属性名 [访问父类的属性]
super.方法名(实参) [访问父类的方法]
super(实参) [调用父类的构造方法]
public class SuperTest04 {
public static void main(String[] args)
{
Cats c = new Cats();
c.yidong();
/*
执行结果
Cat move!
Cat move!
Animal move!
*/
}
}
class Animals {
public void move()
{
System.out.println("Animal move!");
}
}
class Cats extends Animals
{
public void move()
{
System.out.println("Cat move!");
}
//单独编写一个子类特有的方法
public void yidong(){
this.move();
move();//省略的是this.
//super.不仅可以访问属性,也可以访问方法
super.move();
//如果注释掉对父类move的重写,则三个运行结果都是Animal move!
}
}
public class SuperTest02
{
public static void main(String[] args)
{
CreditAccount ca1 = new CreditAccount();
System.out.println(ca1.getActno() + "," + ca1.getBalance() + "," + ca1.getCredit());
CreditAccount ca2 = new CreditAccount("111",10000.0,0.99);
System.out.println(ca2.getActno() + "," + ca2.getBalance() + "," + ca2.getCredit());
}
}
//账户
class Account extends Object{
//属性
private String actno;
private double balance;
//构造方法
public Account()
{
//super();
//this.actno = null;
//this.balance = 0.0;
}
public Account(String actno,double balance)
{
this.actno = actno;
this.balance = balance;
}
//setter and getter
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;
}
}
//信用账户
class CreditAccount extends Account{
//属性 信用度 子类特有的一个特征,父类没有
private double credit;
//构造方法
public CreditAccount ()
{
}
//提供有参数的构造方法
public CreditAccount(String actno,double balance,double credit)
{
/*
this.actno = actno;
this.balance = balance;
编译报错,私有属性只能在本类中访问
*/
//通过子类的构造方法调用父类的构造方法
super(actno,balance);
this.credit = credit;
}
//setter and getter
public double getCredit() {
return credit;
}
public void setCredit(double credit) {
this.credit = credit;
}
}
以下是上述代码的原理图:
package demo;
/*
super不是引用。super不保存内存地址,也不指向任何对象。
super只是代表当前对象内部的那一块父类型的特征。
*/
public class SuperTest03 {
//实例方法
public void doSome()
{
System.out.println(this);//输出结果:demo.SuperTest03@50cbc42f
//输出"引用"的时候,会自动调用引用的toString()方法。
//System.out.println(this.toString());
//编译错误:需要"."
//System.out.println(super);
}
//this和super不能使用在static静态方法中
/*
public static void doOther()
{
System.out.println(this);
System.out.println(super.xxx);
}
*/
//静态方法,主方法
public static void main(String[] args)
{
SuperTest03 st = new SuperTest03();
st.doSome();
}
}