CSC 314 Lecture Notes
Week 3: Interfaces & Inner Classes and Graphics Programming
Questions on the Homework? [1/25]
Benchmarking [2/25]
Static methods [3/25]
Static fields [4/25]
Let's take the quiz... [5/25]
How do we do multiple inheritance in Java? [6/25]
Interfaces [7/25]
Why interfaces [8/25]
Subinterfaces [9/25]
Abstract classes vs.interfaces [10/25]
Comparable
interface of Java.lang [11/25]
Java is strongly typed [12/25]
EmployeeSortTest.java [13/25]
ActionListner
interface of java.awt.event [14/25]
Getting in touch with your Inner Class [15/25]
InnerClassTest.java
[16/25]
GUI [17/25]
javax.swing.JFrame
[18/25]
javax.swing.JFrame
extends java.awt.Frame
[19/25]
javax.swing.JFrame
is the great-great grand daughter of java.awt.Component
[20/25]
CenteredFrameTest.java
[21/25]
ContentPanes and Panels [22/25]
Inheritance [23/25]
A school spireted example [24/25]
Exam Next Week [25/25]
Questions on the Homework? [1/25]
- Did everyone see the extension?
- How's it going otherwise? Questions?
Benchmarking [2/25]
- The
Date
class
java.util.Date
not java.sql.Date
- The time field is instantiated when the class is created!
import java.util.*;
public class BenchMark{
public static void main(String[] args){
final int SIZE = 1500;
int[][] m1 = new int[SIZE][SIZE];
int[][] m2 = new int[SIZE][SIZE];
int[][] m3 = new int[SIZE][SIZE];
int[][] m4 = new int[SIZE][SIZE];
for (int i = 0; i< SIZE; i++){
for (int j = 0; j < SIZE; j++){
m1[i][j] = (int)(Math.random()*500);
m2[i][j] = (int)(Math.random()*500);
}
}
Date addStart = new Date();
m3 = MatrixMath.add(m1,m2,SIZE);
Date addEnd = new Date();
Date mulStart = new Date();
m4 = MatrixMath.mul(m1,m2,SIZE);
Date mulEnd = new Date();
System.out.println("Addition took "+(addEnd.getTime() - addStart.getTime())+" milliseconds");
System.out.println("Multiplication took "+(mulEnd.getTime() - mulStart.getTime())+" milliseconds");
MoreMatrixMath one = new MoreMatrixMath();
System.out.println("There are: " + MoreMatrixMath.howMany() + " instances");
MoreMatrixMath two = new MoreMatrixMath();
System.out.println("There are: " + MoreMatrixMath.howMany() + " instances");
}
}
BenchMark.java
How else did people do it?
Static methods [3/25]
public class MatrixMath{
public static int[][] add(int[][] m1, int[][] m2, int size){
int[][] m3 = new int[size][size];
for(int i = 0; i< size; i++){
for(int j = 0; j < size; j++){
m3[i][j] = m1[i][j]+m2[i][j];
}
}
return m3;
}
public static int[][] mul(int[][] m1, int[][] m2, int size){
int[][] m3 = new int[size][size];
for(int i = 0; i< size; i++){
for(int j = 0; j < size; j++){
m3[i][j] = m1[i][j]*m2[i][j];
}
}
return m3;
}
}
MatrixMath.java
How else did people do it?
Static fields [4/25]
public class MoreMatrixMath extends MatrixMath{
public MoreMatrixMath(){
increment();
}
private void increment(){
++amount;
}
public static int howMany(){
return amount;
}
private static int amount = 0;
}
MoreMatrixMath.java
How else did people do it?
Let's run it!
Let's compare static fields/methods to instance fields/methods, remember our
BankAccount class from last week?
Let's take the quiz... [5/25]
Then we'll go over it.
How do we do multiple inheritance in Java? [6/25]
-We now know that inheritance can be helpful
-Some OO languages allows a class to inherit from more than one unrelated class
-In C++ you can have as much inheritance as you care to debug.
-Only single inheritance in Java, we use Interfaces to accomplish the same goals.
Interfaces [7/25]
- an interface is simply a list of methods with no bodies
- similar to an abstract class where every method is abstract, and every field is final static
public interface Driveable { //can't be private, why?
boolean MUSTBELICENSED = true; // implicitly static and final
static final boolean DANGEROUS = true; // recommended for clarity
boolean startEngine(); //implicitly public
void stopEngine();
float accelerate(float acc);
// you may or may not use the abstract keyword. either is fine, I don't.
abstract boolean turn(Direction dir);
}
Why interfaces [8/25]
- having your class
implement
an interface is like a promise that your class will support the listed methods
- Other classes may insist that you
implement
certain interfaces
- The
Arrays
class will only sort objects that implement the Comparable
interface... more on that later
- Interfaces define abilities, so rather than extending an interface you
implement
an interface. Since a car is driveable an automobile class might implement
a driveable interface.
class Automobile implements Driveable {
public boolean startEngine() {
if (notTooCold) {
engineRunning = true;
}
return engineRunning;
}
public void stopEngine() {
engineRunning = false;
}
public float accelerate(float acc) {
// ..
}
public boolean turn(Direction dir) {
// ..
}
}
- Another possible use of interfaces is as a holder of predefined values.
- By placing initialized variables within the interface, you can bestow those values on a class by having the class implement the interface.
- Unlike class inheritance, a class can
implement
multiple interfaces
- A Car class might want to implement Drivable; but also Comparable, and more...
- You can declare a variable of an interface type!
- If you code to the interface you can change the implementation w/o changing the code that uses the methods
Subinterfaces [9/25]
We subclass classes, so what do you think we can do with interfaces?
If we create an interface that extends another interface then
that is a subinterface.
interface OffRoadDrivable extends Drivable {
static final boolean fourWheelDrive = true;
}
Remember that if we implement OffRoadDrivable we must be sure
to override all the methods in both this interface and the Drivable interface.
Abstract classes versus interfaces [10/25]
Abstract class
- models an abstract concept
- contains real methods
- contains abstract methods
- contains any type of variable
- to use we must extend it
- may be extended by other abstract classes
Interface
- models a behavior or set of attributes
- contains only abstract methods
- contains only static final variables
- to use we must implement it
- may be extended by other interfaces
Both
- classes which extend or implement must override all methods
Comparable
interface of Java.lang [11/25]
public interface Comparable{
int compareTo(Object other);
}
- The
java.util.Arrays
has a sort()
method that will sort an array of objects; but only if every object in the array implements Comparable
!
- In order to sort you must be able to compare, implementing this interface guarantees that the sort method of the
Arrays
class can execute this kind of command: int x = obj1.compareTo(obj2);
- x will be greater than zero if obj1 is greater than obj2, less than zero if the reverse, or zero if equal
- Why not provide the
compareTo()
method without implementing the Comparable
interface?
Java is strongly typed [12/25]
Strong typing means that when a method call is made in Java, the compiler must check to ensure that the method actually exists. Somewhere in the sort
method of the Arrays
class a call is made like this:
(Comparable)a[i].compareTo((Comparable)a[j])
if the cast is allowed, the object implements Comparable
, and thus the existance of the method is assured.
EmployeeSortTest.java [13/25]
import java.util.*;
public class EmployeeSortTest{
public static void main(String[] args) {
Employee[] staff = new Employee[3];
staff[0] = new Employee("Harry Hacker", 35000);
staff[1] = new Employee("Carl Cracker", 75000);
staff[2] = new Employee("Tony Tester", 38000);
Arrays.sort(staff);
for (int i = 0; i < staff.length; i++){
Employee e = staff[i];
System.out.println("name=" + e.getName()
+ ",salary=" + e.getSalary());
}
}
}
class Employee implements Comparable{
public Employee(String n, double s){
name = n;
salary = s;
}
public String getName(){return name;}
public double getSalary(){return salary;}
public void raiseSalary(double byPercent){
double raise = salary * byPercent / 100;
salary += raise;
}
public int compareTo(Object otherObject){
Employee other = (Employee)otherObject;
if (salary < other.salary) return -1;
if (salary > other.salary) return 1;
return 0;
}
private String name;
private double salary;
}
EmployeeSortTest.java
ActionListner
interface of java.awt.event [14/25]
public interface ActionListener{
void actionPerformed(Action event);
}
-Classes that implement this interface can be passed an Action
object from the OS, not explicitly called within the code.
-We will cover this in much more detail next week
-For example the class javax.swing.Timer
requests a class that implements this interface as part of its constructor:
Timer(int interval, ActionListener listener)
and then calls the classes actionPerformed()
method whenever the OS signals that the interval in milliseconds has passed.
class TimePrinter implements ActionListener{
public void actionPerformed(ActionEvent event){
Date now = new Date();
System.out.println("The time is " + now);
}
}
public class TimerTest{
public static void main(String[] args){
ActionListener listener = new TimePrinter();
Timer t = new Timer(10000, listener);
t.start();
}
}
Getting in touch with your Inner Class [15/25]
- An inner class is a class defined inside another class, Why?
- An object of the inner class can access the private data of the outer class
- Inner classes can be hidden from other classes in the same package
- Helpful when writing event-driven programs (more next week)
InnerClassTest.java
[16/25]
import java.awt.event.*;
import java.text.*;
import javax.swing.*;
public class InnerClassTest{
public static void main(String[] args){
BankAccount account = new BankAccount(10000);
account.accrueInterest(10);
while(true){}
}
}
class BankAccount{
public BankAccount(double initialBalance){
balance = initialBalance;
}
public void accrueInterest(double rate){
ActionListener adder = new InterestAdder(rate);
Timer t = new Timer(2000, adder);
t.start();
}
private double balance;
//////INNER CLASS//////
private class InterestAdder implements ActionListener{
public InterestAdder(double aRate){
rate = aRate;
}
public void actionPerformed(ActionEvent event){
double interest = balance * rate / 100;
balance += interest;
System.out.println("new balance: " + balance);
}
private double rate;
}
/////END INNER CLASS//////
}
InnerClassTest.java
Is this a good idea??
GUI [17/25]
- GUI (Graphical User Interface)
javax.swing
is the current standard for Java, don't mind the 'x'
- Swing is much richer than the original Java GUI libraries
- It is also more portable, adapts to the native platform
- Plus it's a little easier to code in
- Be careful, many of the methods used are inherited from the superclasses of Swing
javax.swing.JFrame
[18/25]
import javax.swing.*;
public class SimpleFrameTest
{
public static void main(String[] args)
{
SimpleFrame frame = new SimpleFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// add stuff to your frame here, before showing it!
frame.show();
}
}
class SimpleFrame extends JFrame
{
public SimpleFrame()
{
setSize(WIDTH, HEIGHT);
}
public static final int WIDTH = 300;
public static final int HEIGHT = 200;
}
SimpleFrameTest.java
javax.swing.JFrame
extends java.awt.Frame
[19/25]
-
java.awt.Frame.setIconImage()
- Sets an icon to associate your frame with
java.awt.Frame.setTitle()
- Lets you title your frame
javax.swing.JFrame is the great-great granddaughter of java.awt.Component
[20/25]
-
java.awt.Component.setLocation(x, y)
- Where your component, including frames, will be on the screen
java.awt.Component.setBounds(x, y, width, height)
- Where and how big (in pixels) on the screen
CenteredFrameTest.java
[21/25]
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CenteredFrameTest
{
public static void main(String[] args)
{
CenteredFrame frame = new CenteredFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
}
}
class CenteredFrame extends JFrame{
public CenteredFrame(){
Toolkit kit = Toolkit.getDefaultToolkit(); //Toolkit class gives system info
Dimension screenSize = kit.getScreenSize();
int screenHeight = screenSize.height;
int screenWidth = screenSize.width;
// center frame in screen
setSize(screenWidth / 2, screenHeight / 2);
setLocation(screenWidth / 4, screenHeight / 4);
// set frame icon and title
Image img = kit.getImage("icon.gif");
setIconImage(img);
setTitle("CenteredFrame");
}
}
CenteredFrameTest.java
icon.gif
ContentPanes and Panels [22/25]
The empty part of the frames we keep drawing is the ContentPane, when
we want to add more interesting things, we draw graphic images on a Panel
and then place the panel onto the ContentPane.
import javax.swing.*;
import java.awt.*;
public class NotHelloWorld
{
public static void main(String[] args)
{
NotHelloWorldFrame frame = new NotHelloWorldFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
}
}
/**
A frame that contains a message panel
*/
class NotHelloWorldFrame extends JFrame
{
public NotHelloWorldFrame()
{
setTitle("NotHelloWorld");
setSize(300, 200);
// add panel to frame
NotHelloWorldPanel panel = new NotHelloWorldPanel();
Container contentPane = getContentPane(); //gets this.ContentPane for this frame
contentPane.add(panel); //put a panel on it
}
}
/**
A panel that displays a message.
*/
class NotHelloWorldPanel extends JPanel
{
public void paintComponent(Graphics g) //overide this method, it is called implicitly
{
super.paintComponent(g); //The parent class handles background color etc.
g.drawString("Not a Hello, World program",
75, 100);
}
}
NotHelloWorld.java
Graphics2D
extends Graphics
[23/25]
You can cast your Graphics object, to a 2D object since methods like paintComponent automaticly receive an object of the Graphics2D class:
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D)g;
...
}
Now you have access to shapes, see chapter 7 for a full description of the methods this enables you.
A school spireted example [24/25]
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class DemonDraw{
public static void main(String[] args){
DrawFrame frame = new DrawFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
}
}
/**
A frame that contains a panel with drawings
*/
class DrawFrame extends JFrame{
public DrawFrame(){
setTitle("DrawTest");
setSize(400, 400);
DrawPanel panel = new DrawPanel();
Container contentPane = getContentPane();
contentPane.add(panel);
}
}
/**
A panel that displays rectangles and ellipses.
*/
class DrawPanel extends JPanel{
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
double leftX = 100;
double topY = 100;
double width = 200;
double height = 150;
Rectangle2D rect = new Rectangle2D.Double(leftX, topY,
width, height);
g2.draw(rect);
g2.setPaint(Color.blue);
g2.fill(rect);
g2.setPaint(Color.black);
//chapter 7 goes over Fonts also, it's straight forward
Font f= new Font("SanSerif", Font.BOLD, 20);
g2.drawString("Go DePaul Blue Demons!", 130, 170);
}
}
DemonDraw.java
Exam Next Week [25/25]
-Exam 3 Next Week
-Homework 3 Due Before Class