Java - More - I |
Having looked at the core language elements (vars, types, operators, statements (including flow control) and classes), we now focus on the 'what else' part - in other words, there are more things to study..
In Java, a class definition can have one or more class definitions INSIDE it! Such on-the-inside classes are called, appropriately enough, 'inner classes'.
A private function (method) would exist in a class, to be a 'helper' for sibling public functions; similarly, an inner class is there to help create objects (of its type, of course) that will be useful to methods in the enclosing class.
An inner class has full access to the outer class' data members (even private ones), whereas a subclass would not!
Why at all create and use an inner class? "Separation of concerns".
Customary to keep inner classes private (what might happen otherwise?).
A variable.. varies (duh!). But a 'final' variable CANNOT!
class FinalVars {
public static void createUsers_v1() {
int MAXUSERS=100;
int[] users = new int[MAXUSERS];
//... later ...
MAXUSERS *= 5;
int[] moreUsers = new int[MAXUSERS];
}// createUsers_v1()
public static void createUsers_v2() {
final int MAX_USERS=100; // becomes IMMUTABLE
int[] users = new int[MAX_USERS];
//... later ...
MAX_USERS *= 5; // no! [not allowed, so compile-time error]
int[] moreUsers = new int[MAX_USERS];
}// createUsers_v1()
public static void main(String[] args) {
createUsers_v1();
createUsers_v2();
}// main
}// class FinalVars
A method that has been declared 'final' in a class, can't be overridden in subclasses.
class FinalMethods {
public static void main(String[] args) {
Sub s = new Sub();
s.aMeth();
}// main()
}// class FinalMethods
class Super {
// to make the overriding FAIL, add 'final' after 'public' below, recompile
public void aMeth() {
}// aMeth()
}//Super
class Sub extends Super {
// [try to] override
public void aMeth() {
System.out.println("Inside Sub's aMeth()");
}// aMeth()
}// Sub
A class marked 'final' can't be subclassed [the 'dynasty' ends]!
class FinalClasses {
public static void main(String[] args) {
Sub s = new Sub();
s.aMeth();
}// main()
}// class FinalClasses
// to make the osubclassing below FAIL, add 'final' before 'class' below, recompile
class Super {
public void aMeth() {
}// aMeth()
}//Super
// [try to] subclass
class Sub extends Super {
public void aMeth() {
System.out.println("Inside Sub's aMeth()");
}// aMeth()
}// Sub
This thread is informative.. [FYI]
It is VERY useful to know how to 'write to' a file, ie. create a file on disk, fill it with data (numbers, strings, BINARY values..) and save the contents, all using code.
If we can create files, we can create images, music, video, 3D graphics, CSV files, data files for databases..
In Java, we can use these three classes to create ASCII (plaintext) files: File, FileOutputStream, PrintStream [all are part of java.io]. To write binary data, we only need File and FileOutputStream.
Example that creates a text file with strings and numbers:
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.IOException;
public class POS {
public static void main(String[] args) throws IOException {
File f = new File("C:\\temp\\tst.txt");
FileOutputStream fout = new FileOutputStream(f);
PrintStream out = new PrintStream(fout);
out.println("Hello..");
out.println("text file!");
for(int i=0;i<5;i++) {
out.println(Math.sqrt(i));
}// next i
}// main()
}// class POS
We can also create .pgm and .ppm (color pixels!) files :)
This is an example that shows how to output a .ppm file (viewable using IrfanView etc. or this .pgm viewer) that contains a random RGB value at each pixel - it uses a Pixel inner class (which avoids us having to create a separate Pixel.java source file, and also keeps the Pixel class encapsulated).
The Pixel class is also a 'static' inner class - here is an explanation [if you want you can IGNORE understanding this for right now].
What small changes would you need to make, to output .pgm (grayscale) files instead, again with random values for pixel colors?
Now that we can write out a .ppm, we can play with pattern generation again.
It is QUITE **AMAZING** what "just" (x,y) combined with standard math functions can do (remember that the Mandelbrot fractal also falls under the category of (x,y) plus functions => art).
We can also output CSV (comma separated values) files, a VERY useful capability - this can help shuttle data into spreadsheets and databases..
To illustrate, Student.java which defines a 'Student' class - with this we can create an ArrayList of Student entries, and populate the list (eg. via a database search, entry via a web form, smartphone UI, etc).
Once we have a list of students, we can use CSVExporter.java to write the data out as a .csv file.
The CSV file output (from previous slide's code) looks like this:
The .csv file can now be read into OpenOffice (etc) via File -> Open. The student entries now show up as a spreadsheet (cool!), like this:
Finally, let us output a .mid (MIDI) **binary** file, from scratch (using things we have learned, without extensive library files). Compare this, with the C++ MIDI 'library' (source code, not compiled) we used earlier!
This file contains standalone code for generating a MIDI file. Play with the data input section, see if you can put in notes for 'Twinkle twinkle..', or *this* song [derived from this one] :)