One Way Assignment - PowerPoint PPT Presentation

1 / 42
About This Presentation
Title:

One Way Assignment

Description:

10-1. One Way Assignment. You can assign a subclass (derived) ... The subclass has more methods than the superclass ... Devon $100.00. 10-8. Abstract classes ... – PowerPoint PPT presentation

Number of Views:75
Avg rating:3.0/5.0
Slides: 43
Provided by: rickmercer
Category:
Tags: assignment | devon | one | way

less

Transcript and Presenter's Notes

Title: One Way Assignment


1
One Way Assignment
  • You can assign a subclass (derived) to a
    superclass (base), but not the other way around
  • Object o new String() // This is okay
  • String s new Object() // Error
  • The subclass has more methods than the superclass
  • We could could send toString messages to
    instances of both objects, but odoes not know
    about toUpperCase
  • Therefore, an Object should not be treated as a
    String
  • But a String is an Object with extra methods
  • You can also pass a subclass object to a
    parameter that is a class higher up the
    inheritance hierarchy

2
Therefore, you can assign anything to an Object
object
  • public class TestObject
  • public static void main(String args)
  • Object object new Object4
  • object0 new BankAccount("Devon", 333.45)
  • object1 new TextReader()
  • object2 new Book("QA76.1", "Comp Fun",
    "Rick")
  • object3 new Borrower()
  • for(int j 0 j lt object.length j)
  • System.out.println(objectj)
  • Output
  • Devon 333.45
  • TextReader_at_f92de4bd
  • QA76.1, Comp Fun, Rick
  • Borrower_at_fb11e4bd

Can you send a withdraw message to each in the
for loop?
3
Polymorphism
  • All Objects in the preceding code extend Object
  • So what happens when you send a message to an
    object in an inheritance hierarchy?
  • The class checks if it has a method with exactly
    the same parameters -- and invokes it if it does
    have it.
  • If not, the parent class becomes responsible for
    finding the method and invoking it, this
    continues up to Object
  • This would never have begun if the method did not
    exist, Why?
  • You just saw 4 toString messages, how many
    methods executed?

4
Polymorphism
  • Polymorphism comes in several forms
  • ad-hoc polymorphism no inheritance required
  • Overloading method names println(int) or
    println(String)
  • Overload operators 32 or "3""2"
  • real polymorphism inheritance or interfaces
    required
  • the actual method called is not decided at
    compiletime
  • at runtime, the system will decide which method
    will be called
  • late binding
  • this is why we say 'send a message' rather than
    'call a function'
  • you do not always know which function (method)
    will be called

5
Casting
  • You can cast some primitive types to another
  • double aNumber 1.99
  • int anInt (int)aNumber
  • You can also cast some types of object to another
  • BankAccount anAcct (BankAccount)object0
  • Every Java reference variable knows the type of
    object it refers to, so object0 has a reference
    to a BankAccount
  • the cast was allowed, but ..

What is the value of anInt?
6
You will see class cast exceptions
  • ... you can not cast a Book into a BankAccount
  • BankAccount anAcct (BankAccount)object2
  • However, you can ask a reference variable if it
    is an instance of a particular class
  • use the keyword instanceof

java.lang.ClassCastException Book at
TestObject.main(TestObject.java11)
7
Recall previous code that sent toString messages
to all objects
  • This for loop asks every one of those object if
    it is an instance of the BankAccount class
  • BankAccount messages are only sent if it is a
    BankAccount
  • for(int j 0 j lt object.length j)
  • if(objectj instanceof BankAccount)
  • BankAccount ref (BankAccount)objectj
  • ref.withdraw(233.45)
  • System.out.println(ref)
  • Output
  • Devon 100.00

8
Abstract classes
  • If you declare an class as abstract, you can not
    instantiate it
  • makes your design clear
  • do not construct a Lendable or a Fruit
  • do construct a Book or an Apple
  • If you declare a method abstract, you must
    declare the class as abstract also
  • the abstract method heading promises descendants
    will implement the method. this makes your design
    clear
  • the compiler complain if you forget

