# University of Washington, CSE 142

## Lab 9: Inheritance

Except where otherwise noted, the contents of this document are Copyright 2011 Stuart Reges and Marty Stepp.

lab document created by Marty Stepp, Stuart Reges, and Whitaker Brand

# Basic lab instructions

• We encourage you to talk to your classmates for help. You can even work on the lab with a partner if you like.
• You may want to bring your textbook to future labs to look up syntax and examples.
• Stuck? Confused? Have a question? Ask a TA for help, or look at the book or past lecture slides.
• You probably won't finish all of the exercises. Just do as much as you can within the allotted time. You don't need to keep working on these exercises after you leave the lab.
• Before you leave today, make sure to check in with one of the TAs in the lab to get credit for your work.

# Today's lab

Goals for today:

• get more practice with classes and object-oriented programming
• use inheritance to create hierarchies of related classes
• extend behavior and override existing behavior
• Where you see this icon, you can click it to check the problem in Practice-It! # ClockTime class

Suppose you are given a class named `ClockTime` with the following contents:

```// A ClockTime object represents an hour:minute time during
// the day or night, such as 10:45 AM or 6:27 PM.
public class ClockTime {
private int hour;
private int minute;
private String amPm;

// Constructs a new time for the given hour/minute
public ClockTime(int h, int m, String ap)

// returns the field values
public int getHour()
public int getMinute()
public String getAmPm()

// returns a String for this time; for example, "6:27 PM"
public String toString()

...
}
```

# Exercise : ClockTime advance • Write an instance method `advance` that will be placed inside the `ClockTime` class. The method accepts a number of minutes as its parameter and moves your object forward in time by that amount of minutes. The minutes passed could be any non-negative number, even a large number such as 500 or 1000000. If necessary, your object might wrap into the next hour or day, or it might wrap from the morning ("AM") to the evening ("PM") or vice versa. (A ClockTime object doesn't care about what day it is; if you advance by 1 minute from 11:59 PM, it becomes 12:00 AM.)
• For example, the following calls would produce the following results:
```ClockTime time = new ClockTime(6, 27, "PM");
time.advance(1440);    //  1:11 AM  (1 day later)
time.advance(21075);   //  4:26 PM  (2 weeks later)
```
• Test your solution to this problem in Practice-It.

# Exercise : ClockTime isWorkTime • Write an instance method `isWorkTime` that will be placed inside the `ClockTime` class. The method returns `true` if the object is a time during the "work day" from 9:00 AM - 5:00 PM inclusive; otherwise `false`.
• The following objects would return the following results if the method were called:
```ClockTime t0 = new ClockTime(12, 45, "AM");   // false
ClockTime t1 = new ClockTime( 6, 02, "AM");   // false
ClockTime t2 = new ClockTime( 8, 59, "AM");   // false
ClockTime t3 = new ClockTime( 9, 00, "AM");   // true
ClockTime t4 = new ClockTime(11, 38, "AM");   // true
ClockTime t5 = new ClockTime(12, 53, "PM");   // true
ClockTime t6 = new ClockTime( 3, 15, "PM");   // true
ClockTime t7 = new ClockTime( 4, 59, "PM");   // true
ClockTime t8 = new ClockTime( 5, 00, "PM");   // true
ClockTime t9 = new ClockTime( 5, 01, "PM");   // false
ClockTime ta = new ClockTime( 8, 30, "PM");   // false
ClockTime tb = new ClockTime(11, 59, "PM");   // false
```
• Test your solution to this problem in Practice-It.

# Rectangle class

Suppose you are given a class named `Rectangle` with the following contents:

```// A Rectangle stores an (x, y) coordinate of its top/left corner, a width and height.
public class Rectangle {
private int x;
private int y;
private int width;
private int height;

// constructs a new Rectangle with the given x,y, width, and height
public Rectangle(int x, int y, int w, int h)

// returns the fields' values
public int getX()
public int getY()
public int getWidth()
public int getHeight()

// returns a string such as {(5,12), 4x8}
public String toString()

...
}
```

