Java 中的 this 和 super 区别

目录
  • 1、简介
  • 2、引子
    • 2.1 父类中声明无参构造函数
    • 2.2 子类显示的通过super调用父类的有参构造函数
  • 3、this
  • 4、super
  • 5、总结
    • 5.1 对比差异
    • 5.2 相同点
    • 5.3 总结图

1、简介

thissuper是类实例化时通往Object类通道的打通者;this和super在程序中由于其经常被隐式的使用而被我们忽略,但是理解其作用和使用规范肯定是必须的。接下来将详述this与super的作用和区别。

2、引子

先来看两段代码,无报错代码示例:

package com.liziba.ts;

/**
 * <p>
 *   父类示例代码
 * </p>
 *
 * @Author: Liziba
 */
public class Father {

    private String name;

    public String getName() {
        return name;
    }

}
package com.liziba.ts;

/**
 * <p>
 *   子类示例代码
 * </p>
 *
 * @Author: Liziba
 */
public class Son extends Father{

    public Son(String name) {

    }

}

此时将Father类中的构造函数修改为有参的构造函数,

有错误的代码示例:

package com.liziba.ts;

/**
 * <p>
 *   父类示例代码
 * </p>
 *
 * @Author: Liziba
 */
public class Father {

    private String name;

    public Father(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

}

子类代码不修改,此时子类报错:

这就是super()的隐式使用导致的报错,具体原因是因为子类Son的构造函数中隐式的调用了父类的无参构造器,相当于隐式的super() ,上面报错的代码和下面这个是等价的。

但是由于父类没有显示的申明无参构造函数,此时无参构造函数被有参构造函数覆盖了,所有super()调用无法抵达父类。

此时的解决办法有两种:

2.1 父类中声明无参构造函数

public class Father {

    public String name;

    // 父类什么无参构造函数
    public Father() {
    }

    public Father(String name) {
        this.name = name;
    }
}

public class Son extends Father {

    public Son(String name) {
        super(); // 可以省略
    }
}

2.2 子类显示的通过super调用父类的有参构造函数

public class Son extends Father {

    public Son(String name) {
        // 调用父类的有参构造函数
        super(name);
    }
}

接下来将详细分析thissuper的作用和区别。

3、this

this相当于当前对象实例,或者当前对象的一个引用,

this有如下作用:

  • 调用当前对象中的方法和属性
  • 区分对象属性和方法形参
  • 调用构造方法(必须在构造函数的第一行)

this相当于当前对象实例举例:

public class Son extends Father{

    private String homework = "Java编程思想";

    public void doSomething() {
        // this 相当于当前Son对象实例
        synchronized (this) {

        }
    }
}

调用当前对象中的方法和属性举例:

public class Son extends Father{

    private String homework = "Java编程思想";

    public void doSomething() {
        // this 获取当前对象的属性
        String hn = this.homework;
        // this 调用当前对象的方法
        this.doSomething2();
    }

    public void doSomething2() {
        // toDo
    }
}

区分对象属性和方法形参举例:

public class Son extends Father{

    private String homework = "Java编程思想";

    public Son(String homework) {
        // 区分对象属性与方法形参
        this.homework = homework;
    }

}

调用其他构造方法举例:

public class Son extends Father{

    private String homework = "Java编程思想";

    public Son(String homework) {
        // 调用其他构造方法,必须在第一行
        this(homework, "你们未来都是架构师");
    }

    public Son(String homework, String name) {
    }
}

4、super

super可以理解为父类(直接父类,如果有多层继承关系这里指的是最近的父类)对象的引用。super有如下的作用:

  • 调用父类非私有的属性和方法
  • 区分当前类与父类同名的属性和方法
  • 调用父类的构造函数(必须在构造函数的第一行)

调用父类属性和方法示例:

/**
 * 父类
 */
public class Father {

    public String name;

    public void doSomething3() {
        // toDo
    }

    public void doSomething4() {
        // toDo
    }
}

/**
 * 子类
 */
public class Son extends Father{

   public void doSomething() {
       // 调用父类的非私有方法
       super.doSomething3();
       super.doSomething4();
    // 调用父类的非私有属性
       String name = super.name;
   }

}

区分当前类与父类同名的属性和方法示例:

/**
 * 父类
 */
public class Father {

    public String name;

    public void doSomething3() {
        // toDo
    }

    public void doSomething4() {
        // toDo
    }
}

/**
 * 子类代码修改成如下
 */
public class Son extends Father {
    public String name;

