Interfaces and Inheritance ========================== 1) So far, our programs were oriented to the operations. What does this mean? - COMPUTE the primes under N. - FACTOR N into primes. - COUNT the number of vowels in the input string, etc. 2) We make a shift now, and will be programming to the data, instead of to the operations. - ASK N about the primes under it. - ASK N about its prime factors. - ASK the string to report how many vowels it contains, etc. 3) This shift started in the late 60s/early 70s, grew a lot in the 80s, and exploded in the 90s. What is the advantage of bestowing intelligence to the data? 4) What is a datatype? - A datatype contains an interface. 5) How can we specify a ADT in Java? import java.awt.Graphics; interface Shape { public void draw(Graphics g); } 6) Why this 'import' clause? 7) What is a class? - It is the implementation of a ADT: 8) Provide an implementation to the interface above. Think about how to make it into a circle. import java.awt.Graphics; public class Circle implements Shape { private int r = 0; private int x = 0; private int y = 0; public Circle(int x, int y, int r) { this.r = r; this.x = x; this.y = y; } public void draw(Graphics g) { int xuc = x - r; int yuc = y - r; g.drawOval(xuc, yuc, 2*r, 2*r); } } 8.1) What about a Rectangle? import java.awt.Graphics; public class Rectangle implements Shape { private int x = 0; private int y = 0; private int w = 0; private int h = 0; public Rectangle (int x, int y, int w, int h) { this.x = x; this.y = y; this.w = w; this.h = h; } public void draw(Graphics c) { c.drawRect(x, y, w, h); } } 9) What are these private and public's written in front of the methods? * Example of using these classes: 10) Has anyone heard of Applets? 10.1) Applets are more general than Java applets. 11) Create an applet to draw shapes in the screen. import javax.swing.JApplet; import java.awt.Graphics; import java.util.ArrayList; public class Driver extends JApplet { private static final long serialVersionUID = 1L; private ArrayList figures; public void init() { figures = new ArrayList(); Shape s1 = new Circle(20, 20, 10); figures.add(s1); Shape s3 = new Circle(30, 30, 10); figures.add(s3); Shape s4 = new Rectangle(40, 50, 10, 20); figures.add(s4); } public void paint(Graphics g) { g.drawRect(0, 0, getSize().width - 1, getSize().height - 1); for (Shape s : figures) { s.draw(g); } } } * It is possible for a class to implement many interfaces: public interface Colorable { void setColor(int r, int g, int b); } 12) Write a class Dot, that implements both Shape and Colorable. import java.awt.Color; import java.awt.Graphics; public class Dot implements Shape, Colorable { private Color color; public final static int Radius = 2; private int x; private int y; public Dot(int x, int y) { this.x = x; this.y = y; } public void setColor(int r, int g, int b) { this.color = new Color(r, g, b); } public void draw(Graphics c) { Color cr = c.getColor(); c.setColor(color); c.fillOval(x, y, Dot.Radius, Dot.Radius); c.setColor(cr); } } 13) How to deploy this applet? * To produce a distribution version, we can: a) Produce jar file: export, jar $> jar -cvf appletEx.jar *.class b) Implement HTML file: Exemplo de Applet c) open it with a browser, or appletviewer: $> appletviewer page.html * Every Circle is a Shape, so I can always use a Circle where Shape is expected. 14) How to add one method to our applet so that it will print a number of random points? import javax.swing.JApplet; import java.awt.Graphics; import java.util.ArrayList; public class Driver1 extends JApplet { private static final long serialVersionUID = 1L; private ArrayList figures; public void init() { figures = new ArrayList(); paintRandomDots(50, getSize().width - 2, getSize().height - 1); } public void paint(Graphics g) { g.drawRect(0, 0, getSize().width - 1, getSize().height - 1); for (Shape s : figures) { s.draw(g); } } public void paintRandomDots(int numPoints, int maxX, int maxY) { for (int i = 0; i < numPoints; i++) { int x = (int)(Math.random() * maxX); int y = (int)(Math.random() * maxY); Dot d = new Dot(x, y); d.setColor(0, 0, 0); figures.add(d); } } } 14.1) Would it be possible to use Colorable d = new Dot(x, y)? * Inheritance: 15) How to implement a square? 15.1) What is inheritance? * Inheritance is a mechanism to extend data. public class Square extends Rectangle { public Square(int x, int y, int s) { super(x, y, s, s); } } 16) What type of polymorphism is introduced by inheritance? 17) Does anyone remember Liskov's substitution principle? * Liskov substitution principle: Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T. 18) How does an application interact with the user? import java.awt.Graphics; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import javax.swing.JApplet; public class Driver2 extends JApplet implements MouseListener { private static final long serialVersionUID = 1L; private ArrayList figures; public void init() { figures = new ArrayList(); addMouseListener(this); } public void paint(Graphics g) { g.drawRect(0, 0, getSize().width - 1, getSize().height - 1); for (Shape s : figures) { s.draw(g); } } public void mouseClicked(MouseEvent e) { int x = e.getX(); int y = e.getY(); Dot d = new Dot(x, y); d.setColor(0, 0, 0); figures.add(d); this.repaint(); } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void mousePressed(MouseEvent e) { } } * The Type Vx the Module view: - Type view: a subclass is a subtype. - Module view: inheritance is a reuse technique. 19) What is inheritance good for? * Module view: - Reuse of code. - Addition of new features. - Renaming. - Redefinition. * Type view: - "is-a" relation. - Subseting. - Subtype polymorphism. - Dynamic binding. - Property sharing. "Inheritance leads to a style of software development which, instead of trying to solve every new problem from scratch, encourages building on previous accomplishments and extending their results." 20) The Open-Closed principle say that a module should be closed for use and open for extension. How does inheritance supports this principle? 21) How to implement the code below in C? public void paint(Graphics g) { for (Shape s : figures) { s.draw(g); } } 21.1) How the adage below relates to the code snipped above? * The shoemaker should not look beyond the sandal. - Each Shape should know how to draw itself, but not how to draw the others. - This reduces the software complexity, and facilitates extension. 22) Is inheritance specialization or extension? 22.1) How is it possible build a subset by adding new operations to elements? 22) How do I implement some extra functionality to draw rectangles? I mean, when I press the button, I mark a point, and then I drag the mouse, and when I release the mouse a rectangle appears from the mark to the release point. private int cx = 0, cy = 0; public void mousePressed(MouseEvent e) { this.cx = e.getX(); this.cy = e.getY(); } public void mouseReleased(MouseEvent e) { int newX = e.getX(); int newY = e.getY(); if (cx > newX) { int aux = cx; cx = newX; newX = aux; } if (cy > newY) { int aux = cy; cy = newY; newY = aux; } Rectangle r = new Rectangle(cx, cy, newX - cx, newY - cy); this.cx = 0; this.cy = 0; figures.add(r); repaint(); } 23) What does it mean to construct classes from the outside in? * write some code from the point of view of the caller * make the code compile by providing a simple stub implementation of the method you are designing. For a void method, such a stub is simply an empty method. For a method which has a return value, such a stub might simply return null, 0, false, or an empty String. * experimenting with different designs is simple at this point, since the amount of calling code is minimal, and the implementations are toys * correctness of method name and return type are determined by the needs of the caller * correctness of arguments seems to be determined more by the needs of the implementation, not the caller * is the return type correct? This is an important item, since changes in return type will often have large ripple effects in the caller. * is the method intelligible at the point of call? * when the design is more or less stable, write the javadoc of the method as the formal specification of the contract between the method and its callers. Often, this will also help clarify details and border cases. * finally, replace the stub implementation with a real implementation, and test it.