# Exercise : Rectangle union • Write an instance method `union` that will be placed inside the `Rectangle` class. The method accepts another rectangle r as a parameter and turns the current rectangle into the union of itself and r; that is, modifies the fields so that they represent the smallest rectangular region that completely contains both this rectangle and r.
• For example, the following calls would produce the following rectangles:
```Rectangle rect1 = new Rectangle(5, 12, 4, 6);
Rectangle rect2 = new Rectangle(6,  8, 5, 7);
Rectangle rect3 = new Rectangle(14, 9, 3, 3);
Rectangle rect4 = new Rectangle(10, 3, 5, 8);

rect1.union(rect2);   // {(5, 8), 6x10}
rect4.union(rect3);   // {(10, 3), 7x9}
```
• Test your solution to this problem in Practice-It.

# Exercise : Rectangle contains • Write an instance method `contains` that will be placed inside the `Rectangle` class. The method accepts integers for x and y as parameters and turns `true` if that x/y coordinate lies within this rectangle. The edges are included; for example, a rectangle with x=2, y=5, width=8, height=10 will return `true` for any point from (2, 5) through (10, 15) inclusive.
• Test your solution to this problem in Practice-It.

# Inheritance (syntax)

```public class ClassName extends SuperClass {
...
}
```
• a subclass inherits all of the superclass's behavior and can override methods.
• To call an overridden method from the superclass, use the `super` keyword:
```super.methodName(parameters);
```

# Exercise : `Car` and `Truck` ```public class Car { public void m1() { System.out.println("car 1"); } public void m2() { System.out.println("car 2"); } public String toString() { return "vroom"; } } ``` ```public class Truck extends Car { public void m1() { System.out.println("truck 1"); } } ```
• What is the output from the following code?
```Truck mycar = new Truck();
System.out.println(mycar);    // vroom
mycar.m1();                   // truck 1
mycar.m2();                   // car 2
```

# Exercise : `Car` and `Truck` revisited ```public class Car { public void m1() { System.out.println("car 1"); } public void m2() { System.out.println("car 2"); } public String toString() { return "vroom"; } } ``` ```public class Truck extends Car { public void m1() { System.out.println("truck 1"); } public void m2() { super.m1(); } public String toString() { return super.toString() + super.toString(); } } ```
• Suppose the `Truck` code changes as shown above. What is the output now?
```Truck mycar = new Truck();
System.out.println(mycar);    // vroomvroom
mycar.m1();                   // truck 1
mycar.m2();                   // car 1
```

# Exercise : `MonsterTruck` • Download the following files from the previous exercise and open them in jGRASP:
• Write a class `MonsterTruck` that has the behavior below. Test by running `AutoMain`.
• Some methods produce 2 lines of output; the split between lines is indicated by a `/`.
• Don't just print/return the output; if possible, use inheritance to reuse behavior from the superclass.
```MonsterTruck bigfoot = new MonsterTruck();
bigfoot.m1();                  // monster 1
bigfoot.m2();                  // truck 1 / car 1
System.out.println(bigfoot);   // monster vroomvroom
```

# Exercise : `Marketer` • Write an employee class `Marketer` to accompany the other employees. Marketers make \$50,000 (\$10,000 more than general employees), and they have an additional method named `advertise` that prints `"Act now, while supplies last!"`
• Use the `super` keyword to interact with the `Employee` superclass as appropriate.

# Exercise : `Janitor` • Write an employee class `Janitor` to accompany the other employees. Janitors work twice as many hours (80 hours/week), they make \$30,000 (\$10,000 less than others), they get half as much vacation (only 5 days), and they have an additional method named `clean` that prints "Workin' for the man."
• Use the `super` keyword to interact with the `Employee` superclass as appropriate.

