CS 3500 Fall 2013 Lecture 2: Review of Java ------------------------- Topics: ------- Java program components How to run Java programs from a command line Why do we need static members and static methods Differences between Java and C++ Methods equals and hashCode in Java Interlude: Using the WebCAT homework server Abstraction barrier: - algebraic specification - design recipe implementation Java program components ----------------------- Java programs consist of class definitions and interface definitions. An interface definition can contain method headers. Any class that 'implements' the interface is then required to implement 'public' methods with the same headers. This way the compiler knows that an instance of a class that implements a particular interface will have defined the methods specified by the interface. Another use of interfaces is the definition of constants used in several different classes. Every class that implements the interface can use these constants without referring to the name of the interface. For example, my sound library defines constants that represent the 120 MIDI instruments. While the MIDI interface knows them by their numerical values, using their names makes the programs more readable. Of course, we do not want to reproduce these constants in every class that deals with the MIDI instruments. An interface may 'extend' another interface. It is a poor choice of terminology. All it means that if interface A extends interface B, then any class that implements interface A must implement all methods defined in the interface A, and has access to all constants defined in interface B. A class may be abstract or concrete. Abstract class may contain 'abstract' methods --- there are just like method headers in interfaces - they have no body and are just a requirement that all subclasses implement all abstract methods. Similarly, any object defined to be of the type defined by an abstract class is guaranteed to have implementation of all abstract methods, regardless of its runtime type (i.e. constructor of which class has been invoked to define this object). Abstract classes may also define fields (members). These are then available to instances of all subclasses. Abstract classes may also define constructors. The subclasses may invoke the constructors in the super class, but only if the super(...) invocation is the first statement in the constructor of the subclass. Also, abstract class may extend another abstract class (see Sestoft for details). Concrete classes contain field (member) definitions, constructors, and method definitions. A class may 'extend' another class (its super class), which can be either abstract or concrete. Java requires that any 'public' class or interface be defined in a file that matches the name of that data type (with a .java suffix). We will discuss the differences between static and non-static (dynamic) fields and method in just a short while. The only static method we mention now is the infamous public static void main(String[] argv) This is the method where the execution of a Java program begins. The arguments to this method are a list of String-s that give the program some additional data to work with. It could be a name of the file the program is to read, a number that specifies some limit on how ofter some task is to be performed, or other simile information. The choice of using this method has its origin in the C programming language and leverages the fact that a String can represent (encode) an arbitrary information. Several related definitions of classes and interfaces can be combined into a package. The entire package can then be compiled and forwarded for use by other programs in the form of a 'jar' file (Java archive). Classes that refer to other classes defined within a specific package 'import' the relevant packages through an 'import' statement prior to any class or interface definitions. How to run Java programs from a command line -------------------------------------------- To run a program, you first need to compile it. First of all, remember that Java requires that the definition of any 'public' class or interface be defined in a file with the same name and with the .java suffix. To compile a java program type >javac MyClassName as long as the class MyClassName does not import any additional packages. Any .java files with the definitions of additional classes and interfaces must be in the same folder as the file MyClassName.java - the compiler will find them and use the code in those files. If you need to import an external library (a .jar file) you need to specify where it can be found, and that it should be used. If it is in the super-folder of the one where your file MyClassName.java appear, the compiler command would be: >javac -classpath .:../somelib.jar MyClassName (assuming the jar file is named somelib.jar). To run a Java program, you need to specify the name of the class in which the desired 'main' method has been defined. In a collection of several classes there may be several such classes, your choice of where to start has to be given. As before, if any of the classes that program consists of refers to an external library, you need to let Java runtime know. So, to run the above program, assuming the 'main' method has been defined in the MyClassName class would be: >java -classpath .:../somelib.jar MyClassName If the 'main' method consumes any arguments, they appear on the command line following all what has been shown. Why do we need static members and static methods ------------------------------------------------ Static methods: In Fundies 2 we have required that every method you define has a purpose statement (a comment) that explains what the method produces or what effect it has on the state of the program. The purpose statement referred to the object that invoked the method by the canonical name 'this'. So, we may have defined in the class Person the method // is this person older that the given age? boolean isOlderThan(int age){...} On the other hand, in a program that deals with sorting an 'ArrayList' we may need a method that would swap the elements in the given ArrayList at the two given indices. Here the method purpose and header would be: // swap the elements in the given ArrayList at the two given indices void swap(ArrayList arlist, int index1, in index2){...} There is no mention of 'this; in the purpose statement - it does not need an instance of the 'Algorithm' class - or whatever is the name of the class where this method is defined. It does not refers to any fields of the class, or methods defined there. Such methods should be defined as static methods. One class in the Java Collections Framework that defines a number of static methods is 'Math' with methods such as Math.max(Number a, Number b), Math.abs(Number n), Math.sin(double angle), Math.sqrt(double d). Another such class is Algorithms. We let you explore that class on your own. Static members (fields): At times every instance of a given class need to refer to constants that remain the same for all instances of the class. So, if we define an interactive graphics-based game world, the width and the height of the canvas (frame) that displays the game actions remains unchanged throughout the game. We can define these values as static fields in the GameWorld class as follows: static int WIDTH = 600; static int HEIGHT = 400; and it can then be accessed by all classes that represents the game components as GameWorld.WIDTH and GameWorld.HEIGHT. By convention, the names of the static constants consist of all capital letters. Differences between Java and C++ -------------------------------- C++ has been built on the foundation of the C language. C language has been designed to build an abstraction layer over the assembly language, to support systems programmers who need to directly manipulate bits and operations of the machine and handle the memory management. There are two legacies of the C language that made their way into C++. The first one is that a C++ programmer is responsible for allocating and de-allocating the memory her program is using. Years of programming practice have shown that this is a frequent source of subtle program bugs, many of which go undiscovered for years - until the program fails unexpectedly. Years of experience have also shown that programs with automatic 'garbage collection' are much easier to debug and are more reliable. The only disadvantage of using the garbage collection is when a program operates in a time-critical mode, and cannot deal with unexpected small delays caused intermittently by the garbage collection. The second legacy of C is the fact that a piece of data in C can be accessed in a number of different ways, using the pointer arithmetic, and so it is possible to access an object's fields as if they represented a different data type that originally defined. This poses a number of security and safety problems, and opens the programs to the possibility of hard-to-detect bugs. Java compiles the whole program into a lower-level language, the Java byte code that runs within the Java 'Virtual Machine'. Java Virtual Machine is allowed to access only a specified part of the memory - protecting the rest of the computer memory from intrusion and corruption. The Java byte code is translated into the host machine code one instruction at a time, and so the same compiled Java code can run without any changes on any of the target host computers, regardless of its native machine code. Methods equals and hashCode in Java ----------------------------------- We will devote much more time to the Java equals and hashCode methods later in the course. For now, you need to know, that if you ant to use the JUnit for testing your programs, you need to define the equality between two objects of the class you define, so it faithfully corresponds to what you consider equality between objects. Further, you need to make sure not to violate the Java rule, that any time you override the equals method, you should also override the hashCode method in such a way that any two objects equal under your definition of equals generate the same hashCode value. Interlude: Using the WebCAT homework server ------------------------------------------- This will be an interactive part of discussing the various aspects of the WebCAT system: -- the style that the WebCAT checks -- the tests it runs (yours and mine) and what to expect there -- the additional grading done by the instructors -- the few idiosyncrasies that make our lives difficult Abstraction barrier: - algebraic specification ------------------------- Here we will discuss the next assignment. You job is to implement the FSet class defined through an 'algebraic specification'. The methods to define and their expected behavior is specified vial algebraic notation. Though this may look confusing, it actually defines very clearly how the desired data type should behave. We will discuss some parts of the specification, so you are comfortable with the notation used there. Abstraction barrier: - design recipe implementation ------------------------------ The advantage of the 'algebraic specification' is that at the basic level you can define the entire implementation by just following yet another 'design recipe'. We will go over the 'design recipe' to get you ready for the next week's homework.