Session 22 Chapter 11: Implications of Inheritance Using Images in Java • Image class in java.awt.Image • Toolkit (see section 17.6 of text) contains some useful utilities: – getImage() takes a string or URL and returns a value of type Image – getScreenSize() returns a Dimension object containing the number of pixels of both the height and width – getScreenResolution() returns the number of dots per inch • Dividing one by the other will yield the physical size of the screen – getFontList() returns an array of strings that contain the names of the fonts available on the current system – etc.... Simple Image Code import java.awt.*; public class ImageTestApp extends Frame { private Image demo; public static void main(String[] args) { ImageTestApp app = new ImageTestApp(); } public ImageTestApp() { setTitle( "Image Test" ); setSize( 450, 450 ); demo = Toolkit.getDefaultToolkit().getImage("logo.gif" ); show(); } public void paint( Graphics g ) { g.drawImage( demo, 200, 200, 50, 50, this ); } } // end class ImageTestApp Exercise with Image Code • Modify the ImageTestApp so the logo moves to where the mouse is pressed in the frame. A Solution import java.awt.*; import java.awt.event.*; public class ImageTestApp extends Frame { private Image demo; private int demoX; private int demoY; private int demoSize; public static void main(String[] args) { ImageTestApp app = new ImageTestApp(); } public ImageTestApp() { setTitle( "Image Test" ); setSize( 450, 450 ); demo = Toolkit.getDefaultToolkit().getImage( "logo.gif" ); demoX = 200; demoY = 200; demoSize = 50; addMouseListener( new MouseKeeper() ); show(); } ... A Solution import java.awt.*; import java.awt.event.*; public class ImageTestApp extends Frame { ... public void paint( Graphics g ) { g.drawImage( demo, demoX-demoSize/2, demoY-demoSize/2, demoSize, demoSize, this ); } private class MouseKeeper extends MouseAdapter { public void mousePressed( MouseEvent e ) { demoX = e.getX(); demoY = e.getY(); repaint(); } // end mousePressed } // end private class MouseKeeper } // end class ImageTestApp Polymorphism • polymorphism comes from the Greek root for “many shapes” • polymorphism is about how we can use different objects in the same place in our program, i.e., polymorphism depends on objects that are substitutable for one another • Decorators are great examples of polymorphism: – Because the decorator class is a subclass, instance of the decorator can substitute for instances of the superclass – Because the decorator class holds an instance of the superclass, it can hold instances of anything substitutable for the superclass. Polymorphic Variable • A polymorphic variable can hold many different types of values • Object-oriented languages often restrict the types of values to being subclasses of the declared type of the variable. • Example: “PinBallTarget target” can be assigned a “Hole”, “ScorePad”, etc. Implications of Inheritance/Polymorphism • At compile-time, the amount of memory for polymorphic variables cannot be determined, so all objects reside in the heap • Because values reside in the heap, reference semantics is used for assignment and parameter passing • Most natural interpretation of equality is identity. Since programmers often require a different meaning two operators are needed • Garbage collection needed since it is hard for a programmer to know if when an object is no longer referenced Typical Memory Layout Heap Stack Global variables Program Stack-based Memory Main: ObjA a = new ObjA(); ObjB b = new ObjB(); a.do(5, b) public class ObjA { int x = 100; public void do (int y, ObjB myB) { int loc = 6; int t = myB.doMore(loc); ... } public class ObjB { int z = 30; public int doMore(int i) { z = z + i; return z; } } } • Objects are stored on the heap • When a method is called, an activation record is allocated on the stack to hold: – return address (where to return after execution) – parameters – local variables (stuff declared in the method) • When a method returns, the activation record is popped