# Exercise : `HarvardLawyer` • Write an employee class `HarvardLawyer` to accompany the other employees. Harvard lawyers are like normal lawyers, but they make 20% more money than a normal lawyer, they get 3 days more vacation, and they have to fill out four of the lawyer's forms to go on vacation. That is, the `getVacationForm` method should return `"pinkpinkpinkpink"`.
• (If the normal `Lawyer`'s vacation form ever changed, the `HarvardLawyer`'s should as well. For example, if `Lawyer`'s vacation form changed to `"red"`, the `HarvardLawyer`'s should return `"redredredred"`.)
• Use the `super` keyword to interact with the `Employee` superclass as appropriate.

# Point class

Suppose you are given a class named `Point` with the following contents:

```// A Point represents a 2-D (x, y) position with integer coordinates.
public class Point {
private int x;
private int y;

public Point()                          // (0, 0)
public Point(int x, int y)

public int getX()                       // return field values
public int getY()
public double distanceFromOrigin()      // distance from (0, 0)
public double distance(Point other)     // distance from another point
public void setLocation(int x, int y)   // set x/y to the given values
public void translate(int dx, int dy)   // shift x/y by the given amounts
public String toString()                // string e.g. "(4, -7)"
```

# Exercise : `manhattanDistance` Add the following method to the `Point` class:

```public int manhattanDistance(Point other)
```

Returns the "Manhattan distance" between the current `Point` object and the given other `Point` object. The Manhattan distance refers to how far apart two places are if the person can only travel straight horizontally or vertically, as though driving on the streets of Manhattan. In our case, the Manhattan distance is the sum of the absolute values of the differences in their coordinates; in other words, the difference in x plus the difference in y between the points.

Click on the check-mark above to try out your solution in Practice-it! (Write just the new method, not the entire `Point` class.)

# Exercise : `flip` Add the following method to the `Point` class:

```public void flip()
```

Negates and swaps the x/y coordinates of the `Point` object. For example, if an object `pt` initially represents the point (5, -3), after a call of `pt.flip();` , the object should represent (3, -5). If the same object initially represents the point (4, 17), after a call to `pt.flip();`, the object should represent (-17, -4).

Test your code in Practice-It! or by running the `PointMain` program.

# Exercise : `quadrant` Add the following method to the `Point` class:

```public int quadrant()
```

Returns which quadrant of the x/y plane this `Point` object falls in. Quadrant 1 contains all points whose x and y values are both positive. Quadrant 2 contains all points with negative x but positive y. Quadrant 3 contains all points with negative x and y values. Quadrant 4 contains all points with positive x but negative y. If the point lies directly on the x and/or y axis, return 0.

(Test your code in Practice-It! or by running the `PointMain` program.)

# BankAccount class

Suppose you are given a class named `BankAccount` with the following contents:

```// A BankAccount keeps track of a user's money balance and ID,
// and counts how many transactions (deposits/withdrawals) are made.
public class BankAccount {
private String id;
private double balance;
private int transactions;

// Constructs an object with the given id/balance and 0 transactions.
public BankAccount(String id, double balance)

public double getBalance()
public String getID()
public String getTransactions()

// Adds amount to balance if between 0-500. Also counts as 1 transaction.
public void deposit(double amount)

// Subtracts amount from balance if user has enough money. Counts as 1 transaction.
public void withdraw(double amount)

...
}
```

# Exercise : BankAccount transactionFee • Write a method `transactionFee` to go in the `BankAccount` class. It takes a fee (real number) parameter and applies the fee to all past transactions. The fee is applied once for the first transaction, 2x for the second, 3x for the third, etc. These fees are subtracted from the account's balance.
• If the balance is large enough to afford all fees with > \$0.00 remaining, the method returns `true`. If not, the balance is 0.0 and it returns `false`. For example:
```BankAccount savings = new BankAccount("Jimmy", 0.00);
savings.deposit(10.00);
savings.deposit(50.00);
savings.deposit(10.00);
savings.deposit(70.00);         // balance = \$140, with 4 transactions

savings.transactionFee(5.00);   // deducts  \$5+10+15+20; balance = \$90; returns true
savings.transactionFee(10.00);  // deducts \$10+20+30+40; balance =  \$0; returns false
```

