Chapter 3: Multiple Relational Operators

Consider the expression
if (0 < amount < 1000) . . . // Error
This looks just like the mathematical notation for “amount is between 0 and 1000”. But in Java, it is a syntax error.
Let us dissect the condition. The first half, 0 < amount, is a test with outcome true or false. The outcome of that test (true or false) is then compared against 1000. This seems to make no sense. Is true larger than 1000 or not? Can one compare truth values and numbers? In Java, you cannot. The Java compiler rejects this statement.
Instead, use && to combine two separate tests: if (0 < amount && amount < 1000) . . .

Another common error, along the same lines, is to write if (ch == ‘S’ || ‘M’) . . . // Error
to test whether ch is ‘S’ or ‘M’. Again, the Java compiler flags this construct as an error. You cannot apply the || operator to characters. You need to write two Boolean expressions and join them with the || operator:
if (ch == ‘S’ || ch == ‘M’) . . .

Chapter 3: Conditions with Side Effects

In Java, it is legal to nest assignments inside test conditions:
if ((d = b * b – 4 * a * c) >= 0) r = Math.sqrt(d);
It is legal to use the decrement operator inside other expressions:
if (n–– > 0) . . .
These are bad programming practices because they mix a test with another activity. The other activity (setting the variable d, decrementing n) is called a side effect of the test.
Conditions with side effects can occasionally be helpful to simplify loops; for if statements they should always be avoided.

Occasionally all the work of a loop is already done in the loop header. Suppose you ignore good programming practices and write an investment doubling loop as follows:
for (years = 1;
(balance = balance + balance * rate / 100) < targetBalance; years++);
System.out.println(years);
The body of the for loop is completely empty, containing just one empty statement terminated by a semicolon.
If you do run into a loop without a body, it is important that you make sure the semicolon is not forgotten. If the semicolon is accidentally omitted, then the next line becomes part of the loop statement!
for (years = 1;
(balance = balance + balance * rate / 100) < targetBalance; years++)
System.out.println(years);
You can avoid this error by using an empty block { } instead of an empty statement.

Chapter 3: Confusing && and || Conditions

Confusing && and || Conditions
It is a surprisingly common error to confuse “and” and “or” conditions. A value lies between 0 and 100 if it is at least 0 and at most 100. It lies outside that range if it is less than 0 or greater than 100. There is no golden rule; you just have to think carefully.
Often the “and” or “or” is clearly stated, and then it isn’t too hard to implement it. Sometimes, though, the wording isn’t as explicit. It is quite common that the individual conditions are nicely set apart in a bulleted list, but with little indication of how they should be combined. The instructions for the 1992 tax return say that you can claim single filing status if any one of the following is true:
• You were never married.
• You were legally separated or divorced on December 31, 1992.
• You were widowed before January 1, 1992, and did not remarry in 1992.
Because the test passes if any one of the conditions is true, you must combine the conditions with or. Elsewhere, the same instructions state that you may use the more advantageous status of married filing jointly if all five of the following conditions are true:
• Your spouse died in 1990 or 1991 and you did not remarry in 1992.
• You have a child whom you can claim as dependent.
• That child lived in your home for all of 1992.
• You paid over half the cost of keeping up your home for this child.
• You filed (or could have filed) a joint return with your spouse the year he or she died.
Because all of the conditions must be true for the test to pass, you must combine them with an and.

Chapter 5: Software Development Activities

October 11th, 2013

Software Development Activities

Four basic development activities:

  • establishing the requirements
  • creating a design
  • implementing the design
  • testing

This sequence would be ideal but it almost never completely linear in reality.
They overlap and interact.

Software requirements specify what a program must accomplish: a document called a functional specification.

The client will often provide an initial set of requirements. However, these initial requirements are often incomplete, ambiguous, and perhaps even contradictory.

The software developer must work with the client to refine the requirements.

A software design indicates how a program will accomplish its requirements.

The design specifies the classes and objects needed in a program and defines how they interact. It also specifies the relationships among the classes.

During software design, alternatives need to be considered and explored. Often, the first attempt at a design is not the best solution.

Implementation is the process of writing the source code that will
 solve the problem.

Too many programmers focus on implementation exclusively when actually it should be the least creative of all development activities. The important decisions should be made when establishing the requirements and creating the design.

Testing is the act of ensuring that a program will solve the intended problem given all of the constraints under which it must perform.

Identifying classes and objects

A fundamental part of object-oriented software design is determining the classes that will contribute to the program. We have to carefully consider how we want to represent the various elements that make up the overall solution. These classes determine the objects that we will manage in the system.

