Java笔记十六.java中的this和super用法

一、this引用句柄

this引用句柄在Java程序里的作用,可表现为它在函数内部就是这个函数所属的对象的引用变量,即当前对象。在成员方法中,对访问的同类中成员前加不加this引用,效果都是一样的,这就好像同一公司的职员彼此在提及和自己公司有关的事时,不必说出公司名一样,当然为了强调,可以加上"咱们公司....."这样的前缀,而在Java程序中,this就相当于"我们所属于的那个对象"。

每个成员方法内部,都有一个this引用变量,指向调用这个方法的对象。下面我们开深入剖析下this的几种用法:

1.this是指当前对象自己

当在一个类中明确指出使用对象自己的变量或函数时需加上this的引用。比如我们向通过构造方法将外部传入的参数赋值给类的成员变量,构造方法的形式参数名称与类的成员变量名相同。

<span style="font-size:18px;">public class Hello {
            String s = "Hello";
            public Hello(String s)
            {
                    System.out.println("s = " + s);
                    System.out.println("1 -> this.s = " + this.s);
                    this.s = s;
                    System.out.println("2 -> this.s = " + this.s);
            }
public static void main(String[] args)
{
    Hello x="new" Hello("HelloWorld!");
}
}</span>

运行结果:

s
= HelloWorld!

1
-> this.s = Hello

2
-> this.s = HelloWorld!

分析:在这个例子中,构造函数Hello中,参数s与类Hello的变量s同名,这时如果直接对s进行操作则是对参数s进行操作。若要对类Hello的成员变量s进行操作就应该用this进行引用。运行结果的第一行就是直接对构造函数中传递过来的参数s进行打印结果;
第二行是对成员变量s的打印;第三行是先对成员变量s赋传过来的参数s值后再打印,所以结果是HelloWorld!

2.把this作为参数传递

假设有一个容器类和一个部件类,在容器类的某个方法中要创建部件类的实例对象,而部件类的构造方法要接收一个代表其所在容器的参数。

class Container

{

Component comp;    //声明一个部件类引用变量comp(非对象)

public addComponent()

{

comp=new Component(this);//将this作为对象引用(容器类对象)传递给部件的构造方法

}

}

class Component

{

Container myContainer;    //声明一个容器类引用变量

public Component(Container c)

{

myContainer = c;

}

}

分析:由于每个成员方法内部,都有一个this引用变量,上述代码就实现了通过this引用把当前的对象作为一个参数传递给其他的方法和构造方法。其中addComponent方法的this引用变量便指向Container对象,所以comp=new
Component(this)语句就相当于将Container对象作为参数传递给Component类的构造方法。

3.在构造函数中,通过this调用同一class中别的构造函数

public class Flower

{

Flower (int petals){}

Flower(String ss){}

Flower(int petals, Sting ss)

{

//petals++;调用另一个构造函数的语句必须在最起始的位置

this(petals);

//this(ss);会产生错误,因为在一个构造函数中只能调用一个构造函数

}

}

分析:构造方法是在产生对象时被Java系统自动调用的,我们不能在程序中向调用其他方法一样去调用构造方法。所以我们使用this(参数列表),实现在一个构造方法里调用其他重载的构造方法,但需要有几点注意:

(1)在构造调用另一个构造函数,调用动作必须置于最起始的位置。

(2)不能在构造函数以外的任何函数内调用构造函数。

(3)在一个构造函数内只能调用一个构造函数。

4.匿名类和内部类中的中的this

有时候,我们会用到一些内部类和匿名类,如事件处理。this则指的是匿名类或内部类本身。这时如果我们要使用外部类的方法和变量的话,则应该加上外部类的类名。

如下面这个例子:

public class A

{

int i = 1;

/*构造方法*/

public A()

{

Thread thread = new Thread()

{

public void run()

{

while(true)

{

A.this.run();

try { sleep(1000);
 } catch(InterruptedException ie) { }

}

}

};//thread是一个匿名类对象

thread.start();

}

/*成员方法*/

public void run()

{

System.out.println("i = " + i);

i++;

}

public static void main(String[] args) throws Exception

{

new A();

}

}