# Exercise : BankAccount transfer • Write an instance method `transfer` that moves money from this bank account to another account. The method takes two parameters: a `BankAccount` to accept money, and a real number for the amount to transfer. There is a \$5.00 fee for transferring, to be deducted from the current account's balance.
• The method should modify the two objects such that "this" has its balance decreased by the given amount plus \$5 fee, and the other's balance is increased by the given amount. A transfer also counts as a transaction on both accounts. If this account object does not have enough money to make the full transfer, transfer whatever money is left after the \$5 fee is deducted. If this account has under \$5 or the amount is 0 or less, no transfer should occur and neither account's state should be modified.
• For example, the following calls would produce the following results:
```BankAccount ben = new BankAccount("Benson", 90.00);
BankAccount mar = new BankAccount("Marty",  25.00);
ben.transfer(mar, 20.00);     // ben \$65, mar \$45   (ben loses \$25, mar gains \$20)
ben.transfer(mar, 10.00);     // ben \$50, mar \$55   (ben loses \$15, mar gains \$10)
ben.transfer(mar, -1);        // ben \$50, mar \$55   (no effect; negative amount)
mar.transfer(ben, 39.00);     // ben \$89, mar \$11   (mar loses \$44, ben gains \$39)
mar.transfer(ben, 50.00);     // ben \$95, mar \$ 0   (mar loses \$11, ben gains \$ 6)
mar.transfer(ben,  1.00);     // ben \$95, mar \$ 0   (no effect; no money in account)
ben.transfer(mar, 88.00);     // ben \$ 2, mar \$88   (ben loses \$93, mar gains \$88)
ben.transfer(mar,  1.00);     // ben \$ 2, mar \$88   (no effect; can't afford fee)
```

# Exercise : `TimeSpan` Define a class named `TimeSpan`. A `TimeSpan` object stores a span of time in hours and minutes (for example, the time span between 8:00am and 10:30am is 2 hours, 30 minutes). The minutes should always be reported as being in the range of 0 to 59. That means that you may have to "carry" 60 minutes into a full hour.

To solve this problem, you may want to refer to the lecture slides about the syntax for constructors.

See the Practice-It link above for a full description of the class and the methods/constructors it should have.

# Exercise : `Circle` Define a class named `Circle`. A `Circle` object stores a center point and a radius.

See the Practice-It link above for a full description of the class and the methods/constructors it should have. You can also test your class in Practice-It.

# If you finish them all...

If you finish all the exercises, try out our Practice-It web tool. It lets you solve Java problems from our Building Java Programs textbook.

You can view an exercise, type a solution, and submit it to see if you have solved it correctly.

Choose some problems from the book and try to solve them!
{"ft_lang_label":"__label__en","ft_lang_prob":0.74561185,"math_prob":0.7805994,"size":12222,"snap":"2022-27-2022-33","text_gpt3_token_len":3206,"char_repetition_ratio":0.13079064,"word_repetition_ratio":0.121791646,"special_character_ratio":0.28710523,"punctuation_ratio":0.177589,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.95595133,"pos_list":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"im_url_duplicate_count":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2022-08-18T04:56:52Z\",\"WARC-Record-ID\":\"<urn:uuid:e540e891-2104-4ad0-91f1-77b56ea2fbd1>\",\"Content-Length\":\"34875\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:9f30ce2e-1e44-49bf-9efb-7b9ee3cd08e4>\",\"WARC-Concurrent-To\":\"<urn:uuid:8f8293f3-6ca2-4fa1-89af-d674603b998f>\",\"WARC-IP-Address\":\"128.208.1.193\",\"WARC-Target-URI\":\"https://courses.cs.washington.edu/courses/cse142/11au/labs/lab9-inheritance.shtml\",\"WARC-Payload-Digest\":\"sha1:XBHUL3IFHMD22BC235RNS6RBXM3Y3IW4\",\"WARC-Block-Digest\":\"sha1:SAX2ITC2GRAJICZCGUEFAXVLIX443B36\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2022/CC-MAIN-2022-33/CC-MAIN-2022-33_segments_1659882573163.7_warc_CC-MAIN-20220818033705-20220818063705-00070.warc.gz\"}"}