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


相关文章
|
27天前
|
存储 缓存 Java
Java 并发编程——volatile 关键字解析
本文介绍了Java线程中的`volatile`关键字及其与`synchronized`锁的区别。`volatile`保证了变量的可见性和一定的有序性,但不能保证原子性。它通过内存屏障实现,避免指令重排序,确保线程间数据一致。相比`synchronized`,`volatile`性能更优,适用于简单状态标记和某些特定场景,如单例模式中的双重检查锁定。文中还解释了Java内存模型的基本概念,包括主内存、工作内存及并发编程中的原子性、可见性和有序性。
Java 并发编程——volatile 关键字解析
|
10天前
|
JSON Java 数据挖掘
利用 Java 代码获取淘宝关键字 API 接口
在数字化商业时代,精准把握市场动态与消费者需求是企业成功的关键。淘宝作为中国最大的电商平台之一,其海量数据中蕴含丰富的商业洞察。本文介绍如何通过Java代码高效、合规地获取淘宝关键字API接口数据,帮助商家优化产品布局、制定营销策略。主要内容包括: 1. **淘宝关键字API的价值**:洞察用户需求、优化产品标题与详情、制定营销策略。 2. **获取API接口的步骤**:注册账号、申请权限、搭建Java开发环境、编写调用代码、解析响应数据。 3. **注意事项**:遵守法律法规与平台规则,处理API调用限制。 通过这些步骤,商家可以在激烈的市场竞争中脱颖而出。
|
27天前
|
缓存 安全 Java
Java volatile关键字:你真的懂了吗?
`volatile` 是 Java 中的轻量级同步机制,主要用于保证多线程环境下共享变量的可见性和防止指令重排。它确保一个线程对 `volatile` 变量的修改能立即被其他线程看到,但不能保证原子性。典型应用场景包括状态标记、双重检查锁定和安全发布对象等。`volatile` 适用于布尔型、字节型等简单类型及引用类型,不适用于 `long` 和 `double` 类型。与 `synchronized` 不同,`volatile` 不提供互斥性,因此在需要互斥的场景下不能替代 `synchronized`。
2157 3
|
2月前
|
JavaScript 前端开发 Java
java中的this关键字
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。自学前端2年半,正向全栈进发。若我的文章对你有帮助,欢迎关注,持续更新中!🎉🎉🎉
62 9
|
2月前
|
设计模式 JavaScript 前端开发
java中的static关键字
欢迎来到瑞雨溪的博客,博主是一名热爱JavaScript和Vue的大一学生,致力于全栈开发。如果你从我的文章中受益,欢迎关注我,将持续分享更多优质内容。你的支持是我前进的动力!🎉🎉🎉
62 8
|
2月前
|
Java 开发者
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
52 4
|
3月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
107 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
3月前
|
Java 程序员
在Java编程中,关键字不仅是简单的词汇,更是赋予代码强大功能的“魔法咒语”。
【10月更文挑战第13天】在Java编程中,关键字不仅是简单的词汇,更是赋予代码强大功能的“魔法咒语”。本文介绍了Java关键字的基本概念及其重要性,并通过定义类和对象、控制流程、访问修饰符等示例,展示了关键字的实际应用。掌握这些关键字,是成为优秀Java程序员的基础。
47 3
|
3月前
|
算法 Java
在Java编程中,关键字和保留字是基础且重要的组成部分,正确理解和使用它们
【10月更文挑战第13天】在Java编程中,关键字和保留字是基础且重要的组成部分。正确理解和使用它们,如class、int、for、while等,不仅能够避免语法错误,还能提升代码的可读性和执行效率。本指南将通过解答常见问题,帮助你掌握Java关键字的正确使用方法,以及如何避免误用保留字,使你的代码更加高效流畅。
52 3
|
3月前
|
存储 安全 Java
了解final关键字在Java并发编程领域的作用吗?
在Java并发编程中,`final`关键字不仅用于修饰变量、方法和类,还在多线程环境中确保对象状态的可见性和不变性。本文深入探讨了`final`关键字的作用,特别是其在final域重排序规则中的应用,以及如何防止对象的“部分创建”问题,确保线程安全。通过具体示例,文章详细解析了final域的写入和读取操作的重排序规则,以及这些规则在不同处理器上的实现差异。
了解final关键字在Java并发编程领域的作用吗?