Java基础super关键字详解

简介: Java基础super关键字详解

—:super概述:


1.super能出现在实例方法和构造方法中。


super的语法是:“super.”,“super()”

super不能使用在静态方法中

super. 大部分情况下是可以省略的

2.super();


表示通过子类的构造方法调用父类的构造方法

模拟现实世界中的这种场景:要想有儿子,需要先有父亲

2.重要结论:


当一个构造方法第一行:


既没有this()又没有super()的话,默认会有一个super(); 表示通过当前子类的构造方法调用父类的无参构造方法, 所以必须保证父类的无参数构造方法是存在的

3.注意


this()和super()不能共存,它们都是只能出现在构造方法第一行


示例代码01:


public class SuperTest01{
  public static void main(String[] args){
    new B();
  }
}
class A{
  //建议手动的将一个类的无参数构造方法写出来
  public A(){
  System.out.println("A类的无参构造方法!");
  }
  //一个类中如果没有手动提供任何构造方法,系统会默认提供一个无参数构造方法
  //一个类如果手动提供了一个构造方法,那么无参数构造系统将不再提供
  public A(int n){
  System.out.println("A类的有参构造方法!(int n)");
  }
}
class B extends A{
  /* public B(){
  super(123);
  System.out.println("B类的无参数构造方法");
  } */
  public B(){
  super();//调用父类中有参数的构造方法
  //super(100);
  this("zhangsan");
  System.out.println("B类的无参构造方法!");
  }
  public B(String name){
  super(100);
  System.out.println("B类的有参构造方法!(String name)");
  }
}


运行结果:


0a2653c851af460fa595bd959398a8f1.png


二:super的子类构造方法执行时必然调用父类构造方法


在java语言中不管是new什么对象,最后老祖宗的Object类的无参数构造方法


示例代码02:


public class SuperTest02{
  public static void main(String[] args){
  new C();
  }
}
//老祖宗
/* class Object(){
  public Object(){
  }
} */
class A{
  public A(){
  System.out.println(1);
  }
}
class B extends A{
  public B(){
  this("zhangsan");
   System.out.println(2);
  }
  public B(String name){
  System.out.println(3);
  }
}
class C extends B{
    public C(){
  this("lisi");
  System.out.println(4);
  }
  public C(String name){
  this("lisi",5);
  System.out.println(5);
  }
  public C(String name,int a){
  super(name);
  System.out.println(6);
  }
}


运行结果:


2d65d23f6d4748949b924e4057485923.png


三:super实参的用法


1、举个例子:在恰当的时间使用:super(实际参数列表);


2、注意:在构造方法执行过程中一连串调用了父类的构造方法,父类的构造方法又继续向下调用它的父类的构造方法,但是实际上,对象只创建了一个。


3、思考:“super(实参)”到底是干啥的?


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

并不是创建新对象。实际上对象只创建了1个。

4、super关键字代表什么呀?


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

我继承了我父亲的一部分特征:

  例如:眼睛、皮肤等.

  super代表的就是“眼睛、皮肤等”。

  “眼睛、皮肤等”虽然是继承了父亲的,但这部分是在我身上呢。


示例代码03:


public class SuperTest03{
  public static void main(String[] args){
  CreditAccount ca1 = new CreditAccount();
  System.out.println(ca1.getActno() + " " + ca1.getBalance() + " " + ca1.getCredit() + " ");
  CreditAccount ca2 = new CreditAccount("123456",500000.0,"123556");
  System.out.println(ca2.getActno() + " " + ca2.getBalance() + " " + ca2.getCredit() + " ");
  }
}
class Account{
  private String actno;
  private double balance;
  public Account(){
  }
  public Account(String actno,double balance){
  this.actno = actno;
  this.balance = balance;
  }
  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 String credit;
  public CreditAccount(){
  }
  //提供有参数的构造方法
  public CreditAccount(String actno,double balance,String credit){
  //私有的属性,只能在本类中访问
  /* this.actno = actno;
  this.balance = balance; */
  //以上两行代码在恰当的位置,正好可以使用:super(actno,balance);
  //通过子类的构造方法调用父类的构造方法
  super(actno,balance);
  this.credit = credit;
  }
    public String getCredit() {
  return credit;
  }
  public void setCredit(String credit) {
  this.credit = credit;
  }
    public CreditAccount(String credit){
      this.credit = credit;
    }
}


