Chapter 5: Hiding implementation ● Two viewpoints regarding classes: – Implementor of a class: knows everything about class – User of a class: Only wants to know what services a class provides ● Information hiding is the key – There are public, protected, package access and private access controls ● A related topic is packaging: – Putting all classes in a library in a package context
Package: the library unit ● We use import to access classes in a package: import java.util.*; <- can use all classes in java.util package import java.util.ArrayList <- can only use ArraList in the package ● Packaging is a way to resolve naming conflicts between different library developers: – com.ibm.util.Stack and org.apache.util.Stack ● Upto now we didn't package our classes. But for large programs we should think of packaging to prevent name clashing
.class and jar files Typically a jar file contains class files of a package. file1.java file2.java fileN.jav a Com pile file1.clas s file2.clas s fileN.clas s jar file1.class file2.class file3.class jar file
Creating unique package names For a package name normally internet domain names with some additional keywords is used: apache.org.util ibm.com.util sun.com.util
● For example when we have: import foo.bar.baz ● Java interpreater first looks at CLASSPATH environment variable – For example suppose it is defined as: CLASSPATH=.;c:\advancedprogramming;c:\java – And suppose current directory is c:\ ● Then java interpreter tries to find a baz.class file in following directories, in order: – c:\foo\bar – c:\advancedprogramming\foo\bar – c:\java\foo\bar Resolving class files defined in packages
Defining a class inside a package We use package statement as the first line of our java programs: //: com:bruceeckel:simple:Vector.java // Creating a package. package com.bruceeckel.simple; public class Vector { public Vector() { System.out.println("com.bruceeckel.simple.Vector"); } } ///:~ //: com:bruceeckel:simple:List.java // Creating a package. package com.bruceeckel.simple; public class List { public List() { System.out.println("com.bruceeckel.simple.List"); } } ///:~
Using classes of a package ● We store previous Vector and List classes in com/bruceeckel/simple somewhere that is defined in CLASSPATH ● Then we can use them in our programs: //: c05:LibTest.java // Uses the library. import com.bruceeckel.simpletest.*; import com.bruceeckel.simple.*; public class LibTest { static Test monitor = new Test(); public static void main(String[] args) { Vector v = new Vector(); List l = new List(); monitor.expect(new String[] { "com.bruceeckel.simple.Vector", "com.bruceeckel.simple.List" }); } } ///:~
Collisions ● What happens if two libraries are imported via ‘*’ and they include the same names? For example, suppose a program does this: import com.bruceeckel.simple.*; import java.util.*; ● Since java.util.* also contains a Vector class, this causes a potential collision: Vector v = new Vector(); ● To resolve this problem, we need to be explicit: java.util.Vecor v = new java.util.Vector();
A custom tool library ● Typically when we make programs, we define an use some utility classes ● It is a good idea to package such utility classes //: com:bruceeckel:tools:P.java // The P.rint & P.rintln shorthand. package com.bruceeckel.tools; public class P { public static void rint(String s) { System.out.print(s); } public static void rintln(String s) { System.out.println(s); } } ///:~
And use the library classes //: c05:ToolTest.java // Uses the tools library. import com.bruceeckel.tools.*; import com.bruceeckel.simpletest.*; public class ToolTest { static Test monitor = new Test(); 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("" ); monitor.expect(new String[] { "Available from now on!", "100", " " }); } } ///:~
Java access specifiers ● Access specifiers indicates which mebmers of a class can be used by other classes ● We use of public, protected and private for access specifications ● Packeg access is used when there is no access specifier ● Package access means that all classes in the same package can access the member ● But for all other classes the member is private
Public access Member is available to every other classes //: c05:dessert:Cookie.java // Creates a library. package c05.dessert; public class Cookie { public Cookie() { System.out.println("Cookie constructor"); } void bite() { System.out.println("bite"); } } ///:~
Public access //: c05:Dinner.java // Uses the library. import com.bruceeckel.simpletest.*; import c05.dessert.*; public class Dinner { static Test monitor = new Test(); public Dinner() { System.out.println("Dinner constructor"); } public static void main(String[] args) { Cookie x = new Cookie(); //! x.bite(); // Can't access monitor.expect(new String[] { "Cookie constructor" }); } } ///:~
Private access No class can access the member except the class that contains it //: c05:IceCream.java // Demonstrates "private" keyword. class Sundae { private Sundae() {} static Sundae makeASundae() { return new Sundae(); } public class IceCream { public static void main(String[] args) { //! Sundae x = new Sundae(); Sundae x = Sundae.makeASundae(); } } ///:~
public class Cookie { public Cookie() { System.out.println("Cookie constructor"); } protected void bite() { System.out.println("bite"); } Protected access: inheritance access //: c05:ChocolateChip.java // Can't use package-access member from another package. import com.bruceeckel.simpletest.*; import c05.dessert.*; public class ChocolateChip extends Cookie { private static Test monitor = new Test(); public ChocolateChip() { System.out.println("ChocolateChip constructor"); } public static void main(String[] args) { ChocolateChip x = new ChocolateChip(); x.bite(); monitor.expect(new String[] { "Cookie constructor", "ChocolateChip constructor" }); } } ///:~
● With access control we hide some implementation details ● Implementation hiding and wrapping data and methods within classes is called encapsulation ● Access control makes boundaries for two reasons: – Control what client can and can't use – Separate interface from implementation: programmer can change anything that is not public without breaking the client code ● Public members are those that describes interface of a class Interface and implementation
//: 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 access 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(); } } ///:~
Design a program as follows: Program consists of four classes: Student, Teacher, Course and University Student class has “id, name” data members that are private. It has following public (accessor) methods: setId(String id), String getId(), setName(String name), String getName() similarly teacher class has “id, name” private data member with corresponding accessor methods Course class has “id, name” private data members with associated accessor methods. It has an array of lecture times. Also it has a private data member hodling an instance of Teacher class. And it has an array of Student objects which has this course. First programming assignment
University is the main class of this program (i.e. it has main method) In the main method of University you create and initialize at least 10 courses. Then you create an agenda for all teachers and students, showing which classes they have to attend each week. You don't need to make a sorted agenda but if you like you can do this optionally Use simpletest class to test output of your program First programming assignment
You need to sumbit following items by Aban 6 th (Wendnesday): 1- java source files 2- javadoc files 3- a readme file explaining how to compile and execute the program zip all the files in university.zip and send it to the following address: Quality of code and documentation is very important. First programming assignment