***





Java - More - I

 

'More'

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..

Inner classes

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.

Inner classes [cont'd]

Here is an example.

Inner classes [cont'd]

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?).

'final' vars

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

'final' methods

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

'final' classes

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]

File OUTPUT

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.

File OUTPUT [cont'd]

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

File OUTPUT [cont'd]

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?

File OUTPUT [cont'd]

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).

File OUTPUT [cont'd]

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.

File OUTPUT [cont'd]

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:

File OUTPUT [cont'd]

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] :)