last updated 2/5/07
Abstraction: A model of a system that includes only the details essential to the perspective of the viewer of the system
Information hiding: The practice of hiding details within a module with the goal of controlling access to the details from the rest of the system "give the user what he needs to use the module; give the implementor only what she needs to implement the module"
Data abstraction: The separation of a data type’s logical properties from its implementation
Abstract data type (ADT): A data type whose properties (domain and operations) are specified independently of any particular implementation
Preconditions: Assumptions that must be true on entry into a method for it to work correctly
Postconditions (or Effects): The results expected at the exit of a method, assuming that the preconditions are true
We specify pre- and postconditions for a method in a comment at the beginning of the method
|
Java Abstract Class
Abstract Method
|
Java Interfaces Similar to a Java class
However
|
A Java interface or abstract class cannot be instantiated. However, a reference variable of the interface or abstract class may be created to point to the concrete class and/or interface implementor.
We can use an interface to formally specify the logical level of an ADT:
For example, see the FigureGeometry interface and the Circle class that implements it below
public interface FigureGeometry
{
final float PI = 3.14f;
float perimeter();
// Post: Returns perimeter of this figure.
float area();
// Post: Returns area of this figure.
void setScale(int scale);
// Post: Scale of this figure is set to "scale".
float weight();
// Precondition: Scale of this figure has been set.
//
// Post: Returns weight of this figure. Weight = area X scale.
}
public class Circle implements FigureGeometry
{
protected float radius;
protected int scale;
public Circle(float radius)
{
this.radius = radius;
}
public float perimeter()
// Returns perimeter of
// this figure.
{
return(2 * PI * radius);
}
public float area()
// Returns area of this figure.
{
return(PI * radius * radius);
} |
public void setScale(int scale)
// Scale of this figure
// is set to "scale".
{
this.scale = scale;
}
public float weight()
// Precondition: Scale of this figure
// has been set.
//
// Returns weight of this figure.
// Weight = area X scale.
{
return(this.area() * scale);
}
}
|
We can formally check the syntax of our specification. When we compile the interface, the compiler uncovers any syntactical errors in the method interface definitions.
We can formally verify that the interface “contract” is met by the implementation. When we compile the implementation, the compiler ensures that the method names, parameters, and return types match what was defined in the interface.
We can provide a consistent interface to applications from among alternate implementations of the ADT.
The primary responsibility of the StringLog ADT is to remember all the strings that have been inserted into it and, when presented with any given string, indicate whether or not an identical string has already been inserted.
Constructors
- A constructor creates a new instance of the ADT. It is up to the implementer of the StringLog to decide how many, and what kind, of constructors to provide.
Transformers
- insert(String element): assumes the StringLog is not full; adds element to the log of strings.
- clear: resets the StringLog to the empty state; the StringLog retains its name.
Observers
- contains(String element): returns true if element is in the StringLog, false otherwise; we ignore case when comparing the strings.
- size(): returns the number of elements currently held in the StringLog.
- isFull(): returns whether or not the StringLog is full.
- getName(): returns the name attribute of the StringLog.
- toString(): returns a nicely formatted string that represents the entire contents of the StringLog.
//---------------------------------------------------------------------
// StringLogInterface.java by Dale/Joyce/Weems Chapter 2
//
// Interface for a class that implements a log of Strings.
// A log "remembers" the elements placed into it.
//
// A log must have a "name".
//---------------------------------------------------------------------
public interface StringLogInterface
{
void insert(String element);
// Precondition: This StringLog is not full.
//
// Places element into this StringLog.
boolean isFull();
// Returns true if this StringLog is full, otherwise returns false.
int size();
// Returns the number of Strings in this StringLog.
boolean contains(String element);
// Returns true if element is in this StringLog,
// otherwise returns false.
// Ignores case differences when doing string comparison.
void clear();
// Makes this StringLog empty.
String getName();
// Returns the name of this StringLog.
String toString();
// Returns a nicely formatted string representing this StringLog.
}
//----------------------------------------------------------------------
// UseStringLog.java by Dale/Joyce/Weems Chapter 2
//
// Simple example of the use of a StringLog.
//----------------------------------------------------------------------
public class UseStringLog
{
public static void main(String[] args)
{
StringLogInterface log; //declare with interface
log = new ArrayStringLog("Example Use"); //instantiate with implementation
log.insert("Elvis");
log.insert("King Louis XII");
log.insert("Captain Kirk");
System.out.println(log);
System.out.println("The size of the log is " + log.size());
System.out.println("Elvis is in the log: " + log.contains("Elvis"));
System.out.println("Santa is in the log: " + log.contains("Santa"));
}
}
/*********************** output
Log: Example Use
1. Elvis
2. King Louis XII
3. Captain Kirk
The size of the log is 3
Elvis is in the log: true
Santa is in the log: false
*/
public class ArrayStringLog implements StringLogInterface
{
protected String name; // name of this log
protected String[] log; // array that holds log strings
protected int lastIndex = -1; // index of last string in array
public ArrayStringLog(String name, int maxSize)
// Precondition: maxSize > 0
// Instantiates and returns a reference to an empty StringLog object
// with name "name" and room for maxSize strings.
{
log = new String[maxSize];
this.name = name;
}public ArrayStringLog(String name)
// Instantiates and returns a reference to an empty StringLog object
// with name "name" and room for 100 strings.
{
log = new String[100];
this.name = name;
}
public void insert(String element)
// Precondition: This StringLog is not full.
// Places element into this StringLog.
{
lastIndex++;
log[lastIndex] = element;
}
public void clear()
// Makes this StringLog empty.
{ //ensuring every element is set to null is good
for (int i = 0; i <= lastIndex; i++)
log[i] = null;
lastIndex = -1; //could get away with just this line!
}
public boolean isFull()
// Returns true if this StringLog is full, otherwise returns false.
{
return lastIndex == (log.length - 1);
}
public int size()
// Returns the number of Strings in this StringLog.
{
return (lastIndex + 1);
}
public String getName()
// Returns the name of this StringLog.
{
return name;
}
public String toString()
// Returns a nicely formatted string representing this StringLog.
{
String logString = "Log: " + name + "\n\n";
for (int i = 0; i <= lastIndex; i++)
logString = logString + (i+1) + ". " + log[i] + "\n";
return logString;
}
public boolean contains(String element)
// Returns true if element is in this StringLog
// otherwise returns false.
// Ignores case differences when doing string comparison.
{
int location = 0;
boolean found = false;
while (location <= lastIndex && !found)
{
if (element.equalsIgnoreCase(log[location])) // if they match
found = true;
else
{
location++;
}
}
return found;
}