返回列表 发新帖

【Android入坑系列教程】38.this引用句柄---面向对象

[复制链接]

62

主题

722

回帖

2756

积分

大学生

Rank: 5Rank: 5

金币
2029
好评
12
信誉
100

考神

发表于 2019-3-27 11:54:37 | 显示全部楼层 | 阅读模式  来自 四川
本帖最后由 pansong291 于 2019-3-28 11:39 编辑

上篇:37.构造函数---面向对象
下篇:39.函数的参数传递---面向对象

注意:如果你的回复只是“感谢分享”、“辛苦了”之类的与教程内容无关的字眼,还请不要回复本帖,谢谢合作!!!
注意:如果你的回复只是“感谢分享”、“辛苦了”之类的与教程内容无关的字眼,还请不要回复本帖,谢谢合作!!!
注意:如果你的回复只是“感谢分享”、“辛苦了”之类的与教程内容无关的字眼,还请不要回复本帖,谢谢合作!!!


一个对象中的一个成员方法,可以引用另外一个对象的成员,如下面的程序代码:
class A
{
    String name;
    public A(String x)
    {
        name = x;
    }
    public void func1()
    {
        System.out.println("func1 of " + name +" is calling");
    }
    public void func2()
    {
        A a2 = new A("a2");
        a2.func1();
    }
}
class TestA
{
    public static void main(String [] args)
    {
        A a1 = new A("a1");
        a1.func2();
    }
}
在上面的程序中,我们一共产生了两个类 A 的实例对象,在 a1 的 fun2 中,我们调用了
a2 的 fun1。我们现在把眼光集中在 fun2 中的代码上,我们已经看到了如何在 func2 中引用
另外一个对象的成员,在 func2 运行期间的内存状态如图 3.13 所示。

第一个要想明白的问题是,如果 func2 方法被调用,是不是一定要以“对象.func2”的
方式进行呢?是的,那就是说,func2 被调用时,一定是事先已经有了一个存在的对象,func2
被作为那个对象的方法被使用。
第二个要想明白的问题是,我们在 func2 内部能引用别的对象,我们能不能在 func2
内部引用那个“事先存在并对 func2 进行调用”的对象呢?我们将这个“事先存在并对 func2
进行调用”的对象就叫 func2 所属的那个对象,对于一个方法来说,只要是对象,它就可以
调用,它根本就不区分是不是自己所属的那个对象!
肯定搞清楚了上面的两个问题后,我们接着来思考下面的问题,在 func2 中,怎么引用
自己所属的那个对象呢?也就是自己所属的那个对象的引用名称是什么呢?是 a1 吗?那个
对象在 TestA.main 方法中叫 a1,但在 func2 内就不叫 a1 了,因为,我们在定义 func2 时,
对象 a1 还没产生,我们不可能提前知道以后产生的类 A 的每个实例对象的引用名称。另外,
如果我们在 func2 中用 a1 代表了 func2 所属的那个对象,那么,当我们调用 a2.func2()时,
这时的 func2 所属的那个对象就不再是 a1 了,而是 a2 了,显然我们在 func2 中不能用以后
定义的对象引用名来引用它所属的那个对象。this 关键字在 java 程序里的作用和它的词义
很接近,它在函数内部就是这个函数所属的对象的引用变量。
我们修改类 A 的程序代码,在 func2 中使用 this 关键字调用 func1 方法。
class A
{
    String name;
    public A(String x)
    {
        name = x;
    }
    public void func1()
    {
        System.out.println("func1 of " + name +" is calling");
    }
    public void func2()
    {
        A a2 = new A("a2");
        this.func1(); //使用 this 关键字调用 func1 方法
        a2.func1();
    }
}
重新编译后,运行类 TestA,结果如下:
func1 of a1 is calling
func1 of a2 is calling