分析:在上面这个例子中, thread 是一个匿名类对象,在它的定义中,它的
run 函数里用到了外部类的 run 函数。这时由于函数同名,直接调用就不行了。这时有两种办法,一种就是把外部的 run 函数换一个名字,但这种办法对于一个开发到中途的应用来说是不可取的。那么就可以用这个例子中的办法用外部类的类名加上 this 引用来说明要调用的是外部类的方法 run。

二、super引用句柄

在Java中,this通常指当前对象,super则指父类的。当我们想要引用当前对象的成员变量或某个成员方法,则可以利用this来实现这个目的。当然,如果我们想引用父类的某个成员或成员方法,则使用super引用句柄实现。

一般情况下,super引用句柄主要有两种使用方法:

1.在子类中使用"super.父类中的成员名"的方式,访问父类的成员

源码:superDemo.java

<span style="font-size:18px;">/*父类*/
class Song
{
    //成员变量
    private String name;
    private String singer;
    //构造方法
    public void setInfo(String name,String singer )
    {
        this.name = name;
        this.singer = singer;
    }
    //成员方法
    protected void print()
    {
        System.out.println("Name="+name+"Singer="+singer);
    }
}
/*子类*/
public class superDemo extends Song
{
    //子类成员方法
    public void print()
    {
        System.out.println("superDemo");
        super.print();                                //调用父类的print成员方法
    }
    public static void main(String[] args)
    {
          superDemo demo=new  superDemo();    //实例化一个 superDemo对象,demo能够引用父类所有非private成员
           demo.setInfo("可惜没如果","林俊杰");
            demo.print();
    }
}</span>

打印结果:

分析:在上面的程序中,我们重新覆写了父类的print方法,该方法先完成自己的一些事情(即打印superDemo)。然后,通过super.print()语句调用被子类覆写的print方法。

2.在子类构造方法中,通过"super(参数列表)"形式用来调用父类中具有相同形式的构造函数,而this后加参数则调用的是当前具有相同参数的构造函数。

源码:superDemo.java

<span style="font-size:18px;">/*父类*/
class Song
{
    //构造方法1
    public Song()
    {
           System.out.println("Father class");
    }
    //构造方法2
    public Song(String name )
    {
        System.out.println("Father Class"+name);
    }
}
/*子类*/
public class superDemo extends Song
{
    //构造方法1
    superDemo()
    {
        super();        //super引用父类构造函数1
         System.out.println("Child class --A song"+"\n"+"-------------------------");
    }
    //构造方法2
    superDemo(String name)
    {
        super(name);    //super引用父类构造函数2
        System.out.println("Child class name is"+name+"\n"+"-------------------------");
    }
    //构造方法3
    superDemo(String name,String singer)
    {
        this(name);        //this引用自身构造方法2
        System.out.println("Child class singger is"+singer+"\n"+"-------------------------");
    }
    public static void main(String[] args)
    {
          superDemo demo=new  superDemo();       //实例化一个子类对象,构造方法为第一种
           new superDemo("钟汉良");                        //实例化一个子类对象,构造方法为第二种
           new superDemo("钟汉良","何以笙箫默");     //实例化一个子类对象,构造方法为第三种
    }
}</span>

打印结果:

分析:通过上面打印的结果可知道,super(参数列表)引用的是父类相应的构造方法,this(参数列表)引用的是当前类的构造方法。另外,我们在使用super和this引用构造方法时要放在构造函数的最前面并且只有在创建了相应的实例对象,系统才会自动调用类中相应的构造方法。

时间: 2024-08-09 08:05:49

Java笔记十六.java中的this和super用法的相关文章

“全栈2019”Java第十六章:下划线在数字中的意义

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第十六章:下划线在数字中的意义 下一章 "全栈2019"Java第十七章:赋值运算符和算术运算符 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java学习小组&q

