this关键字与super关键字详解

this关键字与super关键字详解一.this关键字1.实例一:(1)需求:使用Java类描述一个动物;(2)实例:classAnimal{ Stringname; //成员变量 Stringcolor; publicAnimal(Stringn,Stringc){ name=n; color=c; } publicvoideat(){ Stringname=

大家好,又见面了,我是你们的朋友全栈君。

一.this关键字

1.实例一:

(1)需求:使用Java类描述一个动物;

(2)实例:

class Animal{
	String name;	//成员变量
	String color;
	public Animal(String n,String c){
		name = n;
		color = c;
	}
	public void eat(){
		String name = "老鼠";	//局部变量
		System.out.println(name+"在吃……");
	}
}

class Demo1{
	public static void main(String[] args){
		Animal dog = new Animal("狗","白色");//此时在内存中存在两份name数据
		Animal cat = new Animal("猫","黑色");
		cat.eat();
	}
}
 

(3)运行结果:

this关键字与super关键字详解
(4)存在的问题:

当我们new一个动物cat时,让cat去调用eat方法,结果显示的却是老鼠在吃;

也就是说当存在同名的成员变量与局部变量时,在方法的内部访问的是局部变量,那是因为Java采取的是就近原则访问的,要解决这个问题就需要使用this关键字;

2.存在同名成员变量与局部变量的内存分析

this关键字与super关键字详解

(1)栈内存也叫方法栈,把它称为方法栈的原因是因为:一个方法要运行的时候,JVM会在栈内存中开辟一片属于这个方法的空间,让这个方法在这片空间内执行;

(2)首先在这片代码中主方法会先执行,主方法一执行,JVM会在栈内存中开辟一片空间属于main方法,在这片空间中先声明了一个变量a,接着new一个Animal,这时候在堆内存中就创建了一个Animal对象,这个Animal有name和color两个属性,都分配了默认的初始值,name=“狗”,color=null;这时候假设它的内存地址是0X98,此时a这个变量就指向了0X98,也就是a指向了这个对象;
(3)接着在main方法的这片空间执行a.eat();eat方法执行的时候,JVM在栈内存中为这个方法开辟了一片属于eat方法的空间,在这个eat方法里首先声明了一个变量name=“老鼠”,紧接着输出语句,因为Java采取的是就近原则来访问的,因为输出语句中的name变量在eat方法这片空间也存在,如果存在它就只会在eat方法这片空间去找,如果这片空间没有它才会去到堆内存中去找

3.定义:

(1)this关键字代表了所属函数的调用者对象,this代表了对象的内存地址(在构造函数中打印this会发现结果是一个内存地址),也就是说哪个对象调用了this所在的函数,那么this就指代哪个对象;

(2)this是指向本类中某一个对象的一个变量,this相当于文章中第一人称的“我”,所有人描述自己的时候都会说“我”,只要读“我”的这个人发生变化,这个“我”指向的人就变了;而this关键字与之类似,this是抽象的,刚开始并不知道是指代谁,this是每一个对象携带的变量,这个变量所指向的都是自己,this只是起到了一个描述的作用:只要有一个具体的对象来执行的时候,this就用这个对象的this,换一个对象,this就变成另一个对象的this,所以只有在执行的时候才知道指向谁。就像文章中的“我”,只有确定了谁是读这篇文章的,才能确定这个“我”指代谁;

(3)this关键字代表的是对象的引用,也就是this在指向一个对象,所指向的对象就是调用该函数的对象引用;

4.this关键字的作用:

(1)如果存在同名的成员变量与局部变量时,在方法内部默认是访问局部变量的数据,可以通过this关键字指定访问成员变量的数据;

(2)在一个构造函数中可以调用另外一个构造函数初始化对象;

5.this关键字要注意的事项:

(1)存在同名的成员变量与局部变量时,在方法的内部访问的是局部变量(Java采取的是“就近原则”的机制访问的);

(2)如果在一个方法中访问了一个变量,该变量只存在成员变量的情况下,那么Java编译器会在该变量的前面添加this关键字;

6.this关键字调用其他的构造函数要注意的事项:

(1)this关键字调用其他的构造函数时,this关键字必须要位于构造函数中的第一个语句;

(2)this关键字在构造函数中不能出现相互调用的情况,因为是一个死循环;

7.实例二:

class Student{
	int id;	//身份证
	String name;	//名字
	public Student(int id,String name){//一个函数的形式参数也是属于局部变量
		this(name);	//调用了本类的一个参数的构造方法,根据传入的参数确定调用的是本类的哪一个构造方法
		this.id = id;	//局部变量的id给成员变量的id赋值
		System.out.println("两个参数的构造方法被调用了……");
	}
	public Student(){
		System.out.println("无参的构造方法被调用了……");
	}
	public Student(String name){
		this.name = name;
		System.out.println("一个参数的构造方法被调用了……");
	}
}

class Demo6{
	public static void main(String[] args){
		Student s = new Student(110,"铁蛋");
		System.out.println("编号:"+s.id+"  姓名:"+s.name);
	}
}

运行结果如下图所示:

this关键字与super关键字详解

注意:如果是this(); 代表调用了本类无参的构造方法。

8.实例三:

(1)需求:

使用Java定义一个人类,人具备id,name,age三个属性,还具备一个比较年龄的方法;必须要写上一个构造函数,构造函数也必须要使用this关键字。

class Person{	
	int id; //编号
	String name; //姓名
	int age;  //年龄
	//构造函数
	public Person(int id,String name ,int age){
		this.id  = id;
		this.name = name;
		this.age = age;
	}
	//比较年龄的方法,这是本身就具备的,还有一个和谁比较是未知数
	public void compareAge(Person p2){
		if(this.age>p2.age){
			System.out.println(this.name+"大!");
		}else if(this.age<p2.age){
			System.out.println(p2.name+"大!");
		}else{
			System.out.println("同龄");
		}
	}
}

class Demo7{
	public static void main(String[] args) {
		Person p1 = new Person(110,"狗娃",17);
		Person p2 = new Person(119,"铁蛋",9);
		p1.compareAge(p2);
	}
}
 

(2)运行结果如下图所示:

this关键字与super关键字详解

二.super关键字

1. super关键字代表了父类空间的引用;

2. super关键字的作用:

(1) 子父类存在着同名的成员(包括变量和方法)时,在子类中默认是访问子类的成员,可以通过super关键字指定访问父类的成员;

(2) 创建子类对象时,默认会先调用父类无参的构造方法,可以通过super关键字指定调用父类的构造方法。
(1) 如果在子类的构造方法上没有指定调用父类的构造方法,那么java编译器会在子类的构造方法内加上super()语句。
(2) super关键字调用父类的构造函数时,该语句必须要是子类构造函数中的第一个语句。
(3) super与this关键字不能同时出现在同一个构造函数中调用其他的构造函数。因为两个语句都需要第一个语句。
(1) 代表的事物不一致。
① super关键字代表的是父类空间的引用。(并不能代表对象,只是代表一个对象中的一块内存而已)
② this关键字代表的是所属函数的调用者对象。
(2) 使用前提不一致。
① super关键字必须要有继承关系才能使用。
② this关键字不需要存在继承关系也可使用。
(3) 调用构造函数的区别:
① super关键字是调用父类的构造函数。
② this关键字是调用本类的构造函数。

3. super关键字调用父类构造方法要注意的事项:

注意:是两个关键字不能同时出现在同一个构造函数中去调用其他的构造函数,里面还是可以写this.num = num。并不是说不能出现this。

4. super关键字与this关键字的区别:

5.实例:

class Father {
	int x = 1;

	Father() {
		System.out.println("这是父类无参的构造方法");
	}

	Father(int x) {
		this.x = x;
		System.out.println("这是父类有参的构造方法");
	}

	void speak() {
		System.out.println("我是父类");
	}
}

class Son extends Father {
	int y = 1;
	Son() {
		System.out.println("这是子类无参的构造方法");
	}

	Son(int y) {
		this.y = y+x;
		System.out.println("这是子类带参的构造方法");
	}

	void run() {
		super.speak();	//访问父类的函数
		System.out.println("我是子类");
	}
}

class Demo1{
	public static void main(String[] args) {
		Son s = new Son(3);
		System.out.println(s.y);	//4
	}
}
 

运行结果如下图所示:

this关键字与super关键字详解
6.super关键字主要存在于子类方法中,用于指向子类对象中的父类对象;可以访问父类的属性、函数以及构造函数
。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/147978.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 连接docker中的mysql_搭建docker环境

    连接docker中的mysql_搭建docker环境使用docker部署springboot项目并连接上mysql数据库需要的知识Linux操作系统docker(了解git的工作方式即可)工具xshell(用来连接linux服务器)xftp用来给linux服务器上传文件sqlyog(或者navicat)在服务器上解析.sql脚本maven(idea自带)用来打包接下来我们开始正式操作服务器的选择我选择的是阿里…

    2022年8月31日
  • 深入理解ConcurrentHashMap原理分析以及线程安全性问题

    深入理解ConcurrentHashMap原理分析以及线程安全性问题在之前的文章提到CurrentHashMap是一个线程安全的,那么我么看一下CurrentHashMap如何进行操作的。CurrentHashMap与HashTable区别?HashTableput()源代码从代码可以看出来在所有put的操作的时候都需要用synchronized关键字进行同步。并且key不能为空。这样相当于每次进行put的时候都会进行同

    2022年6月18日
  • 回溯算法之N皇后问题[通俗易懂]

    回溯算法之N皇后问题[通俗易懂]问题描述什么是皇后问题八皇后问题(英文:Eightqueens),是由国际西洋棋棋手马克斯·贝瑟尔于1848年提出的问题,是回溯算法的典型案例。问题表述为:在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。如果经过±90度、±180度旋转,和对角线对称变换的摆法看成一类,共有42类。计算机发明后,有多种计算机语

    2022年9月30日
  • MariaDB安装教程

    MariaDB安装教程注:从MariaDB10.4.3开始,不再提供预构建的数据目录,并且用户需要运行mysql_install_db.exe来创建数据目录1、解压到自定义路径E:\MariaDB\mariadb-10.5.4-winx642、将其中的bin加入path系统环境路径3、用管理员方式打开cmd,并打开bin目录4、输入mysql_install_db.exe–datadir=E:\MariaDB\mariadb-10.5.4-winx64\data–service=MyMar..

    2022年6月14日
  • c语言中uint8_uint16转uint8

    c语言中uint8_uint16转uint8C++的基础数据类型:名称字节长度取值范围bool1false,truechar1-128~127signedchar1-128~127unsignedchar10~255short(signedshort)2-215~215-1unsignedshort20~216-1int(signedin…

    2022年9月15日
  • 20款优秀的免费代码编辑器

    20款优秀的免费代码编辑器Atom.io(Win7、Win8、OSX10.8、Linux)免费GitHub开发的文本编辑器Atom发布了0.177.0版,其中一个引入注目的变化是从Node.js切换到了io.js。io.js是Node.js的分支,Node.js社区发生分裂后由核心开发者在2014年12月创建的,已经发布了v1.1版,目前开发非常活跃。Atom是切换到io.js的一个重量级项目。At

    2022年6月15日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号