Java中super的运行原理(super如何在内存中运行的)以及super和this的对比

Posted TGB-Earnest

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中super的运行原理(super如何在内存中运行的)以及super和this的对比相关的知识,希望对你有一定的参考价值。

一、super关键字的了解,以及和this的比较

(1)super()什么时候使用

//银行账户类
//账户的属性:账号、余额
//父类
class Account
    //属性
    private String actno;
    private double balance;
 
    //构造方法
    public Account()
    
    public Account(String actno, double balance)
        this.actno = actno;
        this.balance =balance;
    
    //setter and getter
    public void setActno(String actno)
        this.actno = actno;
    
    public String getActno()
        return actno;
    
    public void setBalance(double balance)
        this.balance = balance;
    
    public double getBalance()
        return balance;
    



//其他类型的账户,信用卡账户
//账户、余额、信誉度
class CreditAccount extends Account
 
    //属性
    private double credit;
    //构造方法
    public CreditAccount()
    
    //setter and getter方法
    public void setCredit(double credit)
        this.credit = credit;
    
    public double getCredit()
        return credit;
    


 如果我把上面改成下面:

public CreditAccount(String actno,double balance , double credit)
    this.actno = actno;
    this.balance = balance;
    //以上两个都是父类的私有属性
    this.credit = credit;

这个时候就会产生报错,因为私有属性是不能在类外进行访问的。

如果我们想要访问了怎么办呢?这个时候就用到了super。

public CreditAccount(String actno,double balance , double credit)
    super(actno,balance);
    this.credit = credit;

(2)super在对象创建的时候起到了什么作用

	public class SuperTest
	
		public static void main(String [] args)
			new B();
		;
	
	class A
	
		public A()
		System.out.println("A类的无参数构造方法");
		
		
	
	class B extends A
	
		public B()
		System.out.println("B类的无参数构造方法");
		
	

这时候控制台会输出

所以说,在创建子类的时候都会走一下父类 ,有儿子必须有父亲。其实public B()这里面第一行有一个默认的super();

当我们改一下程序

	public class SuperTest
	
		public static void main(String [] args)
			new B();
		;
	
	class A
	
		//public A()
		//System.out.println("A类的无参数构造方法");
		//
		public A(int i)
		
		
	
	class B extends A
	
		public B()
		System.out.println("B类的无参数构造方法");
		
	

 其实这时候

pulic B()
	
		super();
	

super()它会去调用A无参数的构造方法,但是A中没有无参数的构造方法,只有public A(int i);所以就会报错了,建议将一个类中无参数构造方法要写出来。

所以结论:(a)即没有this()也没有super(),默认会有一个super(),表示当前通过子类的构造方法调用父类的无参数构造方法,所以必须保证父类的无参数构造方法是存在的。(c)this()和super不能共存,他们都是只能出现在构造方法第一行。

(b)无论怎么折腾,父类中的构造方法一定会执行。

	public class SuperTest
	
		public static void main(String [] args)
			new B();
		;
	
	class A
	
		public A()
		System.out.println("A类的无参数构造方法");
		
		public A(int i)
		
		
	
	class B extends A
	
		public B()
			this("zhangsan");
			//调用父类中有参数的构造方法
			System.out.println("B类中无参数构造方法!");
		
		public B(String name)
			super();
			System.out.println("B类中有参数构造方法(String)");
		
	

(3)子类构造方法执行时必然调用父类的构造方法

在java语言中不管是new什么对象,最后object类的无参数构造方法一定会执行(Object类的无参数构造方法是处于"栈顶部")。

二、super的执行原理(super在内存中的体现)

super代表的是当前对象的父类型特征

//银行账户类
//账户的属性:账号、余额
//父类
class Account
    //属性
    private String actno;
    private double balance;
 
    //构造方法
    public Account()
    
    public Account(String actno, double balance)
        this.actno = actno;
        this.balance =balance;
    
    //setter and getter
    public void setActno(String actno)
        this.actno = actno;
    
    public String getActno()
        return actno;
    
    public void setBalance(double balance)
        this.balance = balance;
    
    public double getBalance()
        return balance;
    


