|
|
本帖最后由 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()方法可以接受一个外部调用者传入的值,当此值超
出 0 到 130 的范围就被视为非法,就不再继续对 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
|