    public void doSomething() {

        // super可以区分父类方法与当前对象的方法
        doSomething3();
        doSomething4();
        super.doSomething3();
        super.doSomething4();

        // 区分当前父类的属性与当前类的属性
        String fatherName = super.name;
        String sonName = name;
    }

    @Override
    public void doSomething3() {
        // todo
    }

    @Override
    public void doSomething4() {
        // todo
    }
}

调用父类的构造函数(必须在构造函数的第一行)

/**
 * 父类
 */
public class Father {

    public String name;

    public Father(String name) {
        this.name = name;
    }
}

/**
 * 子类
 */
public class Son extends Father {

    public Son(String name) {
        super(name);
    }
}

5、总结

5.1 对比差异

this 基本概念:

  • 访问本类实例属性和方法

super 基本概念:

  • 访问父类实例属性和方法

this 查找范围:

  • 先查找本类,不存在再查找父类

super 查找范围:

  • 直接查找父类

this 其他功能:

  • 单独使用表示当前对象

super 其他功能:

  • 子类复写父类方法,用于访问父类同名方法

5.2 相同点

  • 都是关键字,起指代作用
  • 构造方法中必须在第一行调用其它构造函数

5.3 总结图

到此这篇关于Java 中this与super区别的文章就介绍到这了,更多相关this与super内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 关于java关键字this和super的区别和理解

    this: this理解为:当前对象 或 当前正在创建的对象 可以调用的结构:属性.方法:构造器 this调用属性.方法: 先了解一下形参: 形参的意义就是给属性赋值,我们是要给同名的属性赋值,这时候我们就把形参名和属性的名字写成一样,这样我们就知道我们传入的形参就是要给我们同名的属性去赋值的. 在类的方法中,我们可以使用"this.属性"或"this.方法"的方式,调用当前对象属性或方法.但是, 通常情况下,我们都择省略"this.".特殊情况

  • Java中super和this的用法详解

