关于this和super的区别(转载)

本文通过示例代码详细解析了Java中this与super关键字的使用区别,探讨了它们在对象实例化过程中的作用及多态性实现的基础。
 
先看下面一段代码,比较短,

//父类
class FatherClass {
    public int value;
    public void f() {
        this.run();//注意这儿的是this,注意
    }
    public void run(){
        System.out.println("FatherClass.run():"+this.value);
    }
}

//子类
class ChildClass extends FatherClass {
    public int value = 100;
    public void ff() {
        super.run();//注意这儿的是super,注意
    }
    //重写
    public void run(){
        System.out.println("ChildClass.run():"+super.value); 字串6
    }
}

//孙子类,这儿用了一个拼音,偷懒一下,记不到那个孙子的单词了。寒啊...当初还过四级,现在忘光光
class SunziClass extends ChildClass {
    public int value = 200;
    //再次重写
    public void run() {
        System.out.println("SunziClass.run():"+super.value);
    }
}

//这儿是调用的Main
public class TestInherit {
      public static void main(String[] args) {
                FatherClass fc = new ChildClass();
                fc.f();
                FatherClass fc1 = new SunziClass();
                fc1.f();
字串1

                ChildClass cc = new SunziClass();
                cc.ff();
     }
}

想一想运行结果,注意那个this和super。有点晕头把,不要晕,稳住!自己想一下结果,然后再来看运行结果。

运行结果如下:
ChildClass.run():0;
SunziClass.run():100;
FatherClass.run():0;

估计有不少人会大吃一惊!其他不吃惊的人可以散了!吃惊的人继续看下面的。

this代表什么?这儿代表New出来的那个玩意儿在堆空间的引用地址
对于下面的这一句:
FatherClass fc1 = new SunziClass();
fc1这个变量里面放的就是this,是new SunziClass()这个玩意儿在堆空间的引用地址.
只是这儿fc1是定义成FatherClass,只有FatherClass的属性和方法是可见的,不过这不是本文讨论的重点.

所以说在父类里面写的this其实就是这个父类或者他的子类,孙子类,曾孙子类... 在运行的时候[重复一次哈,运行的时候runtime], New 子类()或者New 孙子类()或者New 曾子类()或者....的堆空间的引用地址.

字串4


[再重复一次,FatherClass里面的this,子类里面的this...都是一样的,指向New出来的那玩意儿的引用地址]

很 神奇哈!!嘿嘿,这个其实就是多态的体现,也是多态的实现基础.看父类或者接口定义了方法调用的逻辑,子类可以根据需要改变算法! 这样就可以将关注的方面分为两个层面,一:关注方法调用的业务逻辑[做什么],二:关注方法的实现[怎么做].  "做什么和怎么做",这玩意儿好像在软 件工程里面比较眼熟哦!!!!

问题分解了,而且可复用性也大大提高了.

好了,this总结完了,好像越说越晕了... 再稳一下,看看Super

下面再来说super
说之前,分析一下内存多,这个图,挖卡,蜘蛛网来也....


字串2



现在看这两句:
ChildClass cc = new SunziClass();
cc.ff();
这儿SunziClass里面没有重写父类ChildClass的ff方法,
所以是执行的父类ChildClass的ff方法.这个方法里面有一个super.Run();
这儿实际上就执行到了FatherClass的Run()方法.

这说明什么啦.
说明super只是记录对象内部的父类的特征(属性和方法)的一个引用
(注意哈:这儿super不是指向父类对象的引用地址哈,new出来的玩意儿才在堆里面分配空间有引用地址,这儿没有去new一个父类对象哈,只是执行了父类的构造函数将父类的特征生成了,但是属于New出来的那个子类对象)
估计上面这段话也够晕人了...

实践一下,你可以写
public FatherClass getThis()
{
    return this;
}
编译通过,没有任何问题
但是你写
public FatherClass getSuper()
{
    return super; 字串3
}

嘿嘿,编译出错! 为什么啦,
因为super并不是一个堆空间里面的一个对象的引用地址,而this才是堆空间里面的一个对象的引用地址
    super只能在对象内部使用,而this可以在对象内部使用也可以返回出对象外.
    super是死的,编译的时候就定死了super的指向了,而this是活的,在运行时候决定其指向.

再说一下,子类实例化对象,并没有去实例化他的父类对象,也就是说,那个子类对象里面并没有一个父类对象,
那你说没有父类对象,为什么子类构造函数要执行父类的构造函数啦,那是因为需要创建父类的特征赋予子类,但是是由子类所有,而super就是用来区别是是否是父类对象的特征的.
重写父类方法属性,就是再创建了一个子类的特征,当你用this的时候,就覆盖了父类的特征了,但是父类特征还在那儿,用super就能访问道,但是只能在对象的内部使用.对象外面就只能看到覆盖了父类特征的子类特征了.

字串1



其实就是一句:"this是当前对象在堆空间的引用地址,super是当前对象的父类特征的引用"
public class MainActivity extends Activity { private static final String appid = "wx86b3d972e5ddd153"; private IWXAPI wxApi; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); wxApi = WXAPIFactory.createWXAPI(this, appid); wxApi.registerApp(appid); } public void friend(View v){ share(0); } public void friendline(View v){ share(1); } private void share(int flag){ WXWebpageObject webpage = new WXWebpageObject(); webpage.webpageUrl = "http://blog.youkuaiyun.com/yeyuehei/article/details/28854667"; WXMediaMessage msg = new WXMediaMessage(webpage); msg.title = "test_myblog"; msg.description = "test_myblog"; //这里替换一张自己工程里的图片资源 Bitmap thumb = BitmapFactory.decodeResource(getResources(), R.drawable.erweimas); msg.setThumbImage(thumb); SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction =buildTransaction("webpage"); req.message = msg; req.scene = flag==0?SendMessageToWX.Req.WXSceneSession:SendMessageToWX.Req.WXSceneTimeline; boolean fla = wxApi.sendReq(req); System.out.println("fla="+fla); } private String buildTransaction(final String type) { return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis(); } WXEntryActivity: public class WXEntryActivity extends Activity implements IWXAPIEventHandler { // IWXAPI 是第三方app微信通信的openapi接口 private IWXAPI api; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); api = WXAPIFactory.createWXAPI(this, "wx86b3d972e5ddd153", false); api.handleIntent(getIntent(), this); } @Override public void onReq(BaseReq arg0) { } @Override public void onResp(BaseResp resp) { // LogManager.show(TAG, "resp.errCode:" + resp.errCode + ",resp.errStr:" // + resp.errStr, 1); switch (resp.errCode) { case BaseResp.ErrCode.ERR_OK: Toast.makeText(getApplicationContext(), "分享成功", 2000).show(); System.out.println("success"); this.finish(); //分享成功 break; case BaseResp.ErrCode.ERR_USER_CANCEL: //分享取消 Toast.makeText(getApplicationContext(), "分享取消", 2000).show(); System.out.println("ERR_USER_CANCEL"); this.finish(); break; case BaseResp.ErrCode.ERR_AUTH_DENIED: Toast.makeText(getApplicationContext(), "分享成功", 2000).show(); System.out.println("ERR_AUTH_DENIED"); this.finish(); //分享拒绝 break; } } } 注册该Activity : <activity android:name="com.example.leikemei.wxapi.WXEntryActivity" android:exported="true" android:screenOrientation="portrait" android:theme="@android:style/Theme.Translucent.NoTitleBar" /> ———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接本声明。 原文链接:https://blog.youkuaiyun.com/yeyuehei/article/details/30500629
最新发布
08-06
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值