4.3.5   隐式参数与显式参数

    方法用于操作对象以及存取它们的实例域.例如,方法:


public void raiseSalary(double byPercent)
{
    double raise = salary * byPercent / 100;
    salary += raise;
}

    将调用这个方法的对象的salary实例域设置为新值.看看下面这个调用:


number007.raiseSalary(5);

    它的结果将number007.salary域的值增加5%.具体地说,这个调用将执行下列指令:


double raise = number007.salary * 5 / 100;
number007.salary += raise;

    raiseSalary方法有两个参数.第一个参数称为隐式(implicit)参数,是出现在方法名前的Employee类对象.第二个参数位于方法名后面括号中的数值,这是一个显式(explicit)参数.


    可以看到,显式参数是明显地列在方法声明中的,例如 double byPercent .隐式参数没有出现在方法声明中.


   

在每一个方法中,关键字 this 表示隐式参数.如果需要的话,可以用下列方式编写raiseSalary方法:


public void raiseSalary(double byPercent)
{
    double raise = this.salary * byPercent / 100;
    this.salaray += raise;
}


    有些程序员更偏爱这样的风格,因为这样可以将实例域与局部变量明显地区分开.
    注释
:在C++中,通常在类的外面定义方法:


void Employee::raiseSalary(double byPercent);       // C++ not Java
{
    ...
}

    如果在类的内部定义方法,这个方法将自动地成为内联(inline)方法.


class Employee
{
    ...
    int getName() { return name; }  // inline in C++
}

    在Java中,所有的方法都必须在类的内部定义,但并不表示它们是内联方法.是否将某个方法设置为内联方法是Java虚拟机的任务.


4.3.6   封装的优点

    最后再看一下简单的getName方法


public String getName()
{
    return name;
}

    它是典型的访问器方法,由于它只返回实例域值,因此又称为域访问器.


    将name域标记为 public,依次来取代独立的访问器方法会不会更容易呢?


    关键在于name是一个只读域.一旦在构造器中设置完毕,就没有任何一个方法可以对它进行修改,这样确保name域不会受到外界的破坏.


    在有些时候,需要获得或设置实例域的值.因此,

应该提供下面三项内容:


    一个私有的数据域


    一个公有的域访问器方法


    一个公有的与更改器方法


    这样做要比提供一个简单的公有数据域复杂些,但却有着下列明显的好处:


   

首先,可以改变内部实现,除了该类的方法之外,不会影响其他代码.


    例如,如果将存储名字的域改为:


String firstName;
String lastName;

    那么getName方法可以改为返回


firstName + " " + lastName

    对于这点改变,程序的其他部分完全不可见.


    当然,为了尽心新旧数据表示之间的转换,访问器方法和更改器方法有可能需要做许多工作.但是,这将为我们带来

第二点好处:更改器方法可以执行错误检查,然而直接对域进行赋值将不会进行这些处理.例如,setSalary方法可以检查薪金是否小于 0 .


   

警告:注意不要编写返回引用可变对象的访问器方法.


4.3.7   基于类的访问权限

    方法可以访问所调用对象的私有数据.一个方法可以访问所属类的所有对象的私有数据.下面看一下用于比较两个雇员的equals方法


class Employee
{
    ...
    public boolean equals(Employee other)
    {
        return name.equals(other.name);
    }
}

    典型的调用方式是


if (harry.equals(boss))  ...

    这个方法访问harry的私有域,并且还访问了boss的私有域.这是合法的,其原因是boss是Employee类对象,而Employee类的方法可以访问Employee类的任何一个对象的私有域.


   

注释:C++也有同样的原则.方法可以访问所属类的私有特性,而不仅限于访问隐式参数的私有特性.


4.3.8   私有方法

    对于私有方法,如果改用其他方法实现相应的操作,则不必保留原有的方法.如果数据的表达方式发生了变化,这个方法可能会变得难以实现,或者不再需要.然而,只要方法是私有的,类的设计者就可以确信:它不会被外部的其他类操作调用,可以将其删除.如果方法是公有的,就不能将其删除,因为其他的代码很可能依赖它.


4.3.9   final 实例域

    可以

将实例域定义为 final,构造对象时必须初始化这样的域,并且在后面的操作中,不能够再对它进行修改.例如,可以将Employee类中的name域声明为 final,因为在对象构建之后,这个值不会再被修改,即没有setName方法.


class Employee
{
    private final String name;
    ...
}

    final 修饰符大多应用于基本类型域,或不可变类的域(如果类中的每个方法都不会改变其对象,这种类就是不可变的类,例如String类).