我们前面讲过,一个类中的成员方法可以直接调用同类中的其他成员,其实我们将
this.func1();调用直接写成 func1();调用,效果是一样的。
对于类 A 中的构造函数:
public A(String x)
{
    name = x;
}
可以改写成如下形式:
public A(String x)
{
    this.name = x;
}
在成员方法中,对访问的同类中成员前加不加 this 引用,效果都是一样的,这就好像
同一个公司的职员彼此在提及和自己公司有关的事时,不必说出公司名一样,当然为了强调,
可以加上“咱们公司... ”这样的前缀,在程序里同样可以如此,而 this 就相当于 “我
所属于的那个对象”。每个成员方法内部,都有一个 this 引用变量,指向调用这个方法的对
象,刚才我们所用的类 A 中的成员方法与 this 之间的关系如图 3.14 所示。

说了半天,读者应该总算明白 this 关键字的意义了,但好象用不用 this,程序效果都
一样,那 this 还有多大的作用呢?在有些情况下,我们还是非得用 this 关键字不可的。
1).我们想通过构造方法将外部传入的参数赋值给类成员变量,构造方法的形式参数名
称与类的成员变量名相同。
class Person
{
    String name;
    Public Person(String name)
    {
        name=name;
    }
}
在这段代码里,读者肯定会对 name=name; 这样的赋值语句莫名其妙,根本分不出哪个
是成员变量,哪个是方法的变量。有人说,你定义构造方法的形式参数名称不要与类成员变
量名相同,不就解决这个问题了吗?虽然在前面的例子中,我们都是这样做的,那是因为我们
还没讲到 this 的原因,只是为了讲课而这么做的,这在实际应用中绝对不是一个好注意。
软件工程学中要求我们不仅要完成程序的功能,还要追求程序代码良好的可理解性,让类的
成员变量名和对其进行赋值的成员方法的形参变量同名是必要的,这样的代码谁看了都能明
白这两个变量是彼此相关的,老手看到函数的定义,就能揣摩出函数中的代码,大大节省了
别人和自己日后阅读程序的时间。
形式参数就是方法内部的一个局部变量,成员变量与方法中的局部变量同名时,在该方
法中对同名变量的访问是指那个局部变量。如果明白了这个道理和 this 关键字的作用,我
们就可以修改上面的程序代码,来达到我们的目的。
class Person
{
    String name;
    Public Person(String name)
    {
        this.name=name;
    }
}
2).假设我们有一个容器类和一个部件类,在容器类的某个方法中要创建部件类的实例
对象,而部件类的构造方法要接收一个代表其所在容器的参数,程序代码如下:
class Container
{
    Component comp;
    public void addComponent()
    {
        comp = new Component(this); //将 this 作为对象引用传递
    }
}
class Component
{
    Container myContainer;
    public Component(Container c)
    {
        myContainer = c;
    }
}
读者在脑子中,多想想各对象在内存中的状态,就很容易看懂上面的代码的。我不希望
读者学完这本书后,还要我来提醒你:“读代码时,不是专盯代码本身,而是要看内存状态”,
但在这本书中,我还得反复强调,反复地说。下面的图 3.15 所示是我在脑海中设想的内存
状态,供你参考。

这就是通过 this 引用把当前的对象作为一个参数传递给其它的方法和构造方法的应
用。
构造方法是在产生对象时被 Java 系统自动调用的,我们不能在程序中象调用其他
方法一样去调用构造方法。但我们可以在一个构造方法里调用其他重载的构造方法,不是用
构造方法名,而是用 this(参数列表)的形式,根据其中的参数列表,选择相应的构造方法。
public class Person
{
    String name;
    int age;
    public Person(String name)
    {
        this.name = name;
    }
    public Person(String name, int age)
    {
        this(name);
        this.age = age;
    }
}
在类 Person 的第二个构造方法中,我们通过 this()调用,执行第一个构造方
法中的代码。

上篇:37.构造函数---面向对象
下篇:39.函数的参数传递---面向对象

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

9

主题

715

回帖

1617

积分

高中生

Rank: 4

金币
196
好评
1
信誉
100
QQ
发表于 2019-3-27 12:22:36 来自手机  | 显示全部楼层  来自 广东
感谢分享
回复

使用道具 举报

0

主题

380

回帖

822

积分

高中生

Rank: 4

金币
195
好评
1
信誉
100
发表于 2019-4-26 23:00:34 | 显示全部楼层  来自 河南
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表