Java的面向对象 -- 作用域

在Java中,我们经常看到 publicprotectedprivate 这些修饰符。在Java中,这些修饰符可以用来限定访问作用域。

public

定义为 publicclassinterface 可以被其他任何类访问:

package abc;

public class Hello {
    public void hi() {
    }
}

上面的 Hellopublic ,因此,可以被其他包的类访问:

package xyz;

class Main {
    void foo() {
        // Main可以访问Hello
        Hello h = new Hello();
    }
}

定义为 publicfieldmethod 可以被其他类访问,前提是首先有访问class的权限:

package abc;

public class Hello {
    public void hi() {
    }
}

上面的 hi() 方法是 public ,可以被其他类调用,前提是首先要能访问Hello类:

package xyz;

class Main {
    void foo() {
        Hello h = new Hello();
        h.hi();
    }
}
private

定义为 privatefieldmethod 无法被其他类访问:

package abc;

public class Hello {
    // 不能被其他类调用:
    private void hi() {
    }

    public void hello() {
        this.hi();
    }
}

实际上,确切地说,private 访问权限被限定在 class 的内部,而且与方法声明顺序无关。推荐把 private 方法放到后面,因为 public 方法定义了类对外提供的功能,阅读代码的时候,应该先关注 public 方法:

package abc;

public class Hello {
    public void hello() {
        this.hi();
    }

    private void hi() {
    }
}

由于Java支持嵌套类,如果一个类内部还定义了嵌套类,那么,嵌套类拥有访问 private 的权限:

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

    // private方法:
    private static void hello() {
        System.out.println("private hello!");
    }

    // 静态内部类:
    static class Inner {
        public void hi() {
            Main.hello();
        }
    }
}

定义在一个 class 内部的 class 称为嵌套类(nested class),Java支持好几种嵌套类。

protected

protected 作用于继承关系。定义为 protected 的字段和方法可以被子类访问,以及子类的子类:

package abc;

public class Hello {
    protected void hi() {
    }
}

上面的 protected 方法可以被继承的类访问:

package xyz;

class Main extends Hello {
    void foo() {
        Hello h = new Hello();
        // 可以访问protected方法:
        h.hi();
    }
}
package

最后,包作用域 是指一个类允许访问同一个 package 的没有 publicprivate 修饰的 class ,以及没有 publicprotectedprivate 修饰的字段和方法。

package abc;
// package权限的类:
class Hello {
    // package权限的方法:
    void hi() {
    }
}

只要在同一个包,就可以访问 package 权限的 classfieldmethod

package abc;

class Main {
    void foo() {
        // 可以访问package权限的类:
        Hello h = new Hello();
        // 可以调用package权限的方法:
        h.hi();
    }
}

注意,包名必须完全一致,包没有父子关系,com.apache 和com.apache.abc是不同的包。

在这里插入图片描述

局部变量

在方法内部定义的变量称为局部变量,局部变量作用域从变量声明处开始到对应的块结束。方法参数也是局部变量。

package abc;

public class Hello {
    void hi(String name) { // ①
        String s = name.toLowerCase(); // ②
        int len = s.length(); // ③
        if (len < 10) { // ④
            int p = 10 - len; // ⑤
            for (int i=0; i<10; i++) { // ⑥
                System.out.println(); // ⑦
            } // ⑧
        } // ⑨
    } // ⑩
}

我们观察上面的 hi() 方法代码:

方法参数 name 是局部变量,它的作用域是整个方法,即 ①~⑩;

变量 s 的作用域是定义处到方法结束,即 ②~⑩;

变量 len 的作用域是定义处到方法结束,即 ③~⑩;

变量 p 的作用域是定义处到 if 块结束,即 ⑤~⑨;

变量 i 的作用域是for循环,即 ⑥~⑧。

使用局部变量时,应该尽可能把局部变量的作用域缩小,尽可能延后声明局部变量。

final

Java还提供了一个 final 修饰符。final 与访问权限不冲突,它有很多作用。

final 修饰 class 可以阻止被继承:

package abc;

// 无法被继承:
public final class Hello {
    private int n = 0;
    protected void hi(int t) {
        long i = t;
    }
}

final 修饰 method 可以阻止被子类覆写:

package abc;

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

final 修饰 field 可以阻止被重新赋值:

package abc;

public class Hello {
    private final int n = 0;
    protected void hi() {
        this.n = 1; // error!
    }
}

final 修饰局部变量可以阻止被重新赋值:

package abc;

public class Hello {
    protected void hi(final int t) {
        t = 1; // error!
    }
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值