9
Protected Access
  • Use protected to grant access to a derived class
  • can make instance variables protected so all
    descendants can access them directly - but don't
    do this
  • protected methods can be used by any object newed
    from the hierarchy

10
Preventing Inheritance
  • You can prevent anyone from extending your class
  • make the class final
  • final class Manager
  • You can prevent anyone from overriding your
    method
  • make the method final
  • final public void getDueDate()

11
Visibility rules
  • private data are not accessible from the subclass
  • can add getters and setters to the superclass
  • or make the instance variables protected
  • Subclasses can then modify/access the common data
  • public abstract class Shape extends Object
  • private Point upperLeft
  • public Shape(Point p)
  • upperLeft p
  • public Point getUpperLeftCorner()
  • return upperLeft
  • public void setUpperLeftCorner(Point p)
  • upperLeft p

12
Extend shape, add instance var, add constructor
  • public class Circle extends Shape
  • private double my_radius
  • public Circle(Point upperLeft, double radius)
  • super(upperLeft) // call Shape's constr.
  • my_radius radius

13
The Constructor and Super
  • A subclass typically defines its constructor
  • If not, you will still get a default constructor
  • zero parameters
  • it automatically calls the base class constructor
  • this constructs the base class and initializes
    the data
  • we can explicitly call the base class by writing
    super()which may also pass along arguments
  • if used, super must be the first message in the
    constructor of the derived classes
  • A derived class overrides a base class by
  • adding a method to derived with the same signature

14
Abstract classes
  • A method is either
  • invariant over the hierarchy declare it final
  • or changed by in derived class by overriding
  • rewrite method heading, do different things
    between
  • A third option Abstract methods
  • the method must be given meaning in each and
    every derived class
  • the method is declared abstract in the base
  • the listings show an abstract method

15
Abstract methods
  • Why abstract classes?
  • Because the method represents the common behavior
    of all classes in the hierarchy
  • Each class will then be required to implement
    that method.
  • When a class has one or more abstract methods, it
    is called an abstract class
  • An abstract class is never instantiated
  • Enough of the abstract, let's get concrete
  • check out this new system

16
A New SystemFind the Objects
  • Your are asked to implement a system that
    supports a small set of library operations. The
    librarian allows a student to borrow certain
    items, return those borrowed items, and pay fees.
    Late fees and due dates have been established at
    the following rates         Late
    fee                      
    Length of Borrowbooks    0.50 per
    day                          14
    days
  • videos   5.00 plus 1.50 each additional day    
    2 days CDs      2.50 per day                    
           7 daysThe due date is set
    when the borrowed item is checked out. A student
    with three (3) borrowed items, one overdue item,
    or late fees greater than 25.00 may not borrow
    anything new. This system must support undo and
    redo for book borrows, book returns, and payment
    of late fees.  The system must have a graphical
    user interface.

17
Candidate Objects
  • Object to represent the model a solution after
    eliminating some possibilities
  • Librarian
  • Student
  • Book
  • Video
  • CD
  • 3 borrowed books

18
Some of these things are similar with a few
differences
19
What do books, videos, and CD-Roms have in common?
  • Common operations and data perhaps
  • know due date
  • compute due date
  • determine late fee
  • know borrower
  • check self out
  • check self in

20
An inheritance hierarchy
The abstract class never instantiated
three concrete classes
21
Why not have just one class?
  • Some of the behavior differs
  • determine due date (2, 7, or 14 days)
  • Compute late fee
  • Data differs
  • books have ISBNs
  • videos may have a Hollywood studio name
  • Inheritance
  • allows you to share implementations
  • allows one change in a common method to affect
    all
  • Can add new lendable types later more easily

22
Up First, the abstract class
23
Designing Java Class Definitions
  • public abstract class Lendable // rough first
    draft
  • private data // Common Data
  • constructor(s) // Initialize Common Data
  • // methods common to all, make these final
  • public double getLateFee() ...
  • // add methods that each sublcass must
  • // implement differently. make these abstract

