Java Programming Abstract classes and Interfaces.

Slides:



Advertisements
Similar presentations
JavaScript I. JavaScript is an object oriented programming language used to add interactivity to web pages. Different from Java, even though bears some.
Advertisements

CIS3023: Programming Fundamentals for CIS Majors II Summer 2010 Ganesh Viswanathan Interfaces (Part II) Course Lecture Slides 28 June 2010 A picture is.
Chapter 4 Methods F Introducing Methods –Benefits of methods, Declaring Methods, and Calling Methods F Passing Parameters –Pass by Value F Overloading.
The Point Class public class Point { public double x; public double y; public Point(double x0, double y0) { x = x0; y = y0; } public double distance(Point.
1 MATH METHODS THAT RETURN VALUES. 2 JAVA'S MATH CLASS.
Abstract Class and Interface
Inheritance // A simple class hierarchy. // A class for two-dimensional objects. class TwoDShape { double width; double height; void showDim() { System.out.println("Width.
Objects contains data and methods Class – type of object Create class first Then object or instance String – defined class String s; // creates instance.
Interfaces CSC 171 FALL 2004 LECTURE 14. Project 1 review public class Rational { private int numerator, denominator; public Rational(int numerator, int.
SUMMARY: abstract classes and interfaces 1 Make a class abstract so instances of it cannot be created. Make a method abstract so it must be overridden.
Exercise 1 Suppose C is a class that implements interfaces I and J. Which of the following Requires a type cast? C c = ……? I i = …..? J j = …..? c =
Problem Solving 5 Using Java API for Searching and Sorting Applications ICS-201 Introduction to Computing II Semester 071.
INTERFACES IN JAVA 1.Java Does not support Multiple Inheritance directly. Multiple inheritance can be achieved in java by the use of interfaces. 2.We need.
AP Computer Science TOPICS TO DISCUSS.equals() == instanceof operator compareTo Interfaces Abstract Classes.
Data Structures Lecture 2 Fang Yu Department of Management Information Systems National Chengchi University Fall 2011.
METHOD OVERRIDING Sub class can override the methods defined by the super class. Overridden Methods in the sub classes should have same name, same signature.
Chapter 7 User-Defined Methods. Chapter Objectives  Understand how methods are used in Java programming  Learn about standard (predefined) methods and.
Big Java by Cay Horstmann Copyright © 2009 by John Wiley & Sons. All rights reserved. Chapter 17 – Generic Programming.
Lecture 28: Abstract Classes & Inheritance Announcements & Review Lab 8 Due Thursday Image and color effects with 2D arrays Read: –Chapter 9 Cahoon & Davidson.
Using interfaces Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling How would you find the maximum.
Lecture 17 Abstract classes Interfaces The Comparable interface Event listeners All in chapter 10: please read it.
Java Generics.
Inheritance. 2 Inheritance allows a software developer to derive a new class from an existing one The existing class is called the parent class or superclass.
COMP 14 Introduction to Programming Miguel A. Otaduy May 25, 2004.
The UNIVERSITY of NORTH CAROLINA at CHAPEL HILL Adrian Ilie COMP 14 Introduction to Programming Adrian Ilie July 8, 2005.
Programming 2 LAB TA: Nouf Al-Harbi NoufNaief.net :::
Building Java Programs Interfaces, Comparable reading: , 16.4, 10.2.
CMSC 202 Interfaces. 11/20102 Classes and Methods When a class defines its methods as public, it describes how the class user interacts with the method.
10/7/2015IT 1791 Java’s World in UML Object Shape {abstract} This is done implicitly Shape {abstract} - ShapeName: String # setShapeName(newShapeName:
CS 106 Introduction to Computer Science I 04 / 20 / 2007 Instructor: Michael Eckmann.
* * 0 Chapter 6 Java Methods. * * 0 Method Syntax [access specifier][qualifier] return type method name(argument list) Access specifier public – method.
Recitation 4 Abstract classes, Interfaces. A Little More Geometry! Abstract Classes Shape x ____ y ____ Triangle area() base____ height ____ Circle area()
Generic abstraction  Genericity  Generic classes  Generic procedures Programming Languages 3 © 2012 David A Watt, University of Glasgow.
Hello.java Program Output 1 public class Hello { 2 public static void main( String [] args ) 3 { 4 System.out.println( “Hello!" ); 5 } // end method main.
Programming With Java ICS201 University Of Hail1 Chapter 13 Interfaces.
15440 Distributed Systems Recitation 1 Objected-Oriented Java Programming.
Copyright © 2014 by John Wiley & Sons. All rights reserved.1 Chapter 10 - Interfaces.
1 Enhanced Class Design -- Introduction  We now examine several features of class design and organization  that can improve reusability and system elegance.
U n i v e r s i t y o f H a i l 1 ICS 202  2011 spring  Data Structures and Algorithms 
Chapter 7: Class Inheritance F Superclasses and Subclasses F Keywords: super and this F Overriding methods F The Object Class F Modifiers: protected, final.
CSE 143 Lecture 20 Abstract classes. 2 Circle public class Circle { private double radius; public Circle(double radius) { this.radius = radius; } public.
Chapter 8 Class Inheritance and Interfaces F Superclasses and Subclasses  Keywords: super F Overriding methods  The Object Class  Modifiers: protected,
Java Classes Chapter 1. 2 Chapter Contents Objects and Classes Using Methods in a Java Class References and Aliases Arguments and Parameters Defining.
Side effects A side effect is anything that happens in a method other than computing and/or returning a value. Example: public class hello { public int.
ABSTRACT DATA TYPES, ABSTRACT CLASSES AND INTERFACES And abstract art….
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved COS240 O-O Languages AUBG,
CIS3023: Programming Fundamentals for CIS Majors II Summer 2010 Ganesh Viswanathan Abstract Classes Course Lecture Slides 7 June 2010 “None of the abstract.
1 Inheritance and Subclasses. 2 Inheritance Often we create very similar classes –Different types of triangles: equilateral, isosceles, etc. –Different.
CS2 Module 26 Category: OO Concepts Topic: Interfaces Objectives –Interfaces.
Creating and Using Class Methods. Definition Class Object.
1 Interfaces and Abstract Classes The ability to define the behavior of an object without specifying that behavior is to be implemented Interface class.
Interfaces, Abstract Classes, and Polymorphism. What Is an Interface? An interface is the set of public methods in a class Java provides the syntax for.
1 / 41 COP 3503 FALL 2012 SHAYAN JAVED LECTURE 5 Programming Fundamentals using Java 1.
1 Object-Oriented Programming Inheritance. 2 Superclasses and Subclasses Superclasses and Subclasses  Superclasses and subclasses Object of one class.
Day 3: The Command and Visitor Patterns. Preliminaries The Java static type system uses simple rules to infer types for Java expressions. The inferred.
Interfaces & Abstract Classes (For CS III AP) March 2014.
CSC 205 Programming II Lecture 4 Abstract Class. The abstract keyword indicate that a class is not instantiable Defining a type which will be specialized.
Abstract Classes. Recall We have the ability to create hierarchies of classes. Good design practice suggests that we move common methods as high as possible.
The AP Java Subset Topics. A Topics Primitive Types int double boolean.
Interface.
Methods Attributes Method Modifiers ‘static’
Interfaces Professor Evan Korth.
Abstract classes and Interfaces
null, true, and false are also reserved.
Introduction to Java Programming
CSE 1030: Implementing Non-Static Features
Implementing Non-Static Features
Java Lesson 36 Mr. Kalmes.
Agenda Types and identifiers Practice Assignment Keywords in Java
Presentation transcript:

Java Programming Abstract classes and Interfaces

Classes A class is composed of A class defines a data type. public class Rectangle { private double width, height; public Rectangle(double width, double height) { this.width= width; this.height=height; } public double getArea() { return width * height; } public double getPerimeter() { return 2 * (width + height); } public double getAspectRatio() { return width / height; } public class Rectangle { private double width, height; public Rectangle(double width, double height) { this.width= width; this.height=height; } public double getArea() { return width * height; } public double getPerimeter() { return 2 * (width + height); } public double getAspectRatio() { return width / height; } data methods

Clients The class (or type) of an object defines – the data that is managed by the object – the methods we can apply on the object public void processRectangle(Rectangle r) { double x1 = r.getArea(); double x2 = r.getPerimeter(); double x3 = r.getAspectRatio(); String x4 = r.toString(); boolean x5 = r.equals(“Rectangle”); } public void processRectangle(Rectangle r) { double x1 = r.getArea(); double x2 = r.getPerimeter(); double x3 = r.getAspectRatio(); String x4 = r.toString(); boolean x5 = r.equals(“Rectangle”); } public class Rectangle { private double width, height; public Rectangle(double width, double height) { this.width= width; this.height=height; } public double getArea() { return width * height; } public double getPerimeter() { return 2 * (width + height); } public double getAspectRatio() { return width / height; } public class Rectangle { private double width, height; public Rectangle(double width, double height) { this.width= width; this.height=height; } public double getArea() { return width * height; } public double getPerimeter() { return 2 * (width + height); } public double getAspectRatio() { return width / height; }

Interface An interface is a collection of method signatures – access control – return type – method name – formal parameters – exceptions An interface must be implemented to – define the method bodies – define the data

Interface example public interface Shape { public double getArea(); public double getPerimeter(); public double getAspectRatio(); } public interface Shape { public double getArea(); public double getPerimeter(); public double getAspectRatio(); } collection of method signatures public class Rectangle implements Shape { private double width, height; public Rectangle(double width, double height) { this.width= width; this.height=height; } public double getArea() { return width * height; } public double getPerimeter() { return 2 * (width + height); } public double getAspectRatio() { return width / height; } public class Rectangle implements Shape { private double width, height; public Rectangle(double width, double height) { this.width= width; this.height=height; } public double getArea() { return width * height; } public double getPerimeter() { return 2 * (width + height); } public double getAspectRatio() { return width / height; } the methods are fully defined

Interfaces An interface cannot be instantiated – Shape s = new Shape(); – Shape s = new Rectangle(30, 10); An implementation must either – define all methods OR – be labeled as abstract Implementation denotes an is-a relationship – public class Rectangle implements Shape – means that “a Rectangle is-a Shape”

Implement three Shapes Rectangle – A box with width & height Isosceles Triangle – A triangle with two equal sides Ellipse – an oval with major/minor axis widthheight width height width height

Implementation public class Rectangle implements Shape { private double width, height; public Rectangle(double width, double height) { this.width= width; this.height=height; } public double getArea() { return width * height; } public double getPerimeter() { return 2 * (width + height); } public double getAspectRatio() { return width / height; } public class Rectangle implements Shape { private double width, height; public Rectangle(double width, double height) { this.width= width; this.height=height; } public double getArea() { return width * height; } public double getPerimeter() { return 2 * (width + height); } public double getAspectRatio() { return width / height; } public interface Shape { public double getArea(); public double getPerimeter(); public double getAspectRatio(); } public interface Shape { public double getArea(); public double getPerimeter(); public double getAspectRatio(); } widthheight // Constructing and naming a rectangle Shape x = new Rectangle(10,30); // Constructing and naming a rectangle Shape x = new Rectangle(10,30);

Implementation public interface Shape { public double getArea(); public double getPerimeter(); public double getAspectRatio(); } public interface Shape { public double getArea(); public double getPerimeter(); public double getAspectRatio(); } public class IsocelesTriangle implements Shape { private double width, height; public IsocelesTriangle (double width, double height) { this.width= width; this.height=height; } public double getArea() { return width * height / 2; } public double getPerimeter() { return 2*Math.sqrt(width*width/4 + height*height) + width; } public double getAspectRatio() { return width / height; } public class IsocelesTriangle implements Shape { private double width, height; public IsocelesTriangle (double width, double height) { this.width= width; this.height=height; } public double getArea() { return width * height / 2; } public double getPerimeter() { return 2*Math.sqrt(width*width/4 + height*height) + width; } public double getAspectRatio() { return width / height; } width height // Constructing and naming a triangle Shape x = new IsocelesTriangle(10,30); // Constructing and naming a triangle Shape x = new IsocelesTriangle(10,30);

Implementation public interface Shape { public double getArea(); public double getPerimeter(); public double getAspectRatio(); } public interface Shape { public double getArea(); public double getPerimeter(); public double getAspectRatio(); } public class Ellipse implements Shape { private double width, height; public Ellipse(double width, double height) { this.width= width; this.height=height; } public double getArea() { return Math.PI * width * height / 4; } public double getPerimeter() { double a= width/2, b = height/2; double x = Math.max(a,b), y = Math.min(a,b); int digits = 53; double tolerance = Math.sqrt(Math.pow(a, digits)); double s = 0, m = 1; while(x-y>tolerance*y) { double y1 = Math.sqrt(x*y); double x1 = (x+y)/2; x = x1; y = y1; m *= 2; s += m * Math.pow(x-y,2); } return Math.PI * (Math.pow(a+b, 2)-s)/(x+y); } public double getAspectRatio() { return width / height; } public class Ellipse implements Shape { private double width, height; public Ellipse(double width, double height) { this.width= width; this.height=height; } public double getArea() { return Math.PI * width * height / 4; } public double getPerimeter() { double a= width/2, b = height/2; double x = Math.max(a,b), y = Math.min(a,b); int digits = 53; double tolerance = Math.sqrt(Math.pow(a, digits)); double s = 0, m = 1; while(x-y>tolerance*y) { double y1 = Math.sqrt(x*y); double x1 = (x+y)/2; x = x1; y = y1; m *= 2; s += m * Math.pow(x-y,2); } return Math.PI * (Math.pow(a+b, 2)-s)/(x+y); } public double getAspectRatio() { return width / height; } width height // Constructing and naming an ellipse Shape x = new Ellipse(10,30); // Constructing and naming an ellipse Shape x = new Ellipse(10,30);

Abstract Class public class Rectangle implements Shape { private double width, height; public Rectangle(double width, double height) { this.width= width; this.height=height; } public double getArea() { return width * height; } public double getPerimeter() { return 2 * (width + height); } public double getAspectRatio() { return width / height; } public class Rectangle implements Shape { private double width, height; public Rectangle(double width, double height) { this.width= width; this.height=height; } public double getArea() { return width * height; } public double getPerimeter() { return 2 * (width + height); } public double getAspectRatio() { return width / height; } public class IsocelesTriangle implements Shape { private double width, height; public IsocelesTriangle (double width, double height) { this.width= width; this.height=height; } public double getArea() { return width * height / 2; } public double getPerimeter() { return 2*Math.sqrt(width*width/4+height*height)+width; } public double getAspectRatio() { return width / height; } public class IsocelesTriangle implements Shape { private double width, height; public IsocelesTriangle (double width, double height) { this.width= width; this.height=height; } public double getArea() { return width * height / 2; } public double getPerimeter() { return 2*Math.sqrt(width*width/4+height*height)+width; } public double getAspectRatio() { return width / height; } public class Ellipse implements Shape { private double width, height; public Ellipse(double width, double height) { this.width= width; this.height=height; } public double getArea() { return Math.PI * width * height / 4; } public double getPerimeter() { double a= width/2, b = height/2; double x = Math.max(a,b), y = Math.min(a,b); int digits = 53; double tolerance = Math.sqrt(Math.pow(a, digits)); double s = 0, m = 1; while(x-y>tolerance*y) { double y1 = Math.sqrt(x*y); double x1 = (x+y)/2; x = x1; y = y1; m *= 2; s += m * Math.pow(x-y,2); } return Math.PI * (Math.pow(a+b, 2)-s)/(x+y); } public double getAspectRatio() { return width / height; } public class Ellipse implements Shape { private double width, height; public Ellipse(double width, double height) { this.width= width; this.height=height; } public double getArea() { return Math.PI * width * height / 4; } public double getPerimeter() { double a= width/2, b = height/2; double x = Math.max(a,b), y = Math.min(a,b); int digits = 53; double tolerance = Math.sqrt(Math.pow(a, digits)); double s = 0, m = 1; while(x-y>tolerance*y) { double y1 = Math.sqrt(x*y); double x1 = (x+y)/2; x = x1; y = y1; m *= 2; s += m * Math.pow(x-y,2); } return Math.PI * (Math.pow(a+b, 2)-s)/(x+y); } public double getAspectRatio() { return width / height; } Notice the similar code in these three implementations. Should aggregate into an abstract class. Notice the similar code in these three implementations. Should aggregate into an abstract class.

Abstract Class public class Rectangle extends AbstractShape { public Rectangle(double width, double height) { super(width, height); } public double getArea() { return width * height; } public double getPerimeter() { return 2 * (width + height); } public class Rectangle extends AbstractShape { public Rectangle(double width, double height) { super(width, height); } public double getArea() { return width * height; } public double getPerimeter() { return 2 * (width + height); } public class IsocelesTriangle extends AbstractShape { public IsocelesTriangle (double width, double height) { super(width,height); } public double getArea() { return width * height / 2; } public double getPerimeter() { return 2*Math.sqrt(width*width/4+height*height)+width; } public class IsocelesTriangle extends AbstractShape { public IsocelesTriangle (double width, double height) { super(width,height); } public double getArea() { return width * height / 2; } public double getPerimeter() { return 2*Math.sqrt(width*width/4+height*height)+width; } public class Ellipse extends AbstractShape { public Ellipse(double width, double height) { super(width, height); } public double getArea() { return Math.PI * width * height / 4; } public double getPerimeter() { double a= width/2, b = height/2; double x = Math.max(a,b), y = Math.min(a,b); int digits = 53; double tolerance = Math.sqrt(Math.pow(a, digits)); double s = 0, m = 1; while(x-y>tolerance*y) { double y1 = Math.sqrt(x*y); double x1 = (x+y)/2; x = x1; y = y1; m *= 2; s += m * Math.pow(x-y,2); } return Math.PI * (Math.pow(a+b, 2)-s)/(x+y); } public class Ellipse extends AbstractShape { public Ellipse(double width, double height) { super(width, height); } public double getArea() { return Math.PI * width * height / 4; } public double getPerimeter() { double a= width/2, b = height/2; double x = Math.max(a,b), y = Math.min(a,b); int digits = 53; double tolerance = Math.sqrt(Math.pow(a, digits)); double s = 0, m = 1; while(x-y>tolerance*y) { double y1 = Math.sqrt(x*y); double x1 = (x+y)/2; x = x1; y = y1; m *= 2; s += m * Math.pow(x-y,2); } return Math.PI * (Math.pow(a+b, 2)-s)/(x+y); } public abstract class AbstractShape implements Shape { protected double width, height; public AbstractShape(double width, double height) { this.width= width; this.height=height; } public double getAspectRatio() { return width / height; } public abstract class AbstractShape implements Shape { protected double width, height; public AbstractShape(double width, double height) { this.width= width; this.height=height; } public double getAspectRatio() { return width / height; }

Abstract Class An abstract class – is not completely defined – may have methods – may have data – will usually have a collection of method signatures – cannot be instantiated AbstractShape s = new AbstractShape(3, 5); AbstractShape s = new Rectangle(3, 5);

public class ShapeDriver { public static Shape getRandomShape() { double width = Math.random() * 20; double height = Math.random() * 20; int type = (int) (Math.random() * 3); switch (type) { case 0: return new Ellipse(width, height); case 1: return new IsocelesTriangle(width, height); case 2: return new Rectangle(width, height); } throw new IllegalArgumentException(); } public static double totalArea(List shapes) { double totalArea = 0; for(Shape s : shapes) { totalArea += s.getArea(); } return totalArea; } public static void main(String[] args) { List shapes = new LinkedList<>(); for (int i = 0; i < 20; i++) { shapes.add(getRandomShape()); } System.out.println(totalArea(shapes)); } public class ShapeDriver { public static Shape getRandomShape() { double width = Math.random() * 20; double height = Math.random() * 20; int type = (int) (Math.random() * 3); switch (type) { case 0: return new Ellipse(width, height); case 1: return new IsocelesTriangle(width, height); case 2: return new Rectangle(width, height); } throw new IllegalArgumentException(); } public static double totalArea(List shapes) { double totalArea = 0; for(Shape s : shapes) { totalArea += s.getArea(); } return totalArea; } public static void main(String[] args) { List shapes = new LinkedList<>(); for (int i = 0; i < 20; i++) { shapes.add(getRandomShape()); } System.out.println(totalArea(shapes)); } public interface Shape { public double getArea(); public double getPerimeter(); public double getAspectRatio(); } public interface Shape { public double getArea(); public double getPerimeter(); public double getAspectRatio(); }

Generics A generic class is a class that is parameterized over types. public class Pair { private T1 first; private T2 second; public Pair(T1 first, T2 second) { this.first = first; this.second = second; } public T1 getFirst() { return first; } public T2 getSecond() { return second; } public void setFirst(T1 first) { this.first = first; } public void setSecond(T2 second) { this.second = second; } public class Pair { private T1 first; private T2 second; public Pair(T1 first, T2 second) { this.first = first; this.second = second; } public T1 getFirst() { return first; } public T2 getSecond() { return second; } public void setFirst(T1 first) { this.first = first; } public void setSecond(T2 second) { this.second = second; } T1 and T2 are type parameters. public class PairDriver { public static void main(String[] args) { Pair p1 = new Pair<>(“Kenny”, 1); Pair p2 = new Pair<>(2, 3.5); String x1 = p1.getFirst(); Integer x2 = p1.getSecond(); Integer x3 = p2.getFirst(); Double x4 = p2.getSecond(); Pair,Pair > p3 = new Pair<>(p1, p2); ??? x5 = p3.getFirst(); ??? x6 = p3.getSecond(); } public class PairDriver { public static void main(String[] args) { Pair p1 = new Pair<>(“Kenny”, 1); Pair p2 = new Pair<>(2, 3.5); String x1 = p1.getFirst(); Integer x2 = p1.getSecond(); Integer x3 = p2.getFirst(); Double x4 = p2.getSecond(); Pair,Pair > p3 = new Pair<>(p1, p2); ??? x5 = p3.getFirst(); ??? x6 = p3.getSecond(); } Type arguments are supplied when the class is used.

Comparable & Comparator Java has two commonly used interfaces – Comparable This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class's natural ordering. The compareTo method this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. – Comparator A comparison function, which imposes a total ordering on some collection of objects. The compare method compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. public interface Comparable { public int compareTo(T e); } public interface Comparable { public int compareTo(T e); } public interface Comparator { public int compare(T e1, T e2); } public interface Comparator { public int compare(T e1, T e2); }

Example Can the AbstractShape class implement the Comparable interface? – We define the natural ordering of shapes by keying on the area. public abstract class AbstractShape implements Shape, Comparable { protected double width, height; public AbstractShape(double width, double height) { this.width = width; this.height = height; } public double getAspectRatio() { return width / height; } public int compareTo(Shape e) { double diff = getArea() – e.getArea(); if(diff < 0) { return -1; } else if(diff > 0) { return 1; } else { return 0; } public abstract class AbstractShape implements Shape, Comparable { protected double width, height; public AbstractShape(double width, double height) { this.width = width; this.height = height; } public double getAspectRatio() { return width / height; } public int compareTo(Shape e) { double diff = getArea() – e.getArea(); if(diff < 0) { return -1; } else if(diff > 0) { return 1; } else { return 0; }

Why the interface? public static AbstractShape getSmallest(AbstractShape[] shapes) { if(shapes.length == 0) throw new NoSuchElementException(); AbstractShape smallest = shapes[0]; for(int i=1; i<shapes.length; i++){ if(shapes[i].compareTo(smallest) < 0) { smallest = shapes[i]; } return smallest; } public static AbstractShape getSmallest(AbstractShape[] shapes) { if(shapes.length == 0) throw new NoSuchElementException(); AbstractShape smallest = shapes[0]; for(int i=1; i<shapes.length; i++){ if(shapes[i].compareTo(smallest) < 0) { smallest = shapes[i]; } return smallest; } public static void example() { AbstractShape[] shapes = new AbstractShape[10]; for(int i=0; i<10; i++) { shapes[i] = getRandomShape(); } AbstractShape smallest = getSmallest(shapes); } public static void example() { AbstractShape[] shapes = new AbstractShape[10]; for(int i=0; i<10; i++) { shapes[i] = getRandomShape(); } AbstractShape smallest = getSmallest(shapes); } Could write code like this. It finds the smallest shape in an array of AbstractShapes.

Why the interface? public static Comparable getSmallest(Comparable[] items) { if(items.length == 0) throw new NoSuchElementException(); Comparable smallest = items[0]; for(int i=1; i<items.length; i++){ if(items[i].compareTo(smallest) < 0) { smallest = items[i]; } return smallest; } public static Comparable getSmallest(Comparable[] items) { if(items.length == 0) throw new NoSuchElementException(); Comparable smallest = items[0]; for(int i=1; i<items.length; i++){ if(items[i].compareTo(smallest) < 0) { smallest = items[i]; } return smallest; } Better to write code like this. It finds the smallest “thing” in an array of “things”. public static void example() { AbstractShape[] shapes = new AbstractShape[10]; for(int i=0; i<10; i++) { shapes[i] = getRandomShape(); } AbstractShape smallest = getSmallest(shapes); } public static void example() { AbstractShape[] shapes = new AbstractShape[10]; for(int i=0; i<10; i++) { shapes[i] = getRandomShape(); } AbstractShape smallest = getSmallest(shapes); }

Generic Methods Methods can introduce type parameters public T randomChoice(T x1, T x2) { if(Math.random() <.5) { return x1; } else { return x2; } public T randomChoice(T x1, T x2) { if(Math.random() <.5) { return x1; } else { return x2; } Generic type parameter String s = randomChoice(“a”, “b”); Double x = randomChoice(1.0, 2.3); Integer y = randomChoice(3,5); Shape u = new Rectangle(10,30); Shape v = new Rectangle(30, 50); Shape t = randomChoice(u, v); String s = randomChoice(“a”, “b”); Double x = randomChoice(1.0, 2.3); Integer y = randomChoice(3,5); Shape u = new Rectangle(10,30); Shape v = new Rectangle(30, 50); Shape t = randomChoice(u, v);

Generic Methods Can we write a generic method to accept to elements of some type and return the smallest element? public T smallest(T x1, T x2) { if(x1 < x2) { return x1; } else { return x2; } public T smallest(T x1, T x2) { if(x1 < x2) { return x1; } else { return x2; } public T smallest(T x1, T x2) { if(x1.compareTo(x2) < 0) { return x1; } else { return x2; } public T smallest(T x1, T x2) { if(x1.compareTo(x2) < 0) { return x1; } else { return x2; } This doesn’t work since the “compareTo” method is not supported on objects that don’t implement Comparable. This doesn’t work since the “<“ operator is not supported on object types.

Generic Methods Can we write a generic method to accept elements of some type and return the smallest element? Notation to put an upper-bound on a methods generic parameter – TYPENAME extends UPPERBOUND Examples: – – > – public > T smallest(T x1, T x2) { if(x1.compareTo(x2) < 0) { return x1; } else { return x2; } public > T smallest(T x1, T x2) { if(x1.compareTo(x2) < 0) { return x1; } else { return x2; } This works since T has an “upper bound” of Comparable. This means that whatever T is, it is a sub- class of Comparable. String x1 = smallest(“a”, “b”); Integer x2 = smallest(15, 3); Double x3 = smallest(2, -18); String x1 = smallest(“a”, “b”); Integer x2 = smallest(15, 3); Double x3 = smallest(2, -18);

Generics and Subtyping Consider the following example. What are the conformance rules for generic classes? Pair p1 = new Pair (“a”, “b”); p1.setFirst(4); // IS THIS VALID? p1.setSecond(“c”); // IS THIS VALID? Pair p2 = new Pair (“a”, 3); p2.setFirst(4); // IS THIS VALID? p2.setSecond(“c”); // IS THIS VALID? p1 = p2; // IS THIS VALID? p1.setFirst(4); p1.setSecond(“c”); Pair p1 = new Pair (“a”, “b”); p1.setFirst(4); // IS THIS VALID? p1.setSecond(“c”); // IS THIS VALID? Pair p2 = new Pair (“a”, 3); p2.setFirst(4); // IS THIS VALID? p2.setSecond(“c”); // IS THIS VALID? p1 = p2; // IS THIS VALID? p1.setFirst(4); p1.setSecond(“c”);

Generics and Conformance Conformance rules – If A is a non-generic super-class of B then objects of type B conform to A Shape s = new Rectangle(10,30); Number x = new Double(3.5); – If A is a generic super-class of B, then objects of B type conform to A only if each generic parameter is an exact match. List x = new LinkedList ; List y = new LinkedList ;

Bounded Type Parameters When a method declares a parameterized type, the actual parameters must match exactly. public Object pickOne(TwoOfAKind pair) { if(Math.random() <. 5) { return pair.getFirst(); } else { return pair.getSecond(); } public Object pickOne(TwoOfAKind pair) { if(Math.random() <. 5) { return pair.getFirst(); } else { return pair.getSecond(); } public class TwoOfAKind { private T first; private T second; public TwoOfAKind (T first, T second) { this.first = first; this.second = second; } public T getFirst() { return first; } public T getSecond() { return second; } public void setFirst(T first) { this.first = first; } public void setSecond(T second) { this.second = second; } public class TwoOfAKind { private T first; private T second; public TwoOfAKind (T first, T second) { this.first = first; this.second = second; } public T getFirst() { return first; } public T getSecond() { return second; } public void setFirst(T first) { this.first = first; } public void setSecond(T second) { this.second = second; } TwoOfAKind p1 = new TwoOfAKind (“a”, “b”); TwoOfAKind p2 = new TwoOfAKind (1, ”c”); Object x = pickOne(p1); Object y = pickOne(p2); TwoOfAKind p1 = new TwoOfAKind (“a”, “b”); TwoOfAKind p2 = new TwoOfAKind (1, ”c”); Object x = pickOne(p1); Object y = pickOne(p2);

Generics and Wildcards Wildcards allow us to write truly generic functions. – ? denotes ANY TYPE public Object pickOne(TwoOfAKind pair) { if(Math.random() <. 5) { return pair.getFirst(); } else { return pair.getSecond(); } public Object pickOne(TwoOfAKind pair) { if(Math.random() <. 5) { return pair.getFirst(); } else { return pair.getSecond(); } TwoOfAKind p1 = new TwoOfAKind (“a”, “b”); TwoOfAKind p2 = new TwoOfAKind (1, ”c”); Object x = pickOne(p1); Object y = pickOne(p2); TwoOfAKind p1 = new TwoOfAKind (“a”, “b”); TwoOfAKind p2 = new TwoOfAKind (1, ”c”); Object x = pickOne(p1); Object y = pickOne(p2);

Generics and Wildcards The wildcard can be constrained. If A is the name of some class then – ? extends A the ? stands for some class that is either class A or a SUB CLASS OF A A is an upper-bound public Comparable pickOne(TwoOfAKind pair) { if(Math.random() <. 5) { return pair.getFirst(); } else { return pair.getSecond(); } public Comparable pickOne(TwoOfAKind pair) { if(Math.random() <. 5) { return pair.getFirst(); } else { return pair.getSecond(); } TwoOfAKind p1 = new TwoOfAKind (“a”, “b”); TwoOfAKind p2 = new TwoOfAKind (1, ”c”); Object x = pickOne(p1); Object y = pickOne(p2); TwoOfAKind p1 = new TwoOfAKind (“a”, “b”); TwoOfAKind p2 = new TwoOfAKind (1, ”c”); Object x = pickOne(p1); Object y = pickOne(p2);

Generics and Wildcards The wildcard can be constrained. If A is the name of some class then – ? super A the ? stands for some class that is either class A OR A SUPER CLASS OF A A is a lower-bound public Object pickOne(TwoOfAKind pair) { if(Math.random() <. 5) { return pair.getFirst(); } else { return pair.getSecond(); } public Object pickOne(TwoOfAKind pair) { if(Math.random() <. 5) { return pair.getFirst(); } else { return pair.getSecond(); } TwoOfAKind p1 = new TwoOfAKind (“a”, “b”); TwoOfAKind p2 = new TwoOfAKind (1, 3.5); Object x = pickOne(p1); Object y = pickOne(p2); TwoOfAKind p1 = new TwoOfAKind (“a”, “b”); TwoOfAKind p2 = new TwoOfAKind (1, 3.5); Object x = pickOne(p1); Object y = pickOne(p2);

Generic Interface Example public interface Function { public Y apply(X x); } public interface Function { public Y apply(X x); } public class Square implements Function { public Double apply(Double x) { return x * x; } public class Square implements Function { public Double apply(Double x) { return x * x; } public class isEven implements Function { public Boolean apply(Integer x) { return x % 2 == 0; } public class isEven implements Function { public Boolean apply(Integer x) { return x % 2 == 0; } public class Redness implements Function { public Integer apply(Color color) { return color.getRed(); } public class Redness implements Function { public Integer apply(Color color) { return color.getRed(); } The interface describes one function Each of these non-abstract classes defines that function.

Roots The root of a function f(x) is the value of x such that f(x) = 0. – A function may have multiple roots. Problem: given a continuous function f and interval [a, b], find a root in [a, b] if one exists. – Find a root of f(x) = x*x - 1 in [0, 10]. x = 1 – Find a root of f(x) = sin(x) in [-Pi,Pi]. x = -Pi, Pi, 0

Bisection method

Finding the root of a function public static double root(Function f, double a, double b, double tol) { int NMAX = 50; int n = 1; while(n <= NMAX) { double c = (a + b)/2; double fc = f.apply(c); if(fc == 0 || (b-a)/2 < tol) { return c; } n = n + 1; if(Math.signum(fc) == Math.signum(f.apply(a))) { a = c; } else { b = c; } throw new IllegalArgumentException(); } public static double root(Function f, double a, double b, double tol) { int NMAX = 50; int n = 1; while(n <= NMAX) { double c = (a + b)/2; double fc = f.apply(c); if(fc == 0 || (b-a)/2 < tol) { return c; } n = n + 1; if(Math.signum(fc) == Math.signum(f.apply(a))) { a = c; } else { b = c; } throw new IllegalArgumentException(); }

Finding the root of a function public static double squareRoot(final double value) { return root( new Function () { public Double apply(Double x) { return x * x - value; } }, 0, Math.max(value, 1), 1e-12); } public static double squareRoot(final double value) { return root( new Function () { public Double apply(Double x) { return x * x - value; } }, 0, Math.max(value, 1), 1e-12); }