198页下程序
//: c05:ToolTest.java
// Uses the tools library.
import com.bruceeckel.tools.*;
public class ToolTest {
public static void main(String[] args) {
P.rintln("Available from now on!");
P.rintln("" + 100); // Force it to be a String
P.rintln("" + 100L);
P.rintln("" + 3.14159);
}
} ///:~
200-201页程序
//: com:bruceeckel:tools:Assert.java
// Turning off the assertion output
// so you can ship the program.
package com.bruceeckel.tools;
public class Assert {
public final static void is_true(boolean exp){}
public final static void is_false(boolean exp){}
public final static void
is_true(boolean exp, String msg) {}
public final static void
is_false(boolean exp, String msg) {}
} ///:~
201页中程序
//: c05:TestAssert.java
// Demonstrating the assertion tool.
// Comment the following, and uncomment the
// subsequent line to change assertion behavior:
import com.bruceeckel.tools.debug.*;
// import com.bruceeckel.tools.*;
204页上程序
//: c05:Dinner.java
// Uses the library.
import c05.dessert.*;
public class Dinner {
public Dinner() {
System.out.println("Dinner constructor");
}
public static void main(String[] args) {
Cookie x = new Cookie();
//! x.bite(); // Can‘t access
}
} ///:~
204页下程序
//: c05:Cake.java
// Accesses a class in a
// separate compilation unit.
class Cake {
public static void main(String[] args) {
Pie x = new Pie();
x.f();
}
} ///:~
在位于相同目录的第二个文件里:
205页上程序
//: c05:Pie.java
// The other class.
class Pie {
void f() { System.out.println("Pie.f()");
}
} ///:~
最初可能会把它们看作完全不相干的文件,然而Cake能创建一个Pie对象,并能调用它的f()方法!通常的想法会认为Pie和f()是“友好的”,所以不适用于Cake。它们确实是友好的——这部分结论非常正确。但它们之所以仍能在Cake.java中使用,是由于它们位于相同的目录中,而且没有明确的包名。Java把象这样的文件看作那个目录“默认包”的一部分,所以它们对于目录内的其他文件来说是“友好”的。
210-211页程序
//: c05:Lunch.java
// Demonstrates class access specifiers.
// Make a class effectively private
// with private constructors:
class Soup {
private Soup() {}
// (1) Allow creation via static method:
public static Soup makeSoup() {
return new Soup();
}
// (2) Create a static object and
// return a reference upon request.
// (The "Singleton" pattern):
private static Soup ps1 = new Soup();
public static Soup access() {
return ps1;
}
public void f() {}
}
class Sandwich { // Uses Lunch
void f() { new Lunch(); }
}
// Only one public class allowed per file:
public class Lunch {
void test() {
// Can‘t do this! Private constructor:
//! Soup priv1 = new Soup();
Soup priv2 = Soup.makeSoup();
Sandwich f1 = new Sandwich();
Soup.access().f();
}
} ///:~
214页程序
///: c05:local:PackagedClass.java
package c05.local;
class PackagedClass {
public PackagedClass() {
System.out.println(
"Creating a packaged class");
}
} ///:~
然后在c05之外的另一个目录里创建下述文件:
214-215页程序
///: c05:foreign:Foreign.java
package c05.foreign;
import c05.local.*;
public class Foreign {
public static void main (String[] args) {
PackagedClass pc = new PackagedClass();
}
} ///:~
解释编译器为什么会产生一个错误。将Foreign(外部)类作为c05包的一部分改变了什么东西吗?
Exercises
1.Write a program that creates an ArrayList object without explicitly importing java.util.*.
2.In the section labeled “package: the library unit,” turn the code fragments concerning mypackage into a compiling and running set of Java files.
In the section labeled “Collisions,” take the code fragments and turn them into a program, and verify that collisions do in fact occur.
Generalize the class P defined in this chapter by adding all the overloaded versions of rint( ) and rintln( ) necessary to handle all the different basic Java types.
Change the import statement in TestAssert.java to enable and disable the assertion mechanism.
Create a class with public, private, protected, and “friendly” data members and method members. Create an object of this class and see what kind of compiler messages you get when you try to access all the class members. Be aware that classes in the same directory
are part of the “default” package.
Create a class with protected data. Create a second class in the same file with a method that manipulates the protected data in the first class.
Change the class Cookie as specified in the section labeled “protected: ‘sort of friendly.’” Verify that bite( ) is not public.
In the section titled “Class access” you’ll find code fragments describing mylib and Widget. Create this library, then create a Widget in a class that is not part of the mylib package.
Create a new directory and edit your CLASSPATH to include that new directory. Copy the P.class file (produced by compiling com.bruceeckel.tools.P.java) to your new directory and then change the names of the file, the P class inside and the method names. (You
might also want to add additional output to watch how it works.) Create another program in a different directory that uses your new class.
Following the form of the example Lunch.java, create a class called ConnectionManager that manages a fixed array of Connection objects. The client programmer must not be able to explicitly create Connection objects, but can only get them via a static method
in ConnectionManager. When the ConnectionManager runs out of objects, it returns a null reference. Test the classes in main( ).
Create the following file in the c05/local directory (presumably in your CLASSPATH):
///: c05:local:PackagedClass.java
package c05.local;
class PackagedClass {
public PackagedClass() {
System.out.println(
"Creating a packaged class");
}
} ///:~
Then create the following file in a directory other than c05:
///: c05:foreign:Foreign.java
package c05.foreign;
import c05.local.*;
public class Foreign {
public static void main (String[] args) {
PackagedClass pc = new PackagedClass();
}
} ///:~
Explain why the compiler generates an error. Would making the Foreign class part of the c05.local package change anything?
[33] There’s nothing in Java that forces the use of an interpreter. There exist native-code Java compilers that generate a single executable file.
[34] There’s another effect in this case: Since the default constructor is the only one defined, and it’s private, it will prevent inheritance of this class. (A subject that will be introduced in Chapter 6.)
[35] However, people often refer to implementation hiding alone as encapsulation.
[36] Actually, an inner class can be private or protected, but that’s a special case. These will be introduced in Chapter 7.
[37] You can also do it by inheriting (Chapter 6) from that class.
[ Previous Chapter ] [ Short TOC ] [ Table of Contents ] [ Index ] [ Next Chapter ]