24
Some of the many things a subclass van do
  • A subclass can
  • add new methods
  • add new data fields
  • override methods defined in an ancestor
  • define its own constructor
  • call the super class constructor with super
  • call a method in the super class with
    super.message

25
Abstract methods
  • Derived classes differ setDueDate getLateFee
  • so make them Abstract, this means the derived
    classes must implement them in their own way
    more later
  • public abstract class Lendable // second draft
  • private data // TBA
  • constructor(s) // TBA
  • public double getLateFee() ...
  • public boolean isAvailable() ...
  • public void checkSelfIn() ...
  • public void checkSelfOut(String borrowerID,
  • int daysAhead) ...
  • // some subclass must implement these two
  • abstract public void checkOut()
  • abstract public double getLateFee()

26
A SubClass
  • public class Book extends Lendable
  • additional private data // TBA
  • constructor(s) // TBA
  • additional Methods // TBA
  • public Book(String CallNum, String Author,
  • String title)
  • public void checkOut()
  • // could call super.checkSelfOut(ID, 14)
  • public double getLateFee()

27
Some common data fields
  • Every class must have a DueDate
  • Add my_dueDate my_ID field to the base class
  • Since these fields should be private
  • add accessors getDueDate and getLendableID
  • BTW What do we do about a Date class?
  • Java's Date class has been deprecated
  • Use Cay's Day class
  • Use GregorianCalendar
  • Use Rick's DayCounter class
  • Make up your own Day class

28
Assume we have this DayCounter class
  • // The default constructor sets this DayCounter
    object // to represent the current date of the
    computer clock
  • public DayCounter()
  • // Use this if you want a calendar date to
    represent
  • // a past (argument is negative) or future date.
  • public void adjustDaysBy(int days)

29
Some common data fields
  • Every class in the hierarchy will have these
    instance variables of class Lendable
  • Note subclasses can not directly reference these
  • private String my_callNumber
  • private String my_title
  • private boolean my_availability
  • private String my_borrowerID
  • private DayCounter my_dueDate

30
Lendable's constructor
  • // Constructor needs a callNumber. Title was
  • // added since it seems that all Lendables will
  • // have a title of some sort. These come from
  • // the subclasses constructor.
  • public Lendable(String callNumber,
  • String initTitle)
  • my_callNumber callNumber // from subclass
  • my_title initTitle // from subclass
  • // Initialize others in a special way
  • my_borrowerID null
  • my_dueDate null
  • my_availability true

31
A few Lendable accessors
  • public String getCallNumber()
  • return my_callNumber
  • public String getTitle()
  • return my_title
  • public boolean isAvailable()
  • return my_availability
  • public DayCounter getDueDate()
  • return my_dueDate

32
Reusing DayCounterEarlier project or in the
Chapter10 folder
  • public int daysLate()
  • // return a positive of my_dueDate is before
    today
  • DayCounter today new DayCounter()
  • return my_dueDate.daysFrom(today)
  • public boolean isOverdue()
  • if(this.isAvailable())
  • return false // not even checked out
  • // Or check to see if this Lendable is overdue
  • DayCounter today new DayCounter()
  • // Return true if today is greater than
  • // the due date for this Lendable
  • return daysLate() gt 0

33
A Modifying Method in Lendable
  • public boolean checkSelfIn()
  • if(this.isAvailable())
  • // this can not be checked out
  • return false
  • else
  • // Adjust state so this is checked out
  • my_dueDate null
  • my_availability true
  • return true

34
checkSelfOut responsibility is split between
Lendable and it subclasses
  • protected // called from a subclass checkSelfOut
  • void checkOutAnyLendable(String borrowerID,
  • int borrowLength )
  • // Record who is borrowing this Lendable
  • my_borrowerID borrowerID
  • // Set the due date
  • my_dueDate new DayCounter() // today's date
  • my_dueDate.adjustDaysBy(borrowLength)
  • // Mark this as no longer available
  • my_availability false

