返回列表 发新帖

【Android入坑系列教程】36.类与对象(二)---面向对象

[复制链接]

62

主题

722

回帖

2756

积分

大学生

Rank: 5Rank: 5

金币
2029
好评
12
信誉
100

考神

发表于 2019-3-25 16:26:30 | 显示全部楼层 | 阅读模式  来自 四川
本帖最后由 pansong291 于 2019-3-26 12:36 编辑

上篇:35.类与对象(一)---面向对象
下篇:37.构造函数---面向对象

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


匿名对象
创建完对象,在调用该对象的方法时,我们也可以不定义对象的句柄,而直接调用这个
对象的方法。这样的对象叫做匿名对象,我们把前面的 Person 程序中的代码:
Person p1=new Person();
p1.shout();
改写成:
new Person().shout();
这句代码没有产生任何句柄,而是直接用 new 关键字创建了 Person 类的对象并直接调
用它的 shout()方法,得出的结果和改写之前是一样的。这个方法执行完,这个对象也就变
成了垃圾。
使用匿名对象的两种情况:
1).如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象。
2).我们经常将匿名对象作为实参传递给一个函数调用,比如程序中有一个 getSomeOne
函数,要接收一个 Person 类对象作为参数,函数定义如下:
public static void getSomeOne(Person p)
{
    ……
}
我们可以用下面的语句调用这个函数。
getSomeOne(new Person());

实现类的封装性
细心的读者可能已经发现,在上面定义的 Person 类产生的对象中,我们可以直接操作
其中的成员变量 age,并且使用了
Person p1 = new Person();
p1.age = -30;
这样的代码段,显然在实际应用中,不应该出现这样的情况,这样做会导致数据的错误、
混乱或安全性问题。如果外面的程序可以随意修改一个类的成员变量,会造成不可预料的程
序错误,就象一个人的身高,不能被外部随意修改,只能通过各种摄取营养的方法去修改这
个属性。
我们怎样对一个类的成员实现这种保护呢?我们只需要在定义一个类的成员(包括变量
和方法)时,使用 private 关键字说明这个成员的访问权限,这个成员成了类的私有成员,
只能被这个类的其他成员方法调用,而不能被其他的类中的方法所调用。先来看一段代码:
class Person
{
    private int age;
    public void shout()
    {
        System.out.println(age); //这一句没有错误
    }
}
class TestPerson
{
    public static void main(String[] args)
    {
        new Person().age = -30;
    }
}
编译器会报错:

错误的意思是:'Person'中的未知字段'age',就是找不到'age'成员。因为 age 是 Person
类里的私有变量,不能在其他类中直接调用和修改。虽然在类 TestPerson 中用的是
“对象.对象成员”的格式去访问Person 类中的 age 属性,这是从其他类访问另外一个类
实例对象的成员的必要格式,但这也是不行的,因为一个类里的成员(包括变量和方法)
一旦用 private 加以修饰,就变成该类的私有成员,这个类之外的其它类就再也不能访问它了。
明白了 private 关键字,大家就自然明白了 public 关键字,如果用 public 修饰类里的
成员,那么,这些成员就变成公有的,并可以在任意类中访问这种成员,当然,要在一个类
外部访问这个类的成员,只能是用“对象.对象成员”的格式。
为了实现良好的封装性,我们通常将类的成员变量声明为 private,再通过 public
方法来对这个变量进行访问。对一个变量的操作,一般都有读取和赋值操作,我们分别定义
两个方法来实现这两种操作,一个是 getXxx()(Xxx 表示要访问的成员变量的名字),用来
读取这个成员变量操作,另外一个是 setXxx()用来对这个成员变量赋值。按照刚才所讲的
思路,我们按下面的代码来修改 Person 类的定义。
class Person
{
    private int age;
    public void setAge(int i)
    {
        if(i<0 || i>130)
            return;
        age = i;
    }
    public int getAge()
    {
        return age;
    }
}
public class TestPerson
{
    public static void main(String args[])
    {
        Person p1 = new Person();
        p1.setAge(3);
        p1.setAge(-6);
        System.out.println(p1.getAge());
    }
}
这段程序的 Person 类里,成员变量 age 被定义成了私有(private)变量,这样就只有
该类中的其他成员可以访问它,然后在该类中定义两个公有(public)的方法 setAge()
getAge()供外部调用者访问,setAge()方法可以接受一个外部调用者传入的值,当此值超
0130 的范围就被视为非法,就不再继续对 age 变量进行赋值操作,如果在此范围内就
被赋值给成员变量 age,而 getAge()方法可以给外部调用者返回 age 变量的值,外部调用者
只能访问这两个方法,不能直接访问成员变量 age。我们通过将类的成员变量声明为私有的
private),再提供一个或多个公有(public)方法实现对该成员变量的访问或修改,这种
方式就被称为封装。实现封装可以达到如下目的:
1. 隐藏类的实现细节;
2. 让使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属
性的不合理操作;
3. 便于修改,增强代码的可维护性;
4. 可进行数据检查;
当然,在实际应用中,对于错误赋值的处理,我们不会只是简单地将变量赋 0 值就算完
事,我们可以使用更有效的方式去处理这种非法调用,更有效的通知调用者非法调用的原因。
这就是我们以后要讲到的抛出异常的方式,读者可以暂时不必细究这个问题,在后面的章节
中会有详细的介绍的。
指点迷津:
一个类通常就是一个小的模块,我们应该让模块仅仅公开必须要让外界知道的内容,而
隐藏其它一切内容。我们在进行程序的详细设计时,应尽量避免一个模块直接修改或操作另
一个模块的数据,模块设计追求强内聚(许多功能尽量在类的内部独立完成,不让外面干预),
弱耦合(提供给外部尽量少的方法调用)。一支军队对总统只提供一个接收作战命令的
public 方法,至于这支军队在接到作战命令后所要执行的各个作战过程,由这支军队内部
来完成就行了,没必要让总统来直接操作这支军队具体的作战过程,将这些具体的作战过程
做成 private 方法,这样,总统在调遣这支军队时,只有一个方法可以被使用,这样的总统
工作谁都会干,这不正是总统们期望的效果吗?
多学两招:
我们在一个类中定义了一个 private 类型的成员变量,接着产生了这个类的两个实例对
象,请问第一个对象的方法中,能否以“第二个对象.成员”的格式访问第二个对象中的那个
private 成员变量?通过下面的试验程序代码,就可以找到答案。
class A
{
    private int x=3;
    public static void main(String [] args)
    {
        new A().func(new A());
    }
    public void func(A a)
    {
        System.out.println(a.x);
    }
}
编译运行上面程序,没有任何问题,在
new A().func(new A());
语句中,一共用 new A()产生了两个对象,在第一个对象的 func 方法中成功地访问了
第二个对象的 private 成员变量 x。

上篇:35.类与对象(一)---面向对象
下篇:37.构造函数---面向对象

本帖子中包含更多资源

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

x
回复

使用道具 举报

1

主题

2283

回帖

4494

积分

大学生

Rank: 5Rank: 5

金币
2610
好评
1
信誉
100
发表于 2019-3-25 19:00:36 | 显示全部楼层  来自 河北
一看是你的贴子,我就不敢回
回复

使用道具 举报

发表回复

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

本版积分规则

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