Sun Certified Java Programmer, ©2004 Gary Lance, Chapter 8, page 1 Sun Certified Java 1.4 Programmer Chapter 8 Notes Gary Lance
Sun Certified Java Programmer, ©2004 Gary Lance, Chapter 8, page 2 public class Person1 { private Name name; // CONSTRUCTOR public Person1(String firstName, String lastName){ name = new Name(); name.firstName = firstName; name.lastName = lastName; } public String toString(){ return name.firstName + " " + name.lastName; } public String getLastFirstName(){ return name.lastName + ", " + name.firstName; } // INNER CLASS Name class Name { private String firstName; String lastName; } Person1 Inner Class = Name The private instance variable of outer class Person1 is a Name object, which is an inner class of Person1. Outer class has access to inner class members. Inner class members are visible to outer class, regardless of access.
Sun Certified Java Programmer, ©2004 Gary Lance, Chapter 8, page 3 Creating Person1 objects From OUTSIDE Person1 Same code as on right, as long as Person1 is visible. Note: The inner class Name and its instance variables can have any access. From INSIDE Person1 public class Test1 { public static void main(String[] args){ Person1 gary = new Person1(“John", “Doe"); Person1 abe = new Person1("Abe", "Lincoln"); Set s = new HashSet(); s.add(gary); s.add(abe); Iterator it = s.iterator(); Person1 p; while(it.hasNext()){ p = (Person1)it.next(); System.out.println(p); }
Sun Certified Java Programmer, ©2004 Gary Lance, Chapter 8, page 4 public class Person2 { private Name name; // INNER CLASS Name class Name { private String firstName; String lastName; public Name(String firstName, String lastName){ this.firstName = firstName; this.lastName = lastName; } public String toString(){ return firstName + " " + lastName; } public String getLastFirstName(){ return lastName + ", " + firstName; } Person2 Inner Class = Name We will create Person2.Name objects from outside the outer class (using Test2.java).
Sun Certified Java Programmer, ©2004 Gary Lance, Chapter 8, page 5 Creating Person2.Name objects From OUTSIDE Person2 public class Test2 { public static void main(String[] args){ // CREATE NAME OBJECTS, // AND PUT THEM INTO A VECTOR Person2 p2 = new Person2(); Person2.Name georgeWashington = p2.new Name("George", "Wash"); Person2.Name marthaStewart = new Person2().new Name("Martha", "Stewart"); Vector nameVec = new Vector(); nameVec.add(georgeWashington); nameVec.add(marthaStewart); int size = nameVec.size(); for(int i = 0; i < size; i++) System.out.println( nameVec.get(i) ); } COMMENTS The object that we create has static class: Person2.Name But to instantiate it, we must first create an instance of the outer class: Person p2 = new Person2(). Using p2, we can get an instance of the inner class name. The syntax is different – notice the way we call the constructor of the inner class. Person2.Name georgeWashington = p2.new Name(“George”, “Wash”); We can also use an anonymous reference to the outer class: Person2.Name marthaStewart = new Person2().new Name("Martha", "Stewart");
Sun Certified Java Programmer, ©2004 Gary Lance, Chapter 8, page 6 See Outer Class From Inner Class In order to get a reference to the outer class from the inner class, you must prepend the outer class name to “.this”.
Sun Certified Java Programmer, ©2004 Gary Lance, Chapter 8, page 7 Inner Class Accessing Outer Class class Outer { private int value = 5; private String name = "Outer class"; // PRINT THE CURRENT // DATE AND TIME void printTheDate(){ System.out.println( new Date().toString()); } class Inner { void printOuterVariables(){ // GET A REFERENCE TO // THE OUTER CLASS Outer outer = Outer.this; System.out.println(outer.value); System.out.println(outer.name); } public class Test3 { public static void main(String[] args){ Outer.Inner oi = new Outer().new Inner(); oi.printOuterVariables(); } It is possible to have the inner class access member variables from the outer class. The inner class must get a reference to outer class. From method printOuterVariables(), you get a reference to the outer class by appending “.this” to the outer class’s name (Outer, in this case): Outer outer = Outer.this With that reference to the outer class, you can access anything in the outer class.
Sun Certified Java Programmer, ©2004 Gary Lance, Chapter 8, page 8 Creating Classes Inside Methods public class Test4 { public static void main(String[] args){ new Outer2().doStuff(); } class Outer2 { private String x = "outer"; void doStuff(){ class MyInner { public void seeOuter() { System.out.println( "Outer x = " + x); } } // end class MyInner MyInner mi = new MyInner(); mi.seeOuter(); } Notice that class MyInner is defined witin the method doStuff(). A reference to that class is created in doStuf() after the class is defined. MyInner mi = new MyInner(); The reference to that class (mi) is used to execute the MyInner method seeOuter(). Method seeOuter() has access to the instance variables of the enclosing class (Outer2).
Sun Certified Java Programmer, ©2004 Gary Lance, Chapter 8, page 9 Anonymous Inner Classes class Popcorn { public void pop(){ System.out.println(“popcorn”) } // CREATE A SUBCLASS OF POPCORN // WITHIN FOOD class Food { Popcorn p = new Popcorn() { public void pop() { System.out.println( “anonymous popcorn”); } }; // Note the semicolon after class def. } An anonymous subclass of Popcorn is created within class Food. main() creates a Food object, and uses it to access the instance of the Popcorn subclass. public class X { public static void main(String[] args){ Popcorn p = new Popcorn(); p.pop(); // This time, no ref. to object new Popcorn().p.pop(); }
Sun Certified Java Programmer, ©2004 Gary Lance, Chapter 8, page 10 Anonymous Inner Classes An anonymous subclass of Cup is created within class Dish. main() creates a Dish object, and uses it to access the instance of the Cup subclass. Cup is a class, in this example. Later, we will change it to an interface. class Cup { protected int percentFilled; protected boolean isEmpty(){ if(percentFilled == 0) return true; return false; } protected int getPercentFilled(){ return percentFilled; } public String toString(){ return "percent filled = " + percentFilled; } public class CupTest1 { public static void main(String[] args){ Dish dish = new Dish(); System.out.println( dish.cup.toString() ); } // CREATE A SUBCLASS OF CUP // WITHIN NAME class Dish { Cup cup = new Cup(){ String color; public String toString(){ return "From subclass: " + super.toString(); } }; // Note the semicolon after class def. }
Sun Certified Java Programmer, ©2004 Gary Lance, Chapter 8, page 11 Anonymous Inner Classes interface Popcorns { public void pop(){ System.out.println(“popcorn”) } // CREATE A SUBCLASS OF POPCORN // WITHIN FOOD class Food { Popcorn p = new Popcorn() { public void pop() { System.out.println( “anonymous popcorn”); } }; // Note the semicolon after class def. } Popcorns is an interface this time. So, the anonymous class created in Foods implements Popcorns. main() creates a Dish object, and uses it to access the instance of the Cup subclass. public class X { public static void main(String[] args){ Food food = new Food(); System.out.println( food ); }
Sun Certified Java Programmer, ©2004 Gary Lance, Chapter 8, page 12 Anonymous Inner Classes An anonymous subclass of Cups is created within class Dish. main() creates a Dish object, and uses it to access the instance of the Cup subclass. Notice that Cups is an interface, so what does that say about the members of Cups? What modifiers are implicit? interface Cups { int percentFilled = 25; boolean isEmpty(); int getPercentFilled(); public String toString(); } public class CupTest2 { public static void main(String[] args){ Dishes dish = new Dishes(); System.out.println( dish.cup.toString() ); } // WHAT IS WRONG WITH THIS CODE? class Dishes { Cups cup = new Cups(){ boolean isEmpty(){ if(percentFilled == 0) return true; return false; } int getPercentFilled(){ return percentFilled; } String toString(){ return "percent filled = " + percentFilled; } }; // Note the semicolon after the class def. }
Sun Certified Java Programmer, ©2004 Gary Lance, Chapter 8, page 13 End of Chapter 8