35
Protected
  • The protected access mode means that subclasses
    inherit this method (inherit all public
    protected elements).
  • It's invoked by the subclass's checkSelfOut
    method.
  • So far, good design for the following reasons
  • subclasses can't change the private variables of
    the superclass, even though the subclass has them
  • doesn't require a bunch of setter methods in
    Lendable for subclasses to modify its own
    instance variables
  • the common behavior is in the superclass
  • the same thing is done for all subclasses
  • We'll get a polymorphic checkSelfOut message

36
Abstract methods
  • Subclasses differ setDueDate getLateFee
  • declare the appropriate methods abstract, to
    force sub-classes to implement them in their own
    appropriate ways
  • public abstract class Lendable
  • //Don't really borrow a Lendable or eat a Fruit
  • ...
  • // Subclass must implement these two methods
  • abstract public void checkSelfOut(String ID)
  • abstract public double getLateFee()
  • // Done with Lendable for now

37
The Constructor and Super
  • A subclass typically defines its constructor.
  • If not, you will still get a default constructor
  • zero parameters
  • it automatically calls the base class constructor
  • Constructors in a subclass typically call the
    superclass constructor to initialize the objects.
  • Access superclass with the keyword super
  • can pass along arguments super(callNum, title)
  • if used, super must be the first message in the
    constructor of the derived classes

38
So let's extend Lendable
  • public class Book extends Lendable
  • public static final int DAYS_TO_BORROW_BOOK
    14
  • public static final double BOOK_LATE_DAY_FEE
    0.50
  • // A new instance variable added to the 5
    inherited
  • private String my_author
  • // Can finally construct something
  • public Book(String callNumber, String title,
  • String author)
  • super(callNumber, title) // Lendable
    constructor
  • my_author author
  • public String getAuthor()
  • return my_author
  • // incomplete, but let's see if something works

39
Implement the other abstract methods to do
nothing, then these messages can call Lendable's
methods
  • import junit.framework.TestCase
  • public class TestBook extends TestCase
  • public void testGetters()
  • Book aBook new Book("QA76.1", "C", "Jo")
  • assertTrue(aBook.isAvailable())
  • assertFalse(aBook.isOverdue())
  • assertNull(aBook.getBorrowerID())
  • assertEquals("QA76.1", aBook.getCallNumber())
  • assertEquals("C", aBook.getTitle()) // C
  • assertEquals("Jo", aBook.getAuthor()) //
    Rick

40
Test Late fee
  • Book overdue
  • new Book("Q", "Overdue", "Late fee 30
    0.50")
  • overdue.checkSelfOut("Kim")
  • DayCounter dueDate new DayCounter()
  • dueDate.adjustDaysBy(Book.DAYS_TO_BORROW_BOOK)
  • assertTrue(dueDate.daysFrom(overdue.getDueDate())
    0)
  • assertFalse(overdue.isOverdue())
  • assertEquals(0.00, overdue.getLateFee(), 1e-12)
  • DayCounter thirtyDaysAgo new DayCounter()
  • thirtyDaysAgo.adjustDaysBy(-30)
  • overdue.setDueDate(thirtyDaysAgo)
  • assertTrue(overdue.isOverdue())
  • assertEquals(15.00, overdue.getLateFee(), 1e-12)

41
Complete both required methods
  • checkSelfOut delegates some work to Lendable and
    passes along the unique information borrow length
  • / Modify the state of this object so it is
    borrowed.
  • _at_param borrowerID The identification of
    borrower.
  • /
  • public void checkSelfOut(String borrowerID )
  • checkOutAnyLendable(borrowerID,
  • Book.DAYS_TO_BORROW_BOOK)

42
getLateFee differs among the different Lendables
  • public double getLateFee()
  • if(this.isAvailable()) // Not even checked out!
  • return 0.00
  • else
  • // A positive daysLate means due date has
    passed
  • int daysOverdue this.daysLate()
  • if(daysOverdue gt 0) // This Lendable is
    overdue
  • return daysOverdue Book.BOOK_LATE_DAY_FEE
  • else
  • return 0.00 // The due date is in the
    future
Write a Comment
User Comments (0)
About PowerShow.com