“全栈2019”Java第九十六章:抽象局部内部类详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第九十六章:抽象局部内部类详解 下一章 "全栈2019"Java第九十七章:在方法中访问局部内部类成员详解 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java学

Android之旅十六 android中各种资源的使用

android中各种资源的使用: 在android开发中,各种资源的合理使用应该在各自的xml中进行定义,以便重复使用; 字符串资源:strings.xml,xml中引用:@string/XXX,java代码中引用:R.string.XXX 样式资源:styles.xml,xml中引用:@style/XXX,java代码中引用:R.style.XXX 图片资源:colors.xml,xml中引用:@color/XXX,java代码中引用:R.color.XXX 尺寸资源:dimens.xml,x

swift 笔记 (十六) —— 可选链

可选链(Optional Chaining) 我们都知道"可选型"是什么,那么可选链又是什么,举个例子解释一下: struct MyName{ var name } struct MyInfo { var myName:MyName? = MyName() } class MyClass { var structInstance: MyInfo? = MyInfo() } 这里有两个结构体和一个类,当,这个类实例化的时候: var myInstance = MyClass() 所有的可

C++学习笔记十六-模板和泛型编程(二)

C++学习笔记十六-模板和泛型编程(二) 16.4 类模板成员 1.模板作用域中模板类型的引用: 通常,当使用类模板的名字的时候,必须指定模板形参.这一规则有个例外:在类本身的作用域内部,可以使用类模板的非限定名.例如,在默认构造函数和复制构造函数的声明中,名字 Queue 是 Queue<Type> 缩写表示.实质上,编译器推断,当我们引用类的名字时,引用的是同一版本.因此,复制构造函数定义其实等价于: Queue<Type>(const Queue<Type> &a

Java基础学习笔记十六 集合框架(二)

List List接口的特点: 它是一个元素存取有序的集合.例如,存元素的顺序是11.22.33.那么集合中,元素的存储就是按照11.22.33的顺序完成的. 它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理). 集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素. List接口的常用子类有: ArrayList集合 LinkedList集合 List接口的特有方法(带索引的方法)1.增加元素方法 add(Object e):向集合末尾

Java笔记十四.深入理解类和对象(1)

Java是一种完全面向对象的编程语言(C是面向过程).所谓面向对象编程(OOP),即是一种编程风格,它通过给程序中加入扩展语句,把函数"封装"进编程所必需的"对象"中.OOP 达到了软件工程的三个主要目标:重用性.灵活性和扩展性.其实,面向对象就是把一切东西看成一个个对象,比如人,车,面包,等等,然后把这些对象拥有的属性变量,比如年龄,民族,工作地点,变质期,寿命,还有操作这些属性变量的函数(方法)打包成一个类来表示,这个类的一个抽象就是一个对象.在Java程序中,

Java从零开始学三十六(JAVA IO- 字符流)

一.字符流 BufferedReader:BufferedReader是从缓冲区之中读取内容,所有的输入的字节数据都将放在缓冲区之中 BufferedWriter:把一批数据写入到缓冲区,当缓冲区区的满时,再把缓冲区的内容写到字符输出流中 二.对文本文件的读写 2.1.字符输入流 2.2.字符输出流 2.3.综合使用 package com.pb.io.buffered; import java.io.BufferedReader; import java.io.BufferedWriter;

Java Nio 十六、Java NIO Files

最后更新:2015-04-15 这个Java NIO的Files类(java.nio.file.Files)提供了数个方法中文件系统中操作文件.这个Java NIO的Files类教程将会覆盖这些方法的大部分通用方法的使用.这个类包含了许多的方法,所以也可以核对这个JavaDoc,如果你需要一个没有在这里描述的方法.这个Files类只是可能为了它仍然有一个方法. 这个java.nio.file.Files类同java.nio.file.Path实例一起工作,以至于你在同Files类工作之前需要理解