1. Classes
  2. Objects
  3. Nested Classes

1. Classes

Questions

  1. Consider the following class:
    public class IdentifyMyParts {
        public static int x = 7; 
        public int y = 3; 
    }
    
    1. What are the class variables? x
    2. What are the instance variables? y
    3. What is the output from the following code:
      IdentifyMyParts a = new IdentifyMyParts();
      IdentifyMyParts b = new IdentifyMyParts();
      a.y = 5;
      b.y = 6;
      a.x = 1;
      b.x = 2;
      System.out.println("a.y = " + a.y);
      System.out.println("b.y = " + b.y);
      System.out.println("a.x = " + a.x);
      System.out.println("b.x = " + b.x);
      System.out.println("IdentifyMyParts.x = " + IdentifyMyParts.x);
      
      a.y = 5
      b.y = 6
      a.x = 2
      b.x = 2
      IdentifyMyParts.x = 2
      

Exercises

  1. Write a class whose instances represent a single playing card from a deck of cards. Playing cards have two distinguishing properties: rank and suit.

    Hint:You can use the assert statement to check your assignments. You write:

    assert (boolean expression to test); 
    

    If the boolean expression is false, you will get an error message. For example,

    assert toString(ACE) == "Ace";
    

    should return true, so there will be no error message.

    If you use the assert statement, you must run your program with the ea (-enableassertions) flag:

    java -ea YourProgram.class
    

  2. Write a class whose instances represent a full deck of cards. You should also keep this solution.
  3. Write a small program to test your deck and card classes. The program can be as simple as creating a deck of cards and displaying its cards.

2. Classes And Objects – Objects

Questions

  1. What’s wrong with the following program?
    public class SomethingIsWrong {
        public static void main(String[] args) {
            Rectangle myRect;
            myRect.width = 40;
            myRect.height = 50;
            System.out.println("myRect's area is " + myRect.area());
        }
    }
    

    An instance of Rectangle is not created with new and the object reference is not assigned to myRect so the compiler will generate an error. If myRect was initialised to null the program would compile but generate a NullPointerException at runtime.

  2. The following code creates one array and one string object. How many references to those objects exist after the code executes? 1 reference to the array and one to the string. students contains one reference to the array. The reference to the String object is copied into students[0]. The value of studentName is set to null but the array still contains the reference to the String object.  Is either object eligible for garbage collection? No. At the end of the given scope the objects have not explicitly gone out of scope so there are still references to them.
    ...
    String[] students = new String[10];
    String studentName = "Peter Parker";
    students[0] = studentName;
    studentName = null;
    ...
  3. How does a program destroy an object that it creates? It can’t. It can only make the object drop from scope or set all references to null so the garbage collector destroys them.

Exercises

  1. Fix the program called SomethingIsWrong shown in Question 1.
    public class SomethingIsWrong {
        public static void main(String[] args) {
            Rectangle myRect = new Rectange();
            myRect.width = 40;
            myRect.height = 50;
            System.out.println("myRect's area is " + myRect.area());
        }
    }
  2. Given the following class, called NumberHolder, write some code that creates an instance of the class, initializes its two member variables, and then displays the value of each member variable.
    public class NumberHolder {
        public int anInt;
        public float aFloat;
    }

3. Nested Classes

Questions

  1. The program Problem.java doesn’t compile.
    public class Problem {
        String s;
        static class Inner {
            void testMethod() {
               s = "Set from Inner";
            }
        }
    }

    What do you need to do to make it compile? Make the Inner class non-static. s is not being shadowed in Inner so we don’t need to set it with Problem.this.s. Why? The static Inner class cannot access the instance variable s. Specifically the compiler says “non-static variable s cannot be referenced from a static context”.

  2. Use the Java API documentation for the Box class (in the javax.swing package) to help you answer the following questions.

    public class Box
    extends JComponent
    implements Accessible

    A lightweight container that uses a BoxLayout object as its layout manager. Box provides several class methods that are useful for containers using BoxLayout — even non-Box containers.The Box class can create several kinds of invisible components that affect layout: glue, struts, and rigid areas. If all the components your Box contains have a fixed size, you might want to use a glue component (returned by createGlue) to control the components’ positions. If you need a fixed amount of space between two components, try using a strut (createHorizontalStrut or createVerticalStrut). If you need an invisible component that always takes up the same amount of space, get it by invoking createRigidArea.

    If you are implementing a BoxLayout you can find further information and examples in How to Use BoxLayout, a section in The Java Tutorial.

     

    1. What static nested class does Box define?
      /* An implementation of a lightweight component that participates
      in layout but has no view. */
      public static class Box.Filler
      extends JComponent
      implements Accessible
    2. What inner class does Box define?
      /* Implements accessibility support for the Box class. */
      protected class Box.AccessibleBox
      extends Container.AccessibleAWTContainer
    3. What is the superclass of Box‘s inner class?
      java.awt.Container.AccessibleAWTContainer
      Inner class of Container used to provide default support for accessibility. This class is not meant to be used directly by application developers but is instead meant only to be subclassed by container developers.The class used to obtain the accessible role for this object, as well as implementing many of the methods in the AccessibleContainer interface.
    4. Which of Box‘s nested classes can you use from any class?
      public static class Box.Filler
    5. How do you create an instance of Box‘s Filler class?

      Box.Filler = new Box.Filler()

Exercises

  1. Get the file Class1.java. Compile and run Class1. What is the output?
    InnerClass1: getString invoked.
    InnerClass1: getAnotherString invoked.
  2. The following exercises involve modifying the class DataStructure.java, which the section Inner Class Example discusses.
    1. Define a method named print(DataStructureIterator iterator). Invoke this method with an instance of the class EvenIterator so that it performs the same function as the method printEven.
    /*
     *  1. Define a method print(DataStructureIterator iterator)
     *  2. Performs the same function as the method printEven.
     *  3. Invoked with EvenIterator instance, e.g.
              
           DataStructure.EvenIterator it = ds.new EvenIterator();
           ds.print(it);
    */
    public void print(DataStructureIterator iterator) {
      while (iterator.hasNext()) {
        System.out.print(iterator.next() + " ");
      }
      System.out.println();
    }
    1. Invoke the method print(DataStructureIterator iterator) from a new method called printOdd(), so that it prints elements that have an odd index value. Use an anonymous class as the method’s argument instead of an instance of the interface DataStructureIterator. Question implies you call print from main but you can’t as you can’t access arrayOfInts from there ( a static context) so you have to call print from a new instance method.
    /* 
    * 1. Add a method that prints elements that have an odd
         index value, e.g. ds.printOdd();
    * 2. Invoke the method print(DataStructureIterator iterator) 
    * 2. Use an anonymous class as the method's argument instead
         of an instance of the interface DataStructureIterator.
    */
    public void printOdd() {
      this.print(new DataStructureIterator () {
        // Start stepping through the array from the beginning
        int nextIndex = 1;
    
        public boolean hasNext() {             
          // Check if the current element is the last in the array
          return (nextIndex <= SIZE - 1);
        }        
    
        public Integer next() {             
         // Record a value of an even index of the array
         Integer retValue = Integer.valueOf(arrayOfInts[nextIndex]);
    
         // Get the next even element
         nextIndex += 2;
         return retValue;
         }
        });
    }
    

    Ha, so I got this WRONG. The Question DOES want you to call print from main. You have to SOLVE the issue with accessing arrayOfInts from a static context.

    The solution is to access arrayOfInts from a non-static context by adding an instance method to the DataStructure class to return the index, e.g.

    public int getElement(int index) {
            return arrayOfInts[index];
    }
    

    The other thing to remember is that the anonymous class is defined as the argument to the ds.print() method. The {} of the anonymous class statement doesn’t change the scope of the ds object. You can still reference the ds object in the class body to call the getElement method in the same way you could within the () of the print method.

    The Question would have you also create a method to access SIZE because you cannot access these private members from an anonymous class defined outside DataStructure. This is true but a direct reference to SIZE DOES work in this example because, unlike arrayOfInts, it’s a static field and so can be accessed from a static context, AND everything here IS defined WITHIN DataStructure.

    ds.print(new DataStructureIterator () {
      // Start stepping through the array from the beginning
      int nextIndex = 1;
    
      public boolean hasNext() {             
        // Check if the current element is the last in the array
        return (nextIndex <= SIZE - 1); // static field in scope
      }        
    
      public Integer next() {             
        // Record a value of an even index of the array
        // ds object in scope within class declaration
        Integer retValue = Integer.valueOf(
          ds.getElement(nextIndex));
        
        // Get the next even element
        nextIndex += 2;
        return retValue;
      }
    });
  1. Define a method named print(java.util.function.Function<Integer, Boolean> iterator) that performs the same function asprint(DataStructureIterator iterator). Invoke this method with a lambda expression to print elements that have an even index value. Invoke this method again with a lambda expression to print elements that have an odd index value.
/*
 * 1. Define a method named 
 *    print(java.util.function.Function<Integer, Boolean> iterator) 
 *    that performs the same function as 
 *    print(DataStructureIterator iterator). 
 *    java.util.Function<T,R> contains 1 abstract method,
 *    R apply(T t), that represents a function that accepts one 
 *    argument (integer) and produces a result (boolean).
 * 2. Invoke with a lambda expression to print elements that have
 *    an even index value. The lambda expression should implement 
 *    Boolean Function.apply(Integer t), e.g. 
 *    ds.print( i -> ( i % 2 == 0) );                  
 * 3. Invoke with a lambda expression to print elements that have
 *    an odd index value, e.g. 
      ds.print( i -> ( i % 2 != 0) ); 
*/
public void print(
  java.util.function.Function<Integer, Boolean> iterator) {
    for (int i=0; i<SIZE; i++) {
      if (iterator.apply(i)) {
        System.out.print(arrayOfInts[i] + " ");
      }
    }
    System.out.println();
}
  1. Define two methods so that the following two statements print elements that have an even index value and elements that have an odd index value:
    DataStructure ds = new DataStructure()
    // ...
    ds.print(DataStructure::isEvenIndex);
    ds.print(DataStructure::isOddIndex);
    public static Boolean isEvenIndex(Integer i) {
        return ( i % 2 == 0);
    }
    
    public static Boolean isOddIndex(Integer i) {
        return ( i % 2 != 0);
    }
Advertisements