Thinking In Java -- Chapter 6 -- 访问权限控制

包:库单元


如果我创建了一个工具库,库中有一个工具类Print,在类中,通过public 加 static的形式定义了一些方法,那么通过静态导入后,就可以直接使用此方法,如下例是创建的工具类:

package net.mindview.util;
import java.io.*;

public class Print {
    //print with a new line
    public static void print(Object obj) {
        System.out.println(obj);
    }
    //print a new line by itself
    public static void print() {
        System.out.println();
    }
    //print with no line break
    public static void printnb(Object obj) {
        System.out.print(obj);
    }
    //The new Java SE5 printf() (from C);
    public static PrintStream
    printf(String format,object... args) {
        return System.out.printf(format, args);
    }
}
    

下面通过对上面工具类进行静态导入,就可以直接使用静态的print()和printnb()方法了,如下例:

//: access/PrintTest.java
// Uses the static printing methods in Print.java.
import static net.mindview.util.Print.*;

public class PrintTest {
  public static void main(String[] args) {
    print("Available from now on!");
    print(100);
    print(100L);
    print(3.14159);
  }
} /* Output:
Available from now on!
100
100
3.14159
*///:~

Java访问权限修饰词:


  1. 取得对某成员的访问权的方式:使该成员成为public;放置于同一个包内,这样就互相有了包访问权限;继承而来的类可以访问public和protected成员,但无法访问privated成员;通过get和set方法(这是最优雅的方式,也是JavaBeans的基本原理)。
  2. 如果类有唯一的构造器,并且该构造器是private的,那么该类无法直接通过构造器来创建对象,并且它将阻碍对此类的继承。
  3. protected处理的是继承的概念,直接用例子来了解protected权限的使用,首先是父类:
    //: access/dessert/Cookie.java
    package access.dessert;
    
    public class Cookie {
      public Cookie() {
        System.out.println("Cookie constructor");
      }
      void bite() {
        System.out.println("bite");
      }
    } ///:~

    父类位于access.dessert包下,其中的bite()方法由于没使用权限修饰词,所以默认是包访问权限。然后我们在其他包中创建一个类来继承这个父类,如下例:

    //: access/ChocolateChip.java
    // Can't use package-access member from another package.
    import access.dessert.*;
    
    public class ChocolateChip extends Cookie {
      public ChocolateChip() {
       System.out.println("ChocolateChip constructor");
      }
      public void chomp() {
        //! bite(); // Can't access bite
      }
      public static void main(String[] args) {
        ChocolateChip x = new ChocolateChip();
        x.chomp();
      }
    } /* Output:
    Cookie constructor
    ChocolateChip constructor
    *///:~
    

    可以发现,在其他包中的子类是无法使用父类的bite()方法的,因为此时的bite()方法有包访问权限而且位于另一个包内,所以我们在这个包内是无法使用它的。当然如果你可以给它指定成public,但是这样所有人都有了访问权限。那么这时我们就可以将被继承的父类这么改:

    //: access/cookie2/Cookie.java
    package access.cookie2;
    
    public class Cookie {
      public Cookie() {
        System.out.println("Cookie constructor");
      }
      protected void bite() {
        System.out.println("bite");
      }
    } ///:~

    现在子类就可以访问bite()方法了。

接口和实现:


访问权限的控制,常被称为具体实现的隐藏。把数据和方法包装进类中,以及具体实现的隐藏,常共同被称为封装(然后,人们经常只单独将具体实现的隐藏称作封装)。其结果是一个同时具有特征和行为的数据类型。

类的访问权限:


如果不希望其他任何人对类具有访问权限,那么把所有的构造器都指定为private,从而阻止任何人创建该类的对象,但是也有一个例外,就是你在该类的static成员内部可以创建,如下例:

//: access/Lunch.java
// Demonstrates class access specifiers. Make a class
// effectively private with private constructors:

class Soup1 {
  private Soup1() {}
  // (1) Allow creation via static method:
  public static Soup1 makeSoup() {
    return new Soup1();
  }
}

class Soup2 {
  private Soup2() {}
  // (2) Create a static object and return a reference
  // upon request.(The "Singleton" pattern):
  private static Soup2 ps1 = new Soup2();
  public static Soup2 access() {
    return ps1;
  }
  public void f() {}
}

// Only one public class allowed per file:
public class Lunch {
  void testPrivate() {
    // Can't do this! Private constructor:
    //! Soup1 soup = new Soup1();
  }
  void testStatic() {
    Soup1 soup = Soup1.makeSoup();
  }
  void testSingleton() {
    Soup2.access().f();
  }
} ///:~

其中上例中,Soup2()用了所谓的设计模式,这种是单例模式,这是因为你始终都只能创建它的一个对象。Soup2类的对象是作为Soup2的一个static private成员创建的,所以有且仅有一个,而且除非是通过public 方法access(),否则是无法访问到它的。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值