200 likes | 326 Views
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
E N D
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 file1.java file1.class Typically a jar file contains class files of a package. Compile jar jar file file1.class file2.class file3.class file2.java file2.class fileN.java fileN.class
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
Resolving class files defined in packages • 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
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("" + 3.14159); monitor.expect(new String[] { "Available from now on!", "100", "100", "3.14159" }); } } ///:~
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(); } } ///:~
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" }); } } ///:~ • public class Cookie { • public Cookie() { • System.out.println("Cookie constructor"); • } • protected void bite() { • System.out.println("bite"); • } • }
Interface and implementation • 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
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(); } } ///:~ • //: 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() {} • }
First programming assignment • 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 • http://ce.sharif.edu/~daraii • You need to sumbit following items by Aban 6th (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: • daraii@ce.sharif.edu • Quality of code and documentation is very important.