Java 面向对象作用域全解

 

在java 中class、字段和方法都有很多的修饰词,比如public、protected、private,这些修饰词有什么作用?在什么情况下使用?我现在就来罗列一份使用清单。

一、public

public是公共的的意思,修饰class或者方法可以被其他任何类访问。 例如:有两个package包,一个是abc,另外一个是xyz。

//abc写有public方法。
package abc;

public class Hello {
    public void hi() {
    System.out.println("hello");
    }
}
//xyz调用abc中的写有public的方法。

package xyz;

import abc.Hello;

class Main {
    public static void main(String[] args) {
Hello h = new Hello();
h.hi();
}
}

二、private

private是私有的意思,所以义为private的字段和方法无法被其他类访问。 例如把上面的例子中的hi()方法设置成private就会报错。但是可以在class内部调用,而且和声明顺序无关,所以建议把私有的private定义在class的最后,这样,外部访问这个class的时候就能首先获得public方法。

package abc;

public class Hello {
public void hi() {
System.out.println("hello");
world();
}

private void world() {
System.out.println("hello world");
}

}

三、protected

protected是保护的意思,使用protected定义的字段和方法只能被子类继承,或者子类的子类。然而我一开始的做法是:

// abc 包中
package abc;

public class Hello {
protected void hi() {
System.out.println("hello");
}
}



// xyz 包中
package xyz;
import abc.Hello;

class Main{
public static void main(String[] args) {
SayHi sayhi = new SayHi();
sayhi.say();
}
}
class SayHi extends Hello{
void say() {
Hello h = new Hello();
h.hi()  // 出错
// this.hi() // 编译成功

}
}

发现会出错,原来是要同一个package包下才可以,或者把h.hi()改成this.hi()

对于这一奇怪的现象,我找了一个原因:

看到这个图的时候,我惊呆了,到底是YES,还是NO呢?

关于protected 关键字的真正内涵,很多教程含糊不清,其实要注意protected 有两个特点,

1、相同package包的情况下,基类的protected成员是包内可见的,并且对子类可见;
2、不同package包的情况下,若子类与基类不在同一包中,那么在子类中,子类实例可以访问其从基类继承而来的protected方法,而不能访问基类实例的protected方法。

其实就是这样子:

// xyz 包中
package xyz;

import abc.Hello;

class Main{
public static void main(String[] args) {
SayHi sayhi = new SayHi();
sayhi.say();
}
}
class SayHi extends Hello{
void say() {
// Compile Error 
// Hello h = new Hello();
// h.hi();
SayHi ss = new SayHi();
ss.hi();
}
}

四、package

包作用域是可以访问同一个package包下面的没有被任何关键词public、protected、private修饰的字段和方法。

五、局部变量

和我们的JavaScript中定义的变量不一样,因为java具有块级作用域,所以java定义的变量只能在该变量区域中使用。 例如,以下的例子不能在for之外访问i变量。

for (int i=0; i<10; i++) { 
	System.out.println(); 
} 

六、final

用final修饰class可以阻止被继承。就是你定义了一个可以被继承的类,然而你不想类下的每个方法都可以被覆写,这时候你可以使用final修饰方法,阻止继承。 同样的,也可以用来修饰类。

public class Hello {
    // 无法被覆写:
    protected final void hi() {
    }
}

七、static

java中还可以用static修饰字段和方法,具体请查看我的另外一篇文章有更加详细的讲解: 图文解析Java静态字段和方法

八、interface

Java的接口特指interface的定义,表示一个接口类型和一组方法签名。具体请查看我的另外一篇文章有更加详细的讲解: 快速掌握Java 面向对象编程抽象类和接口

推荐更多简明阅读:

Java 一篇搞定面向对象中的多态

Java面向对象的继承——简明教程

Java 中的构造方法详细解析

Java 面向对象和绑定参数的图文理解

本文为博主原创文章,知识共享,开源精神,转载注明出处。