方法及修饰符


Java 中定义一个方法的格式大概如下:

访问权限修饰符 修饰符 返回类型 方法名(参数类型 参数名, ....) {//参数个数 >= 0
    方法体
}

访问权限修饰符:

  • public 共有的:意味着任何类的任何方法都可以调用这些实例域或方法
  • private 私有的:意味着只有类自身的方法能够访问这些实例域或方法,而其他类的方法不能够读写这些实例域或方法
  • protected 受保护的:意味着只有同一个包内的方法和子类的方法可以调用这些实例域或方法
  • 无修饰符则对本包可见(默认)

上表格更清楚些~

修饰符 本类 同包类 子类 其他类
public 可以访问 可以访问 可以访问 可以访问
protected 可以访问 可以访问 可以访问 不能访问
无(默认) 可以访问 可以访问 不能访问 不能访问
private 可以访问 不能访问 不能访问 不能访问

访问修饰符也可以修饰类
private 和 protected 只能修饰内部类(类的内部定义的类)
public 和 默认既可以修饰内部类,也可以修饰外部类。

public class Class {
    class 内部类{
        ...
    }
}
class 外部类 {
    ...
}

可以用 public 标记实例域,但这是一种极为不提倡的做法。public 数据域允许程序中的任何方法对其进行读取和修改。这就完全破坏了封装。任何类的任何方法都可以修改 public 域,意味着某些代码将使用这种存取权限,所以强烈建议将实例域标记为 private。


## 静态修饰符 static ### 静态域(静态变量) 如果将域定义为 static,则**每个类中只有一个这样的变量**。而每一个对象对于所有的实例域(成员变量)却都有自己的一份拷贝。例如,需要给每一个蜜蜂赋予唯一的标识码:
public class Bee {
    private static int nextId = 1;
    private int id;
    ...
}

现在,每一个蜜蜂对象都有一个自己的 id 域,但这个类的所有实例(所有蜜蜂)将共享一个 nextId 域。换句话说,如果有 1000 个 Bee 类的对象,择优 1000 个实例域 id。但是,只有一个静态域 nextId。即使没有一个 Bee 对象,静态域 nextId 也存在。它属于类,而不属于任何一个独立的对象。


### 静态常量 静态变量是用的比较少,但静态常量(static final)却使用的比较多。如 Math 类中定义了一个静态常量:
public class Math {
    ...
    public static final double PI = 3.14159265358979323846;
    ...
}

在程序中,可以采用 Math.PI 的形式获得这个常量。

前面说过,由于每个类对象都可以对公有域(public 修饰的域)进行修改,所以最好不要讲域设计为 public。然而,共有常量(final)却没问题,因为 PI 被声明为 final,所以不允许被修改。


### 静态方法 **被 static 修饰的方法就是静态方法。静态方法是一种不能向对象实施操作的方法。**换句话说,静态方法没有隐式的参数(没有 this)。静态方法的调用方式为:
类名.静态方法名(参数...);

例如 Math 类的 pow 方法就是一个静态方法:

Math.pow(x, a);

计算幂 $$ x^a $$ 在运算时,不使用任何 Math 对象,换句话说,静态方法没有隐式参数(即静态方法是没有 this 参数的方法)

Bee 类的静态方法不能访问 id 实例域,因为它不能操作对象。但是静态方法可以访问自身类中的静态域:

public static int getNextId() {
    return nextId;//返回静态域
}

可以通过类名调用这个方法:

int n = Bee.getNextId();

这个方法可以省略关键字 static,但是需要通过 Bee 类对象的引用调用这个方法。

此外,可以使用对象调用静态方法,但是不推荐。例如 b 是一个 Bee 对象,可以用b.getNextId() 代替Bee.getNextId()。但是这种方式很容易造成混淆,原因是 getNextId 方法计算的结果与 b 毫无关系。所以建议使用类名来调用静态方法。


## final 修饰符 ### final 类与 final 方法 **不允许被继承的类称为 final 类:**
final class Bee() extends FlyObject {
    ...
}

同样,类中的方法也可以被声明为 final。子类不能重写父类中的 final 方法。

将方法或类声明为 final 的主要目的是确保它们不会在子类中改变语义。


### final 常量 - 静态必须在声明的同时初始化,而非静态常量可以不用在声明时初始化。 - 静态常量命名习惯上将所有字母都大写。

