首页 > 代码库 > Java笔记十六.java中的this和super用法

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引用构造方法时要放在构造函数的最前面并且只有在创建了相应的实例对象,系统才会自动调用类中相应的构造方法。

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