//其他类型的账户,信用卡账户
//账户、余额、信誉度
class CreditAccount extends Account
 
    //属性
    private double credit;
    //构造方法
    public CreditAccount()
    
    //setter and getter方法
    public void setCredit(double credit)
        this.credit = credit;
    
    public double getCredit()
        return credit;
    

//使用继承机制来解决代码复用问题
public class ExtendTest01
 
    public static void main(String [] args)
        //创建普通账户
        Account act = new Account();
        act.setActno("11111");
        act.setBalance(10000);
        System.out.println(act.getActno() + "余额" +act.getBalance());
        //创建信用账户
        CreditAccount ca = new CreditAccount();
        act.setActno("222222");
        act.setBalance(-10000);
        System.out.println(act.getActno() + "余额" +act.getBalance());
    

new CreditAccount它是Account的子类,Account又是Object的子类,所以会调用object,初始化了objtct之后,再初始化Account,然后再初始化CreditAccount,这时候Account的super代表着object的特征,CreditAccount代表这Account的特征,

问题:(1)这个图中一共创建了几个对象?

1个对象。虽然调用构造方法,在调用方法执行过程中一连串调用了父类的构造方法,父类的构造方法又继续向下调用它的父类的构造方法,但是实际上对象只调用了一个。

(2)super(实参)到底是做什么的?

super(实参)的作用是:初始化当前对象的父类型特征

(3)super关键字代表什么?

super关键字代表的就是“当前对象”的那部分父类型特征。


public class SuperTest02

	public static void (String [] args)
		Vip v = new Vip("张三");
		v.shopping();
	

class Customer

	String name;
	public Customer()
	public Customer(String name)
		this.name = name;
	

class Vip

	public vip()
	public vip(String name)
		super(name);
	
	//这个方法不能是静态的,super不能出现在静态方法中。
	public void shopping()
		System.out.println(name +"正在购物");
		System.out.println(this.name +"正在购物");
		System.out.println(super.name +"正在购物");
	

 我们再把代码改一下:

class Vip

    //假设子类中也有一个同名的属性
    String name;
	public vip()
	public vip(String name)
		super(name);
        //this.name = null;
	
	//这个方法不能是静态的,super不能出现在静态方法中。
	public void shopping()
		System.out.println(name +"正在购物");
		System.out.println(this.name +"正在购物");
		System.out.println(super.name +"正在购物");
	

从上图可以看出,java中允许在子类中出现和父类一样的同名变量/同名属性。

(a)super.什么时候不能省略?

 如果父类和子类有同名属性,并且在子类中想要方法父类的属性。

(b)java是怎么区分子类和父类的同名属性的?

this.和super.

(c)super不保存内存地址,super也不指向任何对象,super知识代表当前对象的那一块父类型特征

public class SuperTest03

	public static void main(String [] args)
		
		Dog D1 = new Dog();
		D1.test();
	

class Animal

	public void move()
		System.out.println("动物在移动");
	

class Dog extends Animal

	public void move()
		System.out.println("狗在跑");
	
	public void test()
		this.move();
		move();
		super.move();
	


 

(三)总结:super和this的区别

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.什么时候不能省略呢?在区分父类和子类同名属性

super()只能出现在构造方法第一行,通过当前的构造方法区调用"本类"中其它的构造方法,目的是:代码复用。

目的是:创建子类对象的时候,先初始化父类型特征(创建子类对象的时候,先创建父类对象)

 

以上是关于Java中super的运行原理(super如何在内存中运行的)以及super和this的对比的主要内容,如果未能解决你的问题,请参考以下文章

零基础学Java|在实例方法中如何使用super关键字

类继承super原理

我的程序中有一个抽象类。如何在 Java 中使用“super”关键字? [关闭]

java-继承进阶_抽象类_接口

super和final关键字

在java中的super调用之前创建一个对象