/* --- CSU213 Spring 2005 Lecture Notes --------- Copyright 2005 Viera K. Proulx Lecture 2: Happy Unions */ /* Goals: - learn to design classes that represent union of data types - understand that the concepts are the same Let us return to the library catalog that contains information about books, CDs, and magazines. Books: title, author, catalog number, ... and more CDs: title, artist, number of tracks, catalog number, ... and more Magazines: title, volume or year, issue, catalog number, ... and more Let us make examples of this kind of data: book: Cat in a Hat by Dr Seuss, number 77 book: HtDP, by Matthias, number 42 cd: Thriller, with Michael Jackson, 10 tracks, number 99 cd: Pearl, by Janis Joplin, 12 tracks, number 88 magazine: Time, issue 52 in 2004, number 33 magazine: Wired, issue 3 in 2004, number 44 The data definition in HtDP would then be: A Library item is one of - (define-struct book (title author no)) where title and author are Strings and no is a Number - (define-struct cd (title artist tracks no)) where title and artist are Strings and tracks and no are Numbers - (define-struct mag (title year issue no)) where title is a String and year, issue and no are Numbers We have defined a class Book to represent the information about the books. Similarly, we can design two other classes to represent the CDs and the magazines. The three class diagram would be: +---------------+ +---------------+ +--------------+ | Book | | CD | | Magazine | +---------------+ +---------------+ +--------------+ | String title | | String title | | String title | | String author | | String artist | | int year | | int no | | int tracks | | int issue | +---------------+ | int no | | int no | +---------------+ +--------------+ and the definition of the Java classes follows immediately. However, we would like to be able to express the relationship between these classes, so that we can talk about library items as types of data. To do this, we define a union of the three classes, represented by the following diagram: +----------+ | ALibItem | +----------+ +----------+ / \ --- | ------------------------------------------ | | | +---------------+ +---------------+ +--------------+ | Book | | CD | | Magazine | +---------------+ +---------------+ +--------------+ | String title | | String title | | String title | | String author | | String artist | | int year | | int no | | int tracks | | int issue | +---------------+ | int no | | int no | +---------------+ +--------------+ The arrow connecting the three classes to the top one is a union arrow, or 'inheritance' arrow. The class ALibItem is a super class, the three classes below are its subclasses. We have examples of objects that belong to these three classes, but we cannot make examples of 'ALibItem' - the class just defines a common type for its subclasses. To make this clear, we have to define the class ALibItem as 'abstract' class. It has no constructor - of course! The other three classes define their relationship to the super class by indicating that they 'extend' the super class: */ // to represent library items abstract class ALibItem { } // to represent a book class Book extends ALibItem { String title; String author; int no; Book(String title, String author, int no) { this.title = title; this.author = author; this.no = no; } } // to represent a CD class CD extends ALibItem { String title; String artist; int tracks; int no; CD(String title, String artist, int tracks, int no) { this.title = title; this.artist = artist; this.tracks = tracks; this.no = no; } } // to represent a magazine class Magazine extends ALibItem { String title; int year; int issue; int no; Magazine(String title, int year, int issue, int no) { this.title = title; this.year = year; this.issue = issue; this.no = no; } } /* The examples of books then are defined as follows: Book ch = new Book("Cat in a Hat", "Dr Seuss", 77); Book htdp = new Book("HtDP", "Matthias F", 42); CD thriller = new CD("Thriller", "Michael Jackson", 10, 99); CD pearl = new CD("Pearl", "Janis Joplin", 12, 88); Magazine time = new Magazine("Time", 2004, 52, 33); Magazine wired = new Magazine("Wired", 2004, 3, 44); */ /* Part 2: Common Data We notice that every subclass of the class ALibItem contains a title and a catalog number. If we think about any other library items we may want to represent later, such as maps, video tapes, DVDs, they will also have a title and a catalog number. Because these fields are common to all subclasses, we can enforce this by 'lifting' the fields to the abstract class. it will still be an abstract class, as a title and a catalog number does not provide all the information we need to know about a library item. the same book may be available as a book on tape, and in printed version, Sound of Music may be an audio CD, a DVD, and a music score of the songs. However, by moving the field definitions into a super class, we make sure that every class that extends the abstract class ALibItem will contain at least these two fields. The new class definitions are: */ /* +--------------+ | ALibItem | +--------------+ | String title | | int no | +--------------+ / \ --- | ----------------------------------------- | | | +---------------+ +---------------+ +-----------+ | Book | | CD | | Magazine | +---------------+ +---------------+ +-----------+ | String author | | String artist | | int year | +---------------+ | int tracks | | int issue | +---------------+ +-----------+ */ // to represent a library item abstract class ALibItem { String title; int no; } // to represent a book class Book extends ALibItem { String author; Book(String title, int no, String author) { this.title = title; this.no = no; this.author = author; } } // to represent a CD class CD extends ALibItem { String artist; int tracks; CD(String title, int no, String artist, int tracks) { this.title = title; this.no = no; this.artist = artist; this.tracks = tracks; } } // to represent a magazine class Magazine extends ALibItem { int year; int issue; Magazine(String title, int no, int year, int issue) { this.title = title; this.no = no; this.year = year; this.issue = issue; } } /* Notice that we had to change the order in which the fields appear in the constructor. This is not a requirement in Java, but we will always do it. The examples will have to be then modified as follows: Book ch = new Book("Cat in a Hat", 77, "Dr Seuss"); Book htdp = new Book("HtDP", 42, "Matthias F"); CD thriller = new CD("Thriller", 99, "Michael Jackson", 10); CD pearl = new CD("Pearl", 88, "Janis Joplin", 12); Magazine time = new Magazine("Time", 33, 2004, 52); Magazine wired = new Magazine("Wired", 44, 2004, 3); */