    super 用法 super关键字用来访问父类内容,具体用法可分为三种: 1.子类的成员方法访问父类的成员变量 public class Animal { public int age = 10; } class Dog extends Animal { public int age = 5; public void showAge() { System.out.println(super.age); } } 2.子类的成员方法访问父类的成员方法 public class Animal { pu

  • Java中超详细this与super的概念和用法

    前言:理论和代码必须结合起来才能真正的掌握 一.this 概念:this代表着当前对象的引用,也是当前函数所属对象的引用.直白的说,哪个对象调用了当前函数,this就代表哪个对象. 常见的用法(理论不理解就先参考下面案例) 最常见的情况是是对象的一个属性或被构造器的参数屏蔽时,如果需要调用屏蔽的属性,this就代表哪个对象 this只能在方法内使用,表示正在调用方法的那个对象,但是,如果在方法内调用同一个类的另一个方法,就不必使用this,直接调用即可,this关键字是能省则省 this和sta

  • Java 中的 this 和 super 区别

    目录 1.简介 2.引子 2.1 父类中声明无参构造函数 2.2 子类显示的通过super调用父类的有参构造函数 3.this 4.super 5.总结 5.1 对比差异 5.2 相同点 5.3 总结图 1.简介 this与super是类实例化时通往Object类通道的打通者:this和super在程序中由于其经常被隐式的使用而被我们忽略,但是理解其作用和使用规范肯定是必须的.接下来将详述this与super的作用和区别. 2.引子 先来看两段代码,无报错代码示例: package com.li

  • Java关键字详解之final static this super的用法

    目录 1. final 关键字: 2. static 关键字: 3. this 关键字: 4. super 关键字: final,static,this,super 关键字总结 正文开始@Assassin 1. final 关键字: final 关键字,意思是最终的.不可改变的,初始化之后就不能再次修改 ,用来修饰类.方法和变量,具有以下特点: final 修饰的类不能被继承,final类中的所有成员方法都会被隐式的指定为 final 方法: final 修饰的方法不能被重写: final 修饰

  • Java this super代码实例及使用方法总结

    这几天看到类在继承时会用到this和super,这里就做了一点总结,与各位共同交流,有错误请各位指正~ 一.this this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针. this的用法在java中大体可以分为3种: 1.普通的直接引用 这种就不用讲了,this相当于是指向当前对象本身. 2.形参与成员名字重名,用this来区分: package com.demo; public class Person { private int age = 10; public Pe

  • 举例讲解Java编程中this关键字与super关键字的用法

    this 总要有个事物来代表类的当前对象,就像C++中的this指针一样,Java中的this关键字就是代表当前对象的引用. 它有三个主要的作用: 1.在构造方法中调用其他构造方法.       比如有一个Student类,有三个构造函数,某一个构造函数中调用另外构造函数,就要用到this(),而直接使用Student()是不可以的. 2.返回当前对象的引用. 3.区分成员变量名和参数名. 看下面的例子: public class Student { private String name; p

  • 浅析Java中Runnable和Thread的区别

    线程的起动并不是简单的调用了你的RUN方法,而是由一个线程调度器来分别调用你的所有线程的RUN方法, 我们普通的RUN方法如果没有执行完是不会返回的,也就是会一直执行下去,这样RUN方法下面的方法就不可能会执行了,可是线程里的RUN方法却不一样,它只有一定的CPU时间,执行过后就给别的线程了,这样反复的把CPU的时间切来切去,因为切换的速度很快,所以我们就感觉是很多线程在同时运行一样. 你简单的调用run方法是没有这样效果的,所以你必须调用Thread类的start方法来启动你的线程.所以你启动

  • 实例分析java中重载与重写的区别

    本文以实例详细分析了Java中重载与重写的区别,感兴趣的朋友可以参考一下. 一.重载(Overloading): (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型. 重载Overloading是一个类中多态性的一种表现. (2)Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义. 调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性. (3) 重载的时候,方

  • 浅谈java中字节与字符的区别

    最近在看Java中的IO相关知识,发现对字节和字符的理解还不够.写篇总结记录一下. 一.字节 所谓字节(Byte),是计算机数据存储的一种计量单位.一个二进制位称为比特(bit),8个比特组成一个字节,也就是说一个字节可以用于区分256个整数(0~255).由此我们可以知道,字节本是面向计算机数据存储及传输的基本单位,后续的字符也就是以字节为单位存储的,不同编码的字符占用的字节数不同. 那么在Java中,除了存储的意义外,Java还将字节Byte作为一种基本数据类型,该数据类型在内存中占用一个字

  • Java 中泛型 T 和 ? 的区别详解

    目录 泛型中 T 类型变量 和 ? 通配符 区别 Generic Types 类型变量 用法 2.声明通用的方法 – 泛型方法: 有界类型参数 Wildcards 通配符 1.上界通配符:? extend 上界类型 2.无界通配符:? 3.下界通配符:? super 子类 类型擦除 泛型中 T 类型变量 和 ? 通配符 区别 定义不同 :T 是类型变量,? 是通配符 使用范围不同: ? 通配符用作 参数类型.字段类型.局部变量类型,有时作为返回类型(但请避免这样做) T 用作 声明类的类型参数.

  • Java中 ? extends T 和 ? super T的理解

    目录 ? 通配符类型 上界<? extends T>不能往里存,只能往外取 下界<? super T>不影响往里存,但往外取只能放在Object对象里 PECS原则 总结 ? 通配符类型 <? extends T> 表示类型的上界,表示参数化类型的可能是T 或是 T的子类; <? super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object; 上界<? extends T>不能往里

  • 详谈Java中instanceof和isInstance的区别

    一次性搞定instanceof和isInstance,instanceof和isInstance长的非常像,用法也很类似,先看看这两个的用法: obj.instanceof(class) 也就是说这个对象是不是这种类型, 1. 一个对象是本身类的一个对象 2. 一个对象是本身类父类(父类的父类)和接口(接口的接口)的一个对象 3. 所有对象都是Object 4. 凡是null有关的都是false  null.instanceof(class) class.inInstance(obj) 这个对象

  • 浅谈Java中Collection和Collections的区别

    1.java.util.Collection 是一个集合接口.它提供了对集合对象进行基本操作的通用接口方法.Collection接口在Java 类库中有很多具体的实现.Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式. Collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └Set 2.java.util.Collections 是一个包装类.它包含有各种有关集合操作的静态多态方法.此类不能实例化,就像一

  • Java中HashSet和HashMap的区别_动力节点Java学院整理

    什么是HashSet? HashSet实现了Set接口,它不允许集合中有重复的值,当我们提到HashSet时,第一件事情就是在将对象存储在HashSet之前,要先确保对象重写equals()和hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有储存相等的对象.如果我们没有重写这两个方法,将会使用这个方法的默认实现.. public boolean add(Object o)方法用来在Set中添加元素,当元素值重复时则会立即返回false,如果成功添加的话会返回true. 什

  • 详解Java中HashSet和TreeSet的区别

    详解Java中HashSet和TreeSet的区别 1. HashSet HashSet有以下特点: 不能保证元素的排列顺序,顺序有可能发生变化 不是同步的 集合元素可以是null,但只能放入一个null 当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置. 简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个

随机推荐