Introduction to OO and a quick Java recap Introduction to OO and a quick Java recap Summary The basic concepts of OO and why they were developed. Some examples of very small Java programs to illustrate some basic syntax and features. Some practical heuristics of software modelling in the OO style. Book reference: No specific reading this week; Resources: Some small examples of Java code (available from the COMP229 iLearn pages). Introduction to OO Most of you will be familiar with many of the features of procedural programming, namely a program structure which consists of a number of procedures or functions that process particular pieces of data. Typical of the exercises that most students are set at this stage is to write a program which executes and then terminates. Today’s large applications differ from that kind of programming in two important respects. The first is that the programs never really terminate, and the data is said to “persist”, continuously being updated and consulted. Secondly is that big systems require large programs and teams of programmers to build them. With many programmers working on the same project, data must be “protected” from the other team members. One of the main concepts in Java and other OO languages is their structuring features, in particular to allow data to be encapsulated with the programs that are allowed to modify it. In procedural programming, amongst other things The structure of the program does not reflect the problem, making it hard to get right and specialised for each new application, however similar; Data cannot persist in standalone programs; Code cannot easily be reused or shared between several team members. OO came about in stages as a way to try to solve all of these problems. Some OO features OO languages, like Java, allow data to be encapsulated with the code that processes it. OO allows the programming language to reflect the programming problem and OO languages support the use of “templates” so that code can be replicated and adapted or specialised within a single larger project. Other aspects of the OO approach include subtyping and inheritance, which again encourages simplification as layered code, appropriate for the development. We’ll see examples of all these ideas as the course progresses. Modelling the world: the objective view In the real world objects physically manifest what can be done to them. For example an ordinary book can have its pages turned, or be written in and — the book cannot be replicated, cannot be overwritten by somebody else, cannot have pages removed or re-ordered the extent to which that is possible is limited by the physical makeup (i.e. paper and ink). In software development the OO view is that the programming language should be structured in a way to allow the program to be aligned with the problem and, by extension, the physical (and other) entities that make up the “system” being developed. Physical objects not only embody a thing itself, but also its properties — by allowing data to be encapculated with methods in an object we have the software equivalent of a physical component. The data represents “the thing itself”, and the methods “what its properties are”, i.e. what can be done to make it change. OO development mimics development of engineered systems We build a physical device by deciding what components are needed to make the device and then putting them together — the complete device will work only if the components are put together in the “correct” way. The point is that the components have particular properties which are special to themselves and not to the device. The proponents of OO claim that software should be developed in the same way. The challenge is to define -software- components so that their behavioural properties are clearly defined — it implies careful documentation of what those behaviours are. The main difference between building a physical device and software is that we can “touch” and “visualise” physical things — we can’t do that with software. The point about object orientation is that the functionality of classes should as far as possible capture the functionality of the physical object that it is modelling. In contrast the actual code that implements the functionality does not need to bear any resemblence to physical things, and indeed in many cases it’s better that it doesn’t. The point is that the Interfaces, Encapsulation, and the Protections that OO and (in particular) Java provides allows the programmer to have something of both worlds. Consider the following examples. A statistics package In the statistics package (available from iLearn), we have description of some functionality which is common in many pocket calculators. The package allows a series of numbers to be entered and their average value to be calculated on the click of a button (= total sum of items/number of items). The following method declarations describe the functionality. public void inputItem(double _item);
// Add an item to the list
public void clear();
// Clear the items
public double mean();
// Compute and return the average value of the items inputted so far. One possible implementation to achieve this functionality would be to store the inputted items in a vector and then calculate their mean according to the above formula. But this is wasteful in space; an experienced programmer might choose the space-saving implementation illustrated in the statisticsDemo package available from iLearn. Encapsulation gives programmers the freedom to choose the data structure that it most suited to the properties of the class. The above example suggests an implementation which might not be the most obvious first-choice datastructure. The point is that provided the specified functionality is correct then it should not matter for the user of the system. Moreover the programmers’ assumptions about what all the variables in the system means are also protected from other components. A small database prototype Consider the following scenario. A customer of the company you work for wants an integrated web-based system, which includes access to a database. Your boss has given you the job of implementing only the database part. You must build a package which allows items to be stored, deleted and retrieved. You have been given two days to deliver. A quick solution is to choose an implementation which is easy to put together and test within a tight deadline. You choose a simple and inefficient solution to store items in an array. You meet your deadline. Take a look in the DatabaseDemo class available from iLearn to see a cheap and easy implementation to demo to the customer. Note that it uses simple but slow algorithms for the look up. The customer is very pleased with the result but now tells your boss that he wants to deploy the system for a phone company which contains millions of entries. Your boss passes on the “good” news. You take your program and must change the internals to maintain the functionality but to improve the performance. In particular a linear search for the look up is far too inefficient. With the OO design however that’s all you have to change and it will not change anything else that your team members are working on. Take a look in the DatabaseDemo2 class available from iLearn. Notice that it uses the same interface but a different implementation for the look up — one that is able to cope efficiently with huge data sets. Encapsulation speeds up prototyping Password protection Consider password protections that are common in mobile phones and ATMs. Normally the user is allowed “three tries” before being notified that his card cannot be used anymore. Where should the information about the number of tries be stored: as a global variable on the card which might be affected by other unrelated methods, or inside “password” class which is specialised for authentication etc. \begin{center}\fbox{\parbox{4in}{Encapsulation allows data to be logically placed with its methods, similar to the way that physical objects embody their own physical characteristics.}}\end{center} How do we analyse real problems in OO terms? Software projects begin with an idea about what the system should do. This is normally written in natural language and the programming team’s job is to take the natural language and turn in into computer code. Consider the example of designing a program for social networking. The following are two heuristic techniques for turning the informal requirements into an OO design which can ultimately be implemented. The Noun phrase method. Start by writing down informally what you want the system to do; Identify the “noun phrases” — these will be your object candidates; Now group the nouns together in related groups — these will be the candidate clasees. What are the nouns in social networking? Friends; Madonna; Neil Armstrong; Album; me on the beach; me eating an icecream; Game; scrabble, chess The object Think method This helps us organise activities to be associated with the data: I am a button on the screen:I know my position, my height and width, my colour, my label, what message to send when I’m clicked. I am a window: I know my title and position, I how to close, or be “put aside”, what I am displaying and which part of me has been selected. I am a chat session: I know which friends are chatting, what to do when the chat is terminated and how to add new chatterers. We apply this to further elaborate the structure of the objects and classes. Objects and classes One way to distinguish between objects and classes is to try to list the attributes. Any attribute will be a “data member”, and concrete collections of these things will be an instance, or an object. Objects have attributes: A friend has an email address, a system id, a list of other friends. A game has a board and a status, a number of players, whose turn it is. Not all objects correpond to physical objects. A “chat” is something which could be an object, but it’s not a physical thing. Its attributes are participants, each one a friend etc. Recalling the basic Java features Most of you have completed COMP125 in Java and so will be familiar with some basic Java. This section is for those who might have completed COMP125 before 2011 or have gained entry by credit for previous studies. Although different programming languages appear to be very different, they often share some basic core principles. C++ and Java for example share some basic structure (and even syntax), so if you are already familiar with one of them (in this cae C++) it’s worthwhile reviewing what those core principles are: it will make learning the new language (i.e. Java) much simpler! Two of the key ideas to remember when programming in Java is that first, whenever you write a program, you will be required to create a class; second is that all variables (apart from basic types) are actually references, and so a bit like C++’s “pointer” variables. This means in method calls, for example, the variables are passed by value (it’s just that the value is a reference to memory where the object is located). These ideas are actually present in C++, the only difference is that in Java they are fundamental. Once you have understood these concepts and their implications however, many of the basic programming features in C++ transfer quite simply to Java. The table below sets out a crib for some of these core principles shared by both Java and C++. For both C++ and Java, the basic libraries and examples of syntax are given. The first tutorial exercises (for completion by the end of Week 2) will reinforce these core language principles so that, if this is your first time programming Java, you should be able to use what you already know to help your learning. Language feature C++ Java “main” program int main() { .. \ public static void main() \{.. \ Output cout << "a string" << endl; System.out.println("a string" + '$\backslash$n'); Simple variables int x= 0; char ch= 'a'; int x= 0; char ch= 'a'; for-loops for(int i= 0; i< 3; i++) \{x=x+i;\ } for(int i= 0; i< 3; i++) \{x=x+i;\ strings: use Must include a library: $\#$include Library: import java.lang.String; strings: declaration string x; x= "abc"; String x= new String; x= "abc"; OR, String x; x= "abc"; Arrays: declaration int myArray[3]; int myArray[]= new int[3]; Arrays: declaration String mySarray[3]; String mySarray[]= new String[3]; Arrays: use myArray[0]= 1; myArray[0]= 1; Arrays: use mySarray[0]= "hello"; mySarray[0]= "hello"; Input/output Must include a library: $\#$include Library: import java.io.*; Conditional if (Cond) x= 0; else x=1; if (Cond) x= 0; else x=1; Method calls Call-by-reference or call-by-value All method calls are call-by-value By-value: basic void f(int x) \{ x=x+1; \} void f(int x) \{ x=x+1; } By-reference: basic void f(int &x) { x=x+1; } We cannot translate this. Parameters: arrays void g(int[] x) \{ x[0]=2; } void g(int[] x) \{ x[0]=2; } Parameters: objects void h(MyObject \&x)\{ \\ ... "update x" ... \\ \} void h(MyObject x)\{ \\ ... "update x" ... \\ \} Classes Data and methods Declaration public or private A range, including static Consult Jia 4.4 Constructors Default and user-defined Default and user-defined Implementation myClass::myClass(params) \{\\ "Implementation"\\ \} myClass(params) \{\\ "Implementation"\\ \} Methods: Declaration void myMethod (params); void myMethod (params); Methods: Implementation void myClass::myMethod(params) { "Implementation..."} void myMethod(params){ "Implementation..."} JUnit for correctness testing of your programs JUnit testing is a way to test key properties of the classes that you implement; it should be used in addition to other kinds of testing. You need to have the JUnit library installed in Eclipse, as well as linked to your Java project. Like any kind of testing, how well it tests the programs is determined by the quality of the test. You will be writing your own JUnit tests to test the methods that you implement. To get the most use out of the exercise think carefully about what the method is required to achieve, and then formulate a (set of) representative tests that you think will validate its requirements. You will probably need to think up several tests for each method because for complex data structures there are a number of special cases. In the case of lists for example, methods usually behave specially in the case of empty lists, lists with a single item, and where the processing occurs at the beginning, middle or end of the list. Study the examples given in databaseDemo to see examples of JUnit tests for the class. You can try writing some yourself this week to get up to speed in case you have not used JUnit before. Including JUnit libraries in your project If you are having trouble getting Eclipse to recognise JUnit, make sure you have the current Eclipse installed; this includes JUnit 4, which we’ll be using in this course. You still have to “tell” Eclipse where to find those libraries, so here’s what to do. Inside of your test file at the top you need to have an import statement import org.junit.Test; This will allow you to use the various “assert” facilities supported in the JUnit libraries. Eclipse needs to know where those libraries are, so you’ll need to include the JUnit Library in your project settings via the project properties; this is found under the Project menu. From there, open the Java Build Path setting and then look at the Libraries tab. By default there should be an entry there for the JRE System Library. Next you need to add JUnit via the Add Library button, and selecting JUnit. In the dialog for the JUnit library it shows the path of the library (e.g. something like …/Eclipse/plugins/org.junit…). Select JUnit 4. Finally save the project settings and those pesky error flags (is you had them) should magically disappear! Advanced Design This example is an advanced (beyond the level required to pass this course) discussion of Object Oriented Design. Revision Exercises for Java and Eclipse If you haven’t used Eclipse before, have a look at the Eclipse and Java for total beginners lesson 1 flash video, by Mark Dexter and the the accompanying tutorial companion If you feel confident, you might like to find the Eclipse application and work through the steps in the tutorial video for yourself. Indeed, you might even like to use Eclipse to complete the exercises above. We will start using Eclipse in earnest in the Week 2 practical, and Annabelle will provide an introduction to this important tool in the Week 1 lectures. JUnit Have a go at writing some JUnit tests for delete and getSize in the DatabaseDemo class. New Tests Add some JUnit tests to the classes in the StatisticsDemo . HelloWorld If you’re new to Java search the web for instructions on how to compile and run simple Java programs using the Java developers kit command line tools, and follow those instructions to compile and run these two versions of the “Hello World” program: HelloWorld.java and HelloWorldGUI.java . Note: The Java Developer’s Kit (JDK), which you need to compile Java programs, is installed on the lab machines and can be accessed from the Windows command line. However, you may need to work out what folder the JDK is installed in and set your Windows PATH to include the bin subdirectory of that installation before trying to compile this code. Also: If you find that you get the following kind of error when you try to run the code you’ve compiled: Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld (wrong name: org/macquarie/hello/HelloWorld) then you might want to find out a little about how Java packages work by consulting the following Java packages tutorial Text Editor Use your favourite text editor to inspect the code in the files above, and try to answer the following questions: How does the programmer tell the Java runtime where to start executing his/her code when an application is started? What method (aka command or function) is used to output text to the terminal in Java? Try modifying the HelloWorld.java code to display a different greeting, recompile your new code and check that it does what you expect. Identify the basic parts of these Java programs … class declarations, library imports, variable declarations, method (function) declarations, local variable declarations etc. What patterns do you notice in the naming of files, classes, variables etc.? What parts of the code in the HelloWorldGUI.java version of this application build which parts of the GUI you observe when you run that application? Modify the HelloWorldGUI.java code to change the greeting messages it displays, recompile your new code and check that it does what you expect. GUI Modify the HelloWorldGUI.java code to change the legends displayed on the buttons of its GUI, recompile your new code and check that it does what you expect. GUI (HD) Modify the HelloWorldGUI.java code to add a new button. This should be positioned in the same horizontal line as, and between the, exiting buttons. Its legend should read “Have we met before?” and when pressed it should display the message “I don’t think so” in the text box above the row of buttons. Assessed class exercise Read the following (very brief) software application description: “The application will be called the Library Catalogue System (LCS). The LCS will manage all library resources such as monographs, journals and AV material. In addition to recording all the details of these resources, their location and status (available, borrowed, overdue) needs to be tracked. Client and staff details will also need to be managed. The current manual method of managing resources, staff and clients is time consuming and error prone. It is also difficult to manage the large paper flow involved in this process. The LCS will allow library administrative staff to access relevant information efficiently and effectively." Brainstorm (and write down) some possible classes, attributes, methods, associations and inheritance relationships that might arise in the design of the LCS system. To do this you might like to use the noun-phrase and object-think approaches discussed in the lectures. Which approach did you find more helpful? Sketch a simple diagram illustrating the classes you identified above and their inter-relationships. Blanks Consult your lecture notes or a basic web based Java tutorial, and fill in the blanks in the following statements: The ________ command from the J2SDK executes a compiled Java application. The ________ command from the J2SDK compiles a Java application. A Java program file must end with the ________ file extension. When a Java program is compiled, the file produced by the compiler ends with the ________ file extension. Each Java program file contains ________ java class(es). (possible answers here include ten, at most one, as many as you like, exactly one…) Is everything in life really an object? Is it really more difficult to think in terms of procedures as compared to thinking in terms of objects? Basic Java Here are some simple exercises to get you started writing code in Java. At its simplest Java is much like Processing or C++, both in terms of its fundamental syntax and with regard to the standard operators. looping constructs and basic data types that it provides. If you’re familiar with C++ but not Java, refer to the week 1 notes for a one page crib sheet giving a quick translation for these basic constructs. To get started with Java you might want to browse the first three chapters of Thinking in Java by Bruce Eckel (consult the Week 1 resources for where to download it). Write a Java application which uses a for loop to print the even integers between 0 and 100 (inclusive) to the terminal. Recall from lectures: The standard terminal output stream is called System.out in Java, and you can send text to this output stream using the commands System.out.print() , System.out.println() and System.out.format() . You can find out more about these methods by consulting the Java API documentation for the PrintStream class. Write a Java application which uses a nested pair of for loops to print he following triangle of integers to the terminal: 9
9 8
9 8 7
9 8 7 6
9 8 7 6 5
9 8 7 6 5 4
9 8 7 6 5 4 3
9 8 7 6 5 4 3 2
9 8 7 6 5 4 3 2 1 Write a Java application which uses a nested pair of for loops to print all of the prime numbers between 2 and 200 to the terminal. Remember: a prime number is any strictly positive integer which is only divisible by 1 and itself. So you may check to see if a number num is prime using a loop in which we test to see if it is divisible by any number between 2 and num/2. To test whether one number is divisible by another you may use the remainder operator %. Write a Java application which contains an “infinite” while loop, whose body generates two random numbers between 0 and 999 which it prints to the terminal along with a message indicating how they compare. So for example, here is some sample output from a run of my program: 244 is greater than 30
799 is greater than 542
87 is greater than 74
39 is less than 553
both numbers were 174
989 is greater than 579
917 is greater than 480 Note: if left to its own devices my while loop will run on for ever, generating pairs of random numbers on each iteration. So to stop my program I had to press the little red “stop” square that appeared in Eclipse above the console that was displaying this output. Hint: To generate random double precision numbers between 0.0 and 1.0 you can use Java’s Math.random() method. To round a double to a long integer you can use Java’s Math.round() method. To convert a double to the largest integer less than it or the smallest integer greater than it you can use the Math.floor() and Math.ceil() methods. You can find out more about these methods by consulting the Java API documentation for the Math class. Objects Is everything in life really an object? Is it really more difficult to think in terms of procedures as compared to thinking in terms of objects? based heavily on notes by Annabelle McIver