运行结果:


6de278e6d6694ce5bb08e7e842b7e74b.png


内存分析图一:


12c3b7f3f8814309a195c64f051d4445.png


示例代码04:


public class SuperTest04{
  public static void main(String[] args){
  Vip v = new Vip("张三");
  v.shopping();
  }
}
class Customer{
  String name;
  public Customer(){
  }
  public Customer(String name){
  super();
  this.name = name;
  }
  public String getName(){
  return name;
  }
  public void SetName(String name){
  this.name = name;
  }
}
class Vip extends Customer{
  public Vip(){
  }
  public Vip(String name){
  super(name);
  }
  //super和this都不能出现在静态方法中
  public void shopping(){
  //this表示当前对象
  System.out.println(this.name + "在购物!");
  //super表示的是当前对象的父类型特征。(super是this指向的那个对象中的一块空间)
  System.out.println(super.name + "在购物!");
  System.out.println(name + "在购物!");
  }
}


运行结果:


34e8d716411043c08c7ffba9fbba23de.png


内存分析图二:


92ba0822ed0b46e1ae72df8a17d3a45b.png


内存分析图三:


d79b274929334152a6d38be91e2d1be3.png


四:super什么时候不能省略


1."this."和“super.”大部分情况下都是可以省略的


2.this.什么时候不能省略?


public void setName(String name){
     this.name = name;
    }


3.super.什么时候不能省略?


父中有,子中又有,如果想在子中访问“父的特征”,super.不能省略


示例代码05:


public class SuperTest05{
  public static void main(String[] args){
  Vip v = new Vip("张三");
  v.shopping();
  v.doSome();
  }
}
class Customer{
  String name;
  public Customer(){
  }
  public Customer(String name){
  super();
  this.name = name;
  }
  public String getName(){
  return name;
  }
  public void SetName(String name){
  this.name = name;
  }
  public void doSome(){
  System.out.println(this.name + "在购物!"); //张三在购物
  System.out.println(name + "在购物!");//张三在购物
  //super表示的是当前对象的父类型特征。(super是this指向的那个对象中的一块空间)
  // System.out.println(super.name + "在购物!");//编译报错:找不到符号
  }
}
class Vip extends Customer{
  //假设子类也有一个同名属性
  //java中允许在子类中出现和父类一样的同名变量/同名属性
  String name;//实例变量
  public Vip(){
  }
  public Vip(String name){
  super(name);
  //this.name = null;当前对象默认值为空
  }
  //super和this都不能出现在静态方法中
  public void shopping(){
  //this表示当前对象
  System.out.println(this.name + "在购物!");//null在购物
  //super表示的是当前对象的父类型特征。(super是this指向的那个对象中的一块空间)
  System.out.println(super.name + "在购物!");//张三在购物
  System.out.println(name + "在购物!");//null在购物
  }
}


运行结果:


dfc80ca9d8004e6c9ddc00e8448ffc6a.png


五:super使用后后面必须有个点


super 不是引用。super也不保存内存地址,super也不指向任何对象

super 只是代表当前对象内部的那一块父类型的特征。


示例代码06:



public class SuperTest06{
    //实例方法
  public void doSome(){
  //输出“引用.”的时候,会自动调用引用的toString()方法
  System.out.println(this.toString());
  //SuperTest06@15db9742
  System.out.println(this);
  // System.out.println(super);//编译错误:需要“.”
  }
  //this和super不能使用在static静态方法中
  /* public Static void doOther(){
  System.out.println(this);
  System.out.println(super);
  }
  */
  //静态方法 主方法
  public static void main(String[] args){
  SuperTest06 st = new SuperTest06();
  st.doSome();
  }
}


运行结果:


f91d8a108d0c413eb930b624a9967d37.png


六:使用super调用父类方法


在父类和子类中有同名的属性,或者说有相同的方法, 如果此时想在子类中访问父类中的数据,必须使用“super.”加以区分。


①super.属性名 【访问父类中的属性】

②super.方法名(实参) 【访问父类的方法】

③super(实参) 【调用父类的构造方法】


示例代码07:


public class SuperTest07{
  public static void main(String[] args){
  Cat c = new Cat();
  c.yiDong();
  }
}
class Animal{
    public void move(){
  System.out.println("Animal move");
}
}
class Cat extends Animal{
  //对move进行重写
  public void move(){
  System.out.println("Cat move");
  }
  //单独编写一个子类特有的方法
  public void yiDong(){
    this.move();
    move();
    //super. 不仅可以访问属性,也可访问方法
    super.move();
  }
}


运行结果:


0a2653c851af460fa595bd959398a8f1.png


相关文章
|
1月前
|
设计模式 安全 Java
Java并发编程实战:使用synchronized关键字实现线程安全
【4月更文挑战第6天】Java中的`synchronized`关键字用于处理多线程并发,确保共享资源的线程安全。它可以修饰方法或代码块,实现互斥访问。当用于方法时,锁定对象实例或类对象;用于代码块时,锁定指定对象。过度使用可能导致性能问题,应注意避免锁持有时间过长、死锁,并考虑使用`java.util.concurrent`包中的高级工具。正确理解和使用`synchronized`是编写线程安全程序的关键。
|
20小时前
|
小程序 Java 容器
03|Java基础语法:讲解标识符、关键字、变量、数据类型、运算符、控制语句(条件分支、循环)
03|Java基础语法:讲解标识符、关键字、变量、数据类型、运算符、控制语句(条件分支、循环)
7 0
|
11天前
|
存储 安全 Java
【亮剑】Java并发编程涉及`ThreadLocal`、`Volatile`、`Synchronized`和`Atomic`四个关键机制
【4月更文挑战第30天】Java并发编程涉及`ThreadLocal`、`Volatile`、`Synchronized`和`Atomic`四个关键机制。`ThreadLocal`为每个线程提供独立变量副本;`Volatile`确保变量可见性,但不保证原子性;`Synchronized`实现同步锁,保证单线程执行;`Atomic`类利用CAS实现无锁并发控制。理解其原理有助于编写高效线程安全代码。根据业务场景选择合适机制至关重要。
|
11天前
|
Java 编译器
【Java探索之旅】this 关键字 解决你的成员变量困惑
【Java探索之旅】this 关键字 解决你的成员变量困惑
17 0
|
11天前
|
Java
【Java探索之旅】我与Java的初相识(完):注释,标识符,关键字
【Java探索之旅】我与Java的初相识(完):注释,标识符,关键字
5 0
|
12天前
|
Java
Java里的关键字 __final
Java里的关键字 __final
|
14天前
|
Java 编译器
【JAVA】volatile 关键字的作用
【JAVA】volatile 关键字的作用
|
14天前
|
Java
【JAVA面试题】final关键字的作用有哪些
【JAVA面试题】final关键字的作用有哪些
|
17天前
|
安全 Java 编译器
是时候来唠一唠synchronized关键字了,Java多线程的必问考点!
本文简要介绍了Java中的`synchronized`关键字,它是用于保证多线程环境下的同步,解决原子性、可见性和顺序性问题。从JDK1.6开始,synchronized进行了优化,性能得到提升,现在仍可在项目中使用。synchronized有三种用法:修饰实例方法、静态方法和代码块。文章还讨论了synchronized修饰代码块的锁对象、静态与非静态方法调用的互斥性,以及构造方法不能被同步修饰。此外,通过反汇编展示了`synchronized`在方法和代码块上的底层实现,涉及ObjectMonitor和monitorenter/monitorexit指令。
26 0
|
17天前
|
Java
两千字讲明白java中instanceof关键字的使用!
两千字讲明白java中instanceof关键字的使用!
18 0