// TSRJ 2008 - Advanced // Lecture 3: Data Definitions - Part 3 // Union Types in Java // ------------------- // // Representing Animals // -------------------- // // Lets try to define three kinds of animals, bears, snakes and spiders. // // In Java: // -------- // // +-----------------+ // | Bear | // |-----------------| // |String name | // |String eats | // |int weight | // +-----------------+ // // // +-----------------+ // | Snake | // |-----------------| // |String name | // |int length | // |boolean poisonous| // +-----------------+ // // // +-----------------+ // | Spider | // |-----------------| // |String name | // |int legs | // |boolean poisonous| // +-----------------+ /* ;; In Scheme: ;; ---------- ;; ;; A Bear is (make-bear String String Number) ;; interpretation: (make-bear n f w) creates a bear with ;; n as the name of the bear ;; f as the food the bear eats ;; w as the weight of the bear (define-struct bear (name eats weight)) ;; Examples: ;; --------- (make-bear "Bob" "apples" 1200) ;; ;; A Snake is (make-snake String Number Boolean) ;; interpretation: (make-snake n l p) creates a snake with ;; n as the name of the snake ;; l as the length of the snake ;; p indicates if the snake is poisonous (true) ;; and non-poisonous (false) (define-struct snake (name length poisonous?)) ;; Examples: ;; --------- (make-snake "Cobra" 12 true) ;; ;; A Spider is (make-spider String Number Boolean) ;; interpretation: (make-spider n l p) creates a spider with ;; n as the name of the spider ;; l as the number of legs ;; p indicates if the spider is poisonous (true) ;; and non-poisonous (false) (define-struct spider (name legs poisonous?)) ;; Examples: ;; --------- (make-spider "Spidy" 7 false) ;; We know that the above three data-definitions are animals. So in scheme ;; we can define Animal as a union, e.g. ;; ;; An Animal is one of ;; -- Bear ;; -- Snake ;; -- Spider ;; ;; How can we define unions in Java? */ // // +---------+ // | Animals | // +---------+ // +---------+ // | // / \ // --- // | // ------------------------------------------------ // | | | // +-------------+ +-------------------+ +-------------------+ // | Bear | | Snake | | Spider | // +-------------+ +-------------------+ +-------------------+ // | String name | | String name | | String name | // | String eats | | int length | | int legs | // | int weight | | boolean poisonous | | boolean poisonous | // +-------------+ +-------------------+ +-------------------+ // // // // At this point, every piece of data (object) has two related properties. // An object is an instance of a class of data. But several classes of data // can implement a common 'type' of data. And therefore, we now have a new // way of describing data - by identifing the its type. // // The class diagram translates to the following Java code. // to represent Animals in a Zoo interface Animals { } // to represent Bears class Bear implements Animals { String name; String eats; int weight; Bear(String name, String eats, int weight) { this.name = name; this.eats = eats; this.weight = weight; } } // to represent Snakes class Snake implements Animals { String name; int length; boolean poisonous; Snake(String name, int length, boolean poisonous) { this.name = name; this.length = length; this.poisonous = poisonous; } } // to represent Spiders class Spider implements Animals { String name; int legs; boolean poisonous; Spider(String name, int legs, boolean poisonous) { this.name = name; this.legs = legs; this.poisonous = poisonous; } } // Examples // -------- class ExamplesAnimals{ ExamplesAnimals() {} Animals bob = new Bear("Animal","Apples",1200); Animals cobra = new Snake("Cobra",12,true); Animals spidy = new Spider("Spidy",7,false); } // Note that bob, cobra and spidy are all objects of the type Animals. // We can refer to objects that are instances of classes Bear, Snake and Spider // with a name that represents a data of the type Animals. // Representing Items in a Library // ------------------------------- // // A Library Item is one of // // -- Book // -- Magazine // -- CD // // // // +---------+ // | LibItem | // +---------+ // +---------+ // | // / \ // --- // | // ----------------------------------------- // | | | // +---------------+ +--------------+ +--------------+ // | Book | | Magazine | | CD | // +---------------+ +--------------+ +--------------+ // | String title | | String title | | String title | // | String author | | int year | | String type | // | int catNo | | int month | | int catNo | // +---------------+ | int catNo | +--------------+ // +--------------+ // // // // represent items in a library interface LibItem { } // to represent Books class Book implements LibItem { String title; String author; int catNo; Book(String title, String author, int catNo) { this.title = title; this.author = author; this.catNo = catNo; } } // to represent Magazines class Magazine implements LibItem { String title; int year; int month; int catNo; Magazine(String title, int year, int month, int catNo) { this.title = title; this.year = year; this.month = month; this.catNo = catNo; } } // to represent CDs class CD implements LibItem { String title; String type; int catNo; CD(String title, String type, int catNo) { this.title = title; this.type = type; this.catNo = catNo; } } // Examples: // --------- class ExamplesLibItem { ExamplesLibItem() {} LibItem bookPL = new Book("Paradise Lost", "Milton", 1); LibItem magazineNME = new Magazine("NME", 2006, 10, 2); LibItem cdAftermath = new CD("Aftermath", "Rock", 3); } // How about lists? Recall from Scheme the data definition of lists /* ;; A [Listof Animals] (LoA) is one of ;; -- empty ;; -- (cons Animals [Listof Animals] (LoA */ // We have seen how to create unions and containement in Java ... // // // // +-----+ // | LoA |<----------------+ // +-----+ | // +-----+ | // | | // / \ | // --- | // | | // -------------------- | // | | | // +----------+ +---------------+ | // | EmptyLoA | | ConsLoA | | // +----------+ +---------------+ | // +----------+ | Animals first | | // | LoA rest |----+ // +---------------+ // // // to represent lists of Animals LoA interface LoA { } // to represent an Empty LoA class EmptyLoA implements LoA { EmptyLoA() { } } // to represent a list as an Animal prepended to an LoA class ConsLoA implements LoA { Animals first; LoA rest; ConsLoA(Animals first, LoA rest) { this.first = first; this.rest = rest; } } // Examples: // -------- class ExamplesLoA { ExamplesLoA() {} Animals bob = new Bear("Animal","Apples",1200); Animals cobra = new Snake("Cobra",12,true); Animals spidy = new Spider("Spidy",7,false); LoA empty = new EmptyLoA(); LoA oneAnimal = new ConsLoA(this.bob, this.empty); LoA oneAnimalAgain = new ConsLoA(this.bob, new EmptyLoA()); LoA oneOfEach = new ConsLoA(this.bob, new ConsLoA(this.cobra, new ConsLoA(this.spidy, this.empty))); } // Lets also define lists of library items /* ;; Recall from Scheme ;; ;; A [Listof LibItem] (LoLI) is one of ;; -- empty ;; -- (cons LibItem [Listof LibItem]) */ // // +------+ // | LoLI |<----------------+ // +------+ | // +------+ | // | | // / \ | // --- | // | | // -------------------- | // | | | // +-----------+ +---------------+ | // | EmptyLoLI | | ConsLoLI | | // +-----------+ +---------------+ | // +-----------+ | LibItem first | | // | LoLI rest |-+ | // +---------------+ | | // | | // +--+ // // // // to represent lists of LibItems interface LoLI { } // to represent the empty library item list class EmptyLoLI implements LoLI { EmptyLoLI() { } } // to represent a list as a LibItem prepended on a LoLI class ConsLoLI implements LoLI { LibItem first; LoLI rest; ConsLoLI(LibItem first, LoLI rest) { this.first = first; this.rest = rest; } } // Examples: // --------- class Examples { Examples() {} LibItem bookPL = new Book("Paradise Lost", "Milton", 1); LibItem magazineNME = new Magazine("NME", 2006, 10, 2); LibItem cdAftermath = new CD("Aftermath", "Rock", 3); LoLI emptyLoLI = new EmptyLoLI(); LoLI oneBook = new ConsLoLI(this.bookPL, this.emptyLoLI); LoLI oneOfEach = new ConsLoLI(this.bookPL,new ConsLoLI(this.magazineNME, new ConsLoLI(this.cdAftermath, this.emptyLoLI))); } // Pictures Example // ---------------- // // Given the following data-definitions and scheme code can you translate it // into Java? /* ;; A Picture is one of ;; -- Circle ;; -- Rectangle ;; -- Combo ;; A Circle is (make-circle Posn Number) ;; interpretation: (make-circle p r) creates a circle with ;; p as the center point of the circle ;; r the radius of the circle (define-struct circle (pos radius)) ;; Example ;; ------- (make-circle (make-posn 1 1) 4) ;; A Rectangle is (make-rectangle Posn Number Number) ;; interpretation: (make-rectangle p w h) creates a rectangle with ;; p as the position of the top left hand corner of the rectangle ;; w the width of the rectangle ;; h the height of the rectangle (define-struct rectangle (pos width height)) ;; Example ;; ------- (make-rectangle (make-posn 2 2) 4 5) ;; A Combo is (make-combo Picture Picture) ;; interpretation: (make-combo p1 p2) creates a combo with ;; p1 as the top image in the combo ;; p2 as the bottom image in the combo (define-struct combo (pic1 pic2)) ;; Example ;; ------- (make-combo (make-rectangle (make-posn 2 2) 4 5) (make-circle (make-posn 1 1) 4)) */