Important Java Programming Concepts
Total Page:16
File Type:pdf, Size:1020Kb
Appendix A Important Java Programming Concepts This appendix provides a brief orientation through the concepts of object-oriented programming in Java that are critical for understanding the material in this book and that are not specifically introduced as part of the main content. It is not intended as a general Java programming primer, but rather as a refresher and orientation through the features of the language that play a major role in the design of software in Java. If necessary, this overview should be complemented by an introductory book on Java programming, or on the relevant sections in the Java Tutorial [10]. A.1 Variables and Types Variables store values. In Java, variables are typed and the type of the variable must be declared before the name of the variable. Java distinguishes between two major categories of types: primitive types and reference types. Primitive types are used to represent numbers and Boolean values. Variables of a primitive type store the actual data that represents the value. When the content of a variable of a primitive type is assigned to another variable, a copy of the data stored in the initial variable is created and stored in the destination variable. For example: int original = 10; int copy = original; In this case variable original of the primitive type int (short for “integer”) is assigned the integer literal value 10. In the second assignment, a copy of the value 10 is used to initialize the new variable copy. Reference types represent more complex arrangements of data as defined by classes (see Section A.2). The important thing to know about references types is that a variable of a reference type T stores a reference to an object of type T. Hence, values of reference types are not the data itself, but a reference to this data. The main implication is that copying a value means sharing a reference. Arrays are also reference types. For example: © Springer Nature Switzerland AG 2019 273 M. P. Robillard, Introduction to Software Design with Java, https://doi.org/10.1007/978-3-030-24094-3 274 A Important Java Programming Concepts int[] original = new int[] {1,2}; int[] copy = original; copy[0] = 3; int result = original[0]; // result == 3 In this case, copy is assigned the value stored in original. However, because the value stored in original is a reference to an object of an array type, the copy also refers to the object created in the first statement. Because, in effect, copy is only a different name (or alias) for original, modifying an element in copy also modifies that element in original. A.2 Objects and Classes Essentially, an object is a cohesive group of variables that store pieces of data that correspond to a given abstraction, and methods that apply to this abstraction. For example, an object to represent the abstraction “book” could include, among others, the book’s title, author name, and publication year. In Java, the class is the compile- time entity that defines how to build objects. For example, the class: class Book { String title; String author; int year; } states that objects intended to represent a book will have three instance variables named title, author, and year of type String, String, and int, respectively. In addition to serving as a template for creating objects, classes also define a cor- responding reference type. Objects are created from classes through a process of instantiation with the new keyword: Book book = new Book(); The statement above creates a new instance (object) of class Book and stores a reference to this object in variable book declared to be of reference type Book. Instance variables, also known as fields, can be accessed by dereferencing a variable that stores a reference to the object. The dereferencing operator is the period (.). For example, to obtain the title of a book stored in a variable book,wedo: String title = book.title; When discussing software design, it is good to avoid subconsciously using the terms class and object interchangeably. Objects and classes are different things. A class is a strictly compile-time entity that does not exist in running code. Conversely, objects are strictly run-time entities that do not have any representation in program source code. Mixing them up can lead to ambiguity and confusion. A.4 Methods 275 A.3 Static Fields Java allows the declaration of static fields: class Book { static int MIN_PAGES = 50; String title; String author; int year; } The effect of declaring a field static means that the field is not associated with any object. Rather, a single copy of the field is created when the corresponding class is loaded by the Java virtual machine, and the field exists for the duration of the program’s execution. Access to static fields can be restricted to only the code of the class in which it is declared using the access modifier private. If declared to be public, a static field can be accessed by any code in the application, in which case it effectively constitutes a global variable. Because it is generally a bad practice to modify globally-accessible data, global variables are best defined as constants, i.e., values not meant to be changed. Globally-accessible constants are declared with the modifiers public, static, and final, and typically named using uppercase letters (see Appendix B). class Book { public static final int MIN_PAGES = 50; ... } Static fields are accessed in classes other than the class that declares them by prefixing their name with the name of their declaring class, followed by a period. For example: int minNumberOfPages = Book.MIN_PAGES; A.4 Methods In Java and other object-oriented programming languages, a method is the abstrac- tion for a piece of computation. A method definition includes a return type, a name, a (possibly empty) list of parameters, and a method body. The return type can be re- placed by the keyword void to indicate that the method does not return a value. The method body comprises the statements that form the implementation of the method. Methods correspond to procedures in procedural languages and functions in functional languages. Java supports two main categories of methods: static methods and instance methods. Static methods are essentially procedures, or “non-object- oriented” methods. Although they are declared in a class for reasons discussed in 276 A Important Java Programming Concepts Chapter 2, they are not automatically related to any object of the class and must explicitly list all their parameters in their signature. Method abs(int), declared in the library class java.lang.Math, is a typical example of a static method. It takes an integer as an input and returns an integer that is the absolute value of the input number: no object is involved in this computation. Static methods are declared with the static modifier: static int abs(int a) {...} and called by prefixing the name of the method with the name of the class that declares the method, for example: int absolute = Math.abs(-4); In contrast, instance methods are methods intended to operate on a specific in- stance of a class. For this reason, instance methods have an implicit parameter of the same type as the type of the class they are declared in. An example is the static method getTitle(Book book) that simply returns the title of a book. Because this is a static method, it requires all necessary data to be provided as input: class Book { String title; ... static String getTitle(Book book) { return book.title; } } Because method getTitle(Book) operates on an instance of class Book,it makes more sense to declare it as an instance method. In this case, the parameter book becomes implicit: it must not be declared in the method’s list of parameters, and its corresponding value becomes accessible inside the body of the method in a special variable called this. The code for getTitle written as an instance method is thus: class Book { String title; ... String getTitle() { return this.title; } } An instance method gets invoked by dereferencing a variable that stores a refer- ence to an object. The result of the process is that the object referenced becomes the implicit argument to the instance method. In the statement: Book book = ...; String title = book.getTitle(); the object referenced by variable book becomes bound to the this pseudo-variable within the body of getTitle(). A.6 Generic Types 277 A.5 Packages and Importing User-defined types such as classes are organized into packages. Types declared to be in one package can be referenced from code in a different package using their fully-qualified name. A fully-qualified name consists of the name of the type in the package prefixed by the package name. For example, class Random of pack- age java.util is a pseudo-random number generator. Its fully-qualified name is java.util.Random. Declaring a variable using a fully-qualified name can be rather verbose: java.util.Random randomNumberGenerator = new java.util.Random(); For this reason, it is possible to import types from another package using the import statement at the top of a Java source code file: import java.util.Random; This makes it possible to refer to the imported type using its simple name (here Random) instead of the fully-qualified name. In Java, the import statement is sim- ply a mechanism to avoid having to refer to various program elements using fully- qualified names. In contrast to other languages, it does not have the effect of making libraries available that were not already available through their fully-qualified name. In addition to importing types, Java also makes it possible to import static fields and methods.