具体请参考之前的笔记《变量与常量


## 返回类型 **注明该方法需要返回的数据类型,如果该方法不需要返回任何数据则返回类型写 void。**

方法的结果返回

return:结束该方法并返回方法的操作结果,如果该方法是有返回值,则通过

return 结果;//返回的结果数据类型必须和该方法标明的返回类型相同

将结果返回出去。若该方法没有返回值(void)则可以不写 return,或使用

return;

来提前结束方法的执行。


## 方法名 用户自定义方法的名字,习惯上把第一个单词小写,之后每个单词首字母大写。
## 参数

方法可以有个 0~n 个参数,每个参数都需要指定参数类型,并且用”,”隔开每个参数
形参:在定义方法的时候定义的参数

实参:调用方法的时候传入的实际参数

Java 中调用方法时,传给方法的是实参,而方法得到的参数值是所有实参的一个拷贝(形参),也就是一个方法不能修改传递给它的基本数据类型参数变量的值。

public void addFive(int x) {
    x = x + 5;
    System.out.println("形参 x 的值:" + x);
}
int X = 5;
addFive(X);//这里将输出“形参 x 的值:10”
System.out.println("实参 X 的值:" + X);//此时 X 还是 5

可以看到,无论怎样,调用这个方法之后,X 的值还是 5。

然而,方法参数共有两种类型:

  • 基本数据类型
  • 对象引用类型

如果参数是对象引用作类型,则可以很容易的实现改变对象参数状态

public void initLocation(Bee b) {
    b.x = 0;
    b.y = 0;
}
Bee bee = new Bee(1, 2);//构造一个初始坐标为 1, 2 的 Bee 对象
System.out.println("bee 的坐标:" + bee.x + "  " + bee.y);//输出当前坐标为 1, 2
initLocation(bee);
System.out.println("bee 的坐标:" + bee.x + "  " + bee.y);//此时输出当前坐标为 0, 0

该代码具体的执行过程为:

  1. b 被初始化为bee 值的拷贝,这里是一个对象的引用。
  2. initLocation 方法应用于这个对象引用。 b 和 bee 同时引用的那个 Bee 对象的坐标改为了 0,0
  3. 方法结束后, 参数变量 b 不再使用,但是变量 bee 继续引用那个坐标改为 0,0 的 Bee 对象。

为了理解形参是实参的拷贝,再举个例子:

public void swap (Bee a, Bee b) {//交换两个对象
    Bee temp = a;
    a = b;
    b = temp;
}
//定义两个 Bee 对象
Bee beea = new Bee(1,1);
Bee beeb = new Bee(2,2);
System.out.println("beea 的坐标为" + beea.toString() + "  beeb 的坐标为" + beeb.toString());
swap(beea,beeb);//调用方法打断交换 beea 和 beeb 的值
System.out.println("beea 的坐标为" + beea.toString() + "  beeb 的坐标为" + beeb.toString());

然而上面这段代码输出的两个结果是完全一样的。这个 swap 方法并没有改变储存在变量 beea 和 beeb 中的对象引用。swap 方法的参数 a 和 b 被初始化为两个对象引用的拷贝,交换的也是两个对象的拷贝。原来的变量 beea 和 beeb 仍然引用调用方法之前所引用的对象。

哈哈 有点绕,晕了的话多看几遍~

总结一下 Java 参数的使用情况:

  • 一个方法不能修改一个基本数据类型的参数(即数值型和布尔型)。
  • 一个方法可以改变一个对象参数的状态。
  • 一个方法不能让对象参数引用一个新的对象

## 方法体 就是这个方法需要做的事咯!具体要做啥那是你的事~
## 方法的调用 方法是需要被调用才能执行的。

文章作者: CrazyBunQnQ
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明来源 CrazyBunQnQ !
 上一篇
Hello World Hello World
Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hex
2017-03-10
下一篇 
面向对象(一) 面向对象(一)
面向对象程序设计简称 OOP 面向对象的程序是由对象组成的,每个对象包含对用户公开的特定功能部分和隐藏的实现部分。程序中的很多对象来自标准库,还有一些是自定义的。究竟是自己构造对象,还是从外界购买对象完全取决于开发项目的预算时间。在 OO
2017-02-28
  目录