When designing classes, objects are generally nouns.

The nouns in a problem description may indicate some of the classes and objects needed in a program.

A class represents a group of objects with similar behavior. A plural noun is an indication that your design might not be good.

Classes that represent objects should generally be given names that are singular nouns.

A class represents a single item from which we are free to create as many instances as we choose.

Another key decision is whether to represent something as an object or as a primitive attribute of another object.

We want to strike a good balance between classes that are too general and those that are too specific.

There might be additional classes to support the work necessary to get the job done.

Keep in mind that may be an old class that’s similar enough to serve as the basis for our new class.

The existing class may be part of the Java standard class library, part of a solution to a problem we’ve solved previously, or part of a library that can be bought from a third party, “Software Re-usability”.

Assigning responsibilities

Part of the process of identifying the classes needed in a program is the process of assigning responsibilities to each class. Each class represents an object with certain behaviors that are defined by the methods of the class. Any activity that the program must accomplish must be represented somewhere in the behaviors of the classes. That is, each class is responsible for carrying out certain activities, and those responsibilities must be assigned as part of designing a program.

Generally use verbs for the names of behaviors and the methods that accomplish them.

Sometimes it is challenging to determine which is the best class to carry out a particular responsibility. You could benefit from defining another class to shoulder the responsibility.

It’s not necessary in the early stages of a design to identify all the methods that a class will contain. It is often sufficient to assign primary responsibilities and consider how those responsibilities translate to particular methods.

Class and object relationships

The classes in a software system have various types of relationships to each other. Three of the more common relationships are dependency, aggregation, and inheritance.

Dependency relationships: a class “uses” another.
Class A uses class B, then one or more methods of class A invoke one or more methods of class B. If an invoked method is static, then A merely references B by name. If the invoked method is not static, then A must have access to a specific instance of class B in order to invoke the method. That is, A must have a reference to an object of class B.

dependency

UML notation distinguishes between object diagrams and class diagrams. In an object diagram the class names are underlined; in a class diagram the class names are not underlined. In a class diagram, you denote dependency by a dashed line with a shaped open arrow tip that points to the dependent class. Figure 1 shows a class diagram indicating that the CashRegister class depends on the Coin class.

Note that the Coin class does not depend on the CashRegister class. Coins have no idea that they are being collected in cash registers, and they can carry out their work without ever calling any method in the CashRegister class.

coupling

Aggregation: the objects of one class contain objects of another, creating a “has-a” relationship.
When one class instantiates the objects of another, it is the basis of an aggregation relationship. The access can also be accomplished by passing one object to another as a method parameter.
The less dependent our classes are on each other, the less impact changes and errors will have on the system.

Inheritance: creates an “is-a” relationship between classes.

Chapter 5: Interfaces – Zero ADT

Exception Handling
An exception is an object created to handle unusual or specific errors.
An exception is thrown by a program or the run-time environment.
An exception can be caught and handled appropriately when needed.
An error is similar to an exception except that an error runs its course.
Java has a predefined set of exceptions and errors that may occur during the execution of a program.

zeromile

//********************************************************************
//  Zero.java       Author: Lewis/Loftus/Cocking
//
//  Demonstrates an uncaught exception.
//********************************************************************

public class Zero
{
   //-----------------------------------------------------------------
   //  Deliberately divides by zero to produce an exception.
   //-----------------------------------------------------------------
   public static void main (String[] args)
   {
      int numerator = 10;
      int denominator = 0;

      System.out.println (numerator / denominator);

      System.out.println ("This text will not be printed.");
   }
}

Run Zero.java. Does it compile? Does it run?
Answer this question in edmodo.com

/**
 * This class demonstrates the use of exception classes
 * 
 * @Lewis/Loftus/Cocking/Elia
 * @10/21/14
 */
public class ExceptionsExample
{
    
    //********************************************************************
//  Zero.java       Author: Lewis/Loftus/Cocking
//
//  Demonstrates an uncaught exception and how to handle it
//********************************************************************

   //-----------------------------------------------------------------
   //  Deliberately divides by zero to produce an exception during runtime.
   //-----------------------------------------------------------------
   public static void main (String[] args)
   {
      int numerator = 10;
      int denominator = 0;

      //System.out.println (numerator / denominator);

      //.out.println ("This text will not be printed.");
      
      // handling the exception with try and catch
      
      
      try
         {
            System.out.println (numerator / denominator);
         }
         catch (ArithmeticException e)
         {
            System.out.println ("Improper denominator input validation");
         }
         catch (NumberFormatException exception)
         {
            System.out.println ("Improper number format");
         }
      
   }
}

/**
 * output: Improper denominator input validation
 */



Interfaces

A Java interface is a collection of constants and abstract methods.
An interface cannot be instantiated.
A class implements an interface by providing method implementations for each of the abstract methods defined in the interface.
Methods in interfaces have public visibility by default.

In addition to, or instead of, abstract methods, an interface can also contain constants, defined using the final modifier. When a class implements an inter- face, it gains access to all the constants defined in it.

An interface is represented similarly to a class node except that the designation

 <> 

is inserted above the interface name. A dotted arrow with a closed arrowhead is drawn from the class to the interface that it implements.

Screen Shot 2014-10-21 at 1.53.23 PM

//********************************************************************
//  Complexity.java       Author: Lewis/Loftus/Cocking
//
//  Represents the interface for an object that can be assigned an
//  explicit complexity.
//********************************************************************

public interface Complexity
{
   public void setComplexity (int complexity);
   public int getComplexity();
}

 

//********************************************************************
//  Question.java       Author: Lewis/Loftus/Cocking
//
//  Represents a question (and its answer).
//********************************************************************

public class Question implements Complexity
{
   private String question, answer;
   private int complexityLevel;

   //-----------------------------------------------------------------
   //  Sets up the question with a default complexity.
   //-----------------------------------------------------------------
   public Question (String query, String result)
   {
      question = query;
      answer = result;
      complexityLevel = 1;
   }

   //-----------------------------------------------------------------
   //  Sets the complexity level for this question.
   //-----------------------------------------------------------------
   public void setComplexity (int level)
   {
      complexityLevel = level;
   }

   //-----------------------------------------------------------------
   //  Returns the complexity level for this question.
   //-----------------------------------------------------------------
   public int getComplexity()
   {
      return complexityLevel;
   }

   //-----------------------------------------------------------------
   //  Returns the question.
   //-----------------------------------------------------------------
   public String getQuestion()
   {
      return question;
   }
   //-----------------------------------------------------------------
   //  Returns the answer to this question.
   //-----------------------------------------------------------------
   public String getAnswer()
   {
      return answer;
   }

   //-----------------------------------------------------------------
   //  Returns true if the candidate answer matches the answer.
   //-----------------------------------------------------------------
   public boolean answerCorrect (String candidateAnswer)
   {
      return answer.equals(candidateAnswer);
   }

   //-----------------------------------------------------------------
   //  Returns this question (and its answer) as a string.
   //-----------------------------------------------------------------
   public String toString()
   {
      return question + "\n" + answer;
   }
}

Replace the Keyboard Class with Scanner

//********************************************************************
//  MiniQuiz.java       Author: Lewis/Loftus/Cocking
//
//  Demonstrates the use of a class that implements an interface.
//********************************************************************



public class MiniQuiz
{
   //-----------------------------------------------------------------
   //  Presents a short quiz.
   //-----------------------------------------------------------------
   public static void main (String[] args)
   {
      Question q1, q2;
      String possible;

      q1 = new Question ("What is the capital of Jamaica?",
                         "Kingston");
      q1.setComplexity (4);

      q2 = new Question ("Which is worse, ignorance or apathy?",
                         "I don't know and I don't care");
      q2.setComplexity (10);

      System.out.print (q1.getQuestion());
      System.out.println (" (Level: " + q1.getComplexity() + ")");
      possible = Keyboard.readString();
      if (q1.answerCorrect(possible))
         System.out.println ("Correct");
      else
         System.out.println ("No, the answer is " + q1.getAnswer());

      System.out.println();
      System.out.print (q2.getQuestion());
      System.out.println (" (Level: " + q2.getComplexity() + ")");
      possible = Keyboard.readString();
      if (q2.answerCorrect(possible))
         System.out.println ("Correct");
      else
         System.out.println ("No, the answer is " + q2.getAnswer());
   }
}


 

Classwork:
1. What is the difference between an error and an exception?
2. What is the difference between a class and an interface?
3. Define a Java interface called Nameable. Classes that implement this interface must provide a setName method that requires a single String parameter and returns nothing, and a getName method that has no parameters and returns a String.
4. True or False? Explain.
a. A Java interface can include only abstract methods, nothing else.
b. An abstract method is a method that does not have an implementation.
c. All of the methods included in a Java interface definition must be
abstract.
d. A class that implements an interface can define only those methods
that are included in the interface.
e. Multiple classes can implement the same interface.
f. A class can implement more than one interface.
g. All classes that implement an interface must provide the exact
same definitions of the methods that are included in the interface.

Read up to pages 263 through 269 from Chapter 5.

 

 

Chapter 5: Interface Lockable – Comparable

January 3rd, 2018

Classwork:

lock

Programming Project 5.6:
Design a Java interface called Lockable that includes the following methods: setKey, lock, unlock, and locked. The setKey, lock, and unlock methods take an integer parameter that represents the key. The setKey method establishes the key. The lock and unlock methods lock and unlock the object, but only if the key passed in is correct. The locked method returns a boolean that indicates whether or not the object is locked. A Lockable object represents an object whose regular methods are protected: if the object is locked, the methods cannot be invoked; if it is unlocked, they can be invoked. Redesign and implement a version of the Coin class from Chapter 4 so that it is Lockable.
Include a driver.

Homework:
Programming Project 5.7:
Redesign and implement a version of the Account class from Chapter 4 so that it is Lockable as defined by Programming Project 5.6.
Include a driver.

Chapter 5: Inner Classes – Nested Classes

January 12th, 2017

Classwork:

Inner Classes – Nested Classes
A class can be declared inside another class. Just as a loop written inside another loop is called a nested loop, a class written inside another class is called a nested class. The nested class is considered a member of the enclosing class, just like a variable or method.

  • Just like any other class, a nested class produces a separate bytecode file.
  • The name of the bytecode file is the name of the enclosing class followed by the $ character followed by the name of the nested class.
  • Like any other bytecode file, it has an extension of .class. A class called Nested that is declared inside a class called Enclosing will result in a compiled bytecode file called Enclosing$Nested.class.
  • Because it is a member of the enclosing class, a nested class has access to the enclosing class’s instance variables and methods, even if they are declared with private visibility.
  • The enclosing class can directly access data in the nested class only if the data is declared public.
  • Data should always be kept private to follow the rules of encapsulation. However, the exception applies to nested class so the enclosing class can get to the data.
  • Such a privileged relationship should be reserved for appropriate situations.
  • The static modifier can be applied to a class, but only if the class is nested inside another.
  • Like static methods, a static nested class cannot reference instance variables or methods defined in its enclosing class.
  • //********************************************************************
    //  TestInner.java       Author: Lewis/Loftus
    //
    //  Demonstrates the access capabilities of inner classes.
    //********************************************************************
       public class TestInner
       {
          //-----------------------------------------------------------------
          //  Creates and manipulates an Outer object.
          //-----------------------------------------------------------------
          public static void main (String[] args)
          {
             Outer out = new Outer();
             System.out.println (out);
             System.out.println();
             out.changeMessages();
             System.out.println (out);
          } 
       }
    

    Output
    Copy these files to your project.
    Show and explain the output on edmodo.com

    
    //********************************************************************
    //  Outer.java       Author: Lewis/Loftus
    //
    //  Represents a class that encapsulates an inner class.
    //********************************************************************
    public class Outer
    {
       private int num;
       private Inner in1, in2;
       //-----------------------------------------------------------------
       //  Sets up this object, initializing one int and two objects
       //  created from the inner class.
       //-----------------------------------------------------------------
       public Outer()
       {
         num = 9876;
         in1 = new Inner ("Half of the problem is 90% mental.");
         in2 = new Inner ("Another deadline. Another miracle.");
       }
       //-----------------------------------------------------------------
       //  Changes the messages in the Inner objects (directly).
       //-----------------------------------------------------------------
       public void changeMessages()
       {
          in1.message = "Life is uncertain. Eat dessert first.";
          in2.message = "One seventh of your life is spent on Mondays.";
       }
       //*****************************************************************
       //  Returns this object                
       //*****************************************************************
    
       public String toString()
       {
          return in1 + "\n" + in2;
       }
    
          //*****************************************************************
          //  Represents an inner class.
          //*****************************************************************
          private class Inner
          {
             public String message;
             //--------------------------------------------------------------
             //  Sets up this Inner object with the specified string.
             //--------------------------------------------------------------
             public Inner (String str)
             {
                message = str;
             }
             //--------------------------------------------------------------
             //  Returns this object as a string, including a value from
             //  the outer class.
             //--------------------------------------------------------------
             public String toString()
             {
                num++;
                return message + "\nOuter num = " + num;
             }
           }
       }
        
    
  • Each Inner object contains a public String called message.
  • Because it is public, the changeMessages of the Outer class can reach in and modify the contents.
  • As the authors’ve stressed many times, giving data public access should be avoided in general. However, in this case, since Inner is a private class, no class other than Outer can refer to it. Therefore no class other than Outer can directly access the public data inside it either.
    Using inner classes with public data should be done only in situations in which the outer class is completely dependent on the inner class for its existence.

    If designed properly, inner classes preserve encapsulation while simplifying the implementation of related classes

    Preparing for chapter 5 test on Wednesday and getting ready for Midterm.

    Homework:
    Study for chapter 5 test.

    Chapter 5: Goodies Co. Examples

    The Goodies Company Project

    vendingmachines

    From Wikipedia:
    In computer programming, an application programming interface (API) is a set of routines, protocols, and tools for building software applications. An API expresses a software component in terms of its operations, inputs, outputs, and underlying types. An API defines functionalities that are independent of their respective implementations, which allows definitions and implementations to vary without compromising the interface. A good API makes it easier to develop a program by providing all the building blocks. A programmer then puts the blocks together.

    Cay Horstmann:
    A class should represent a single concept. The public methods
    and constants that the public interface exposes should be cohesive.
    That is, all interface features should be closely related to the single
    concept that the class represents.
    If you find that the public interface of a class refers to multiple concepts,
    then that is a good sign that it may be time to use separate classes instead.

    NO CODE – It is no programming language related!

    Examples of public interfaces for the Goodies Company Application:
    Example 1:

    Class BD_VendingMachine:
    public BD_VendingMachine: initializes allocated change and sets profit to 0
    void addChange(value) adds allocated change
    void addProduct(BD_Product) adds a product to the machine
    double getBalance() returns profit
    double getChange() returns allocated change remaining
    void purchase(BD_Product, double money) buys product inputted and determines change to return, subtracting from allocated change accordingly

    Class BD_Product:
    public BD_Product(string name, double price)initializes new product and price

    Example 2:
    Classes:

    Class 1 – snack
    name, price, stock
    can set the name price and amount of the item
    can change the price of the item
    will decrement the amount when the item is purchased

    Class 2 – machine
    sales, list of snacks
    holds several objects of the class snack
    method for purchasing an item which will decrement the snack, increase sales, and output change
    method for restocking the amount of a snack
    can remove and add snacks
    can return the total sales of a machine

    Class 3/ Main Class –
    runs several of the machines
    will buy snacks from various machines
    will restock the machines
    will check the total sales and amount of snacks in each machine

    Example 3:
    Vending Machine Project Outline

    VendingMachine —> Class
    – Array of Products
    – Amount initially put in for change
    – Total
    – Name / Location
    addProduct() – allows you to add a product object to the inventory of the machine
    addChange() – allows you to add change to the machine
    getProfit() – subtracts the added change from the total to display the profit of the machine
    buy() – takes in a Product object, and a money value (possibly in coin objets) and allows you to “buy” the product

    Product —> Class
    – name
    – price
    getPrice()
    getName()
    toString()

    Coin —> Class
    – name
    – value
    getValue()
    getName()
    toString()

    Example 4:
    buyDrink: contains getPrice, giveChange, will give an error message if there are none left
    toString: will show everything in the machine and its prices (and quantities?)
    addChange: adds to the machine’s change supply w/o buying anything
    getQuantity: tells you how many of a drink are in the machine

    contains different types of drinks (Drink class?)
    takes coins form Coin class

    Example 5:
    order(x) – The order method is called whenever the user places an order. It decreases the
    quantity of the specific item by 1 and adds the price to the overall profit. The item the person
    order is given by x, which is an integer that corresponds to the object.
    makeChange(x, y) – The makeChange method is always called right after the order method. It
    takes in the item as it’s first parameter and the amount the user put into the machine as it’s
    second. Then, it returns how much the machine owes the user.
    getProfit() – The getProfit method returns the total profit the machine makes.
    getQuantity() – The getQuantity method returns the total quantity left of each item in the
    machine.

    Example 6:
    Classes:
    endingMachine: This class deals with Product objects and the number of Product objects that exist. This also deals with money taken from the user.
    Product: This contains instance variables for different products with their descriptions and prices.
    Driver: represents the user’s interaction with the vendingMachine

    Methods (VendingMachine):
    sellProduct: This method gives a product to the user by lowering the stock of that product and increases profit but checks if the amount of inserted money is enough for the purchase. And if not it refuses it and uses the giveChange method to return the rest.
    collectMoney: Collects only the amount of money needed by the machine and allows for sellProduct method.
    giveChange: Gives the remaining amount of money that was given but not required to purchase the product.
    restockItems: Resets the amount of goods that exist in the vendingmachine.

    Product Methods:
    getPrice: gives price of product
    getProductName: gives the name of the product chosen