--- tags: hw, spr22 --- # Homework 1B (CS 17/111/112/19): Interfaces and Inheritance ### Due: Monday, February 7th, 2022 at 11:59pm ET **Collaboration Policy:** *You may collaborate as much as you want on this assignment* (this is more flexible than the normal course policy). The goal is to get everyone up to speed on functional programming. You are required to turn this in, but it will be weighted lightly in final grades. That said, we strongly encourage you to actively try writing these on your own while collaborating, as assignments after we come back together will assume you can do these sorts of problems on your own. ## Learning Objectives - practice using interfaces as types - practice sharing common fields and methods across classes - practice creating inheritance/containment diagrams to present problem designs ## Assignment Setup Using [this GitHub Classroom link](https://classroom.github.com/a/sK-pG36d), accept the assignment and clone on your machine. If you're having trouble with IntelliJ, our [First Time Setup Guide](https://hackmd.io/7azYQstzS4a6udptmaADCw) includes a common bugs/FAQ section. Please make sure to read [our Gradescope submission guide](https://hackmd.io/oTbF1IUuRs27VgVJF4z2rA) before handing in your assignment! ## [Style Expectations (Click on blue links for Soundtrack)](https://www.youtube.com/watch?v=-CmadmM5cOk) For this assignment (1B), **you should not use access modifiers for fields.** If you don’t know what they are yet, don’t worry about it. When creating fields, make sure to **name them exactly** what is given in the handout. If you do not do this, the autograder will fail. Otherwise, we expect your code to conform to the [CS200 Java Style Guide](https://hackmd.io/io7Gock2TZqC6UnBwpjP2w). # [Design Problem: Creating An Inheritance/Containment Diagram](https://www.youtube.com/watch?v=Ob7vObnFUJc&ab_channel=Beyonc%C3%A9VEVO) Inheritance/containment diagrams represent the structure of your project, including interfaces, abstract classes, and classes. Here is a [guide to the notation in these diagrams](https://docs.google.com/document/d/1Yg86xEu7WQPusArinwL-u9HtzSXFFMtTJ1FFhwfVHeE). **Task:** Answer the following questions about this diagram that we are developing in lecture: ![The inheritance-containment diagram for animals](https://i.imgur.com/ZoIe0v9.png) - Which class names can be used with the "new" keyword? - What are the fields and methods in a `FruitFly`? - What are the fields and methods in a `Shark`? - Imagine that we wanted to add a method named `likesFruit` to `IAnimal`, which returns true for all `FruitFlys` and those `Boas` whose `eats` field is `"fruit"`. Which classes would need to be edited to provide this method? **Type your answers in a block comment at the bottom of your `Homework1BTest.java` file.** ### Creating Your Own Inheritance Diagram Kathi has decided that she would like to pursue her other passion: cookies! She's just opened the "Kathi Kafé," which she'll operate on the weekends. Kathi will need baristas, waiters, and bakers. These people will be her employees. Each employee has an hourly wage. Kathi is, of course, the boss of the Kathi Kafé, so she needs to be represented as well. However, she is not an employee (she's putting all her profits back into the business). <!-- Everyone at the Kafé wears a hat. Bakers' hats are white, Kathi's is purple, and baristas and waiters' hats are blue. --> Kathi, the baristas, and the bakers need access to the supply closet. Kathi and the waiters need to be able to open the cash register. Develop an inheritance/containment diagram (on paper) for this scenario. List any fields or method names that you would define in each interface or class (as we showed for the example picture above). You can draw this on paper or with a drawing tool. Upload a png (picture) or a PDF with your diagram, named `HierarchyDiagram.png` or `HierarchyDiagram.pdf`. There's no one correct answer to this question, but there are "better designed" answers. **You are NOT writing code for this question.** # [Programming Problems](https://www.youtube.com/watch?v=MzTLMp-vh9s&ab_channel=JayZVEVO) ## [Adding Grades and TAs](https://www.youtube.com/watch?v=elueA2rofoo) In Homework 1A, we began designing a C@B-like system, and made classes to represent courses, faculty, and students. With this homework, we will add more features, such as: - Different kinds of grades - TAs (students who can also help with grading) ## Adding Grades As we build out our classes for managing courses, we will need to represent course grades. **Task:** Create a class called `GradeReport`that has three fields: `forStudent`, `forCourse` and `grade`. The constructor should take all three fields as inputs. For now, let `grade` be an `int`. In the next task, we'll learn about another way to represent grades. Grades come in one of two formats: - Letter grades can be one of `A`, `B`, `C`, `NC`. - S/NC grades are captured with two booleans: one for whether the student passed, and another for whether the student has passed with distinction. The distinction boolean should be true only if the boolean representing whether the student passed is also true. ### Enums: capture types with a few discrete values Instead of using built-in types like `String` we can use `enum` types. An `enum` is a special data type used to represent a group of **related constants**. They are types that we create. An example are the cardinal directions: North, South, East, and West. For this, we can create a `Direction` enum. To set up an `enum`, we can declare it as an `enum` rather than a class or interface. Next, declare the set of constants separated by commas. Because they are constants, enum fields should be in all `UPPER_CASE` letters. Take a look at the example below! To access the `enum` constant, use dot syntax (e.g. `Direction.UP`, `Direction.LEFT`). `Direction` num Example: ```java= public enum Direction { UP, DOWN, LEFT, RIGHT; } ``` To work with `enum`s, you can use a construct called the switch statement. Here is an example: ```java= switch (myDirection) { case UP: return "UP"; case DOWN: return "DOWN"; case LEFT: return "LEFT"; case RIGHT: return "RIGHT"; default: break; } ``` ### Creating Grade Classes **Task:** Define classes for `LetterGrade` and `SNCGrade`, with the components indicated above (each class in separate files). The constructor for `LetterGrade` should take in a `Letter` enum with constants for `A, B, C`, or `NC` and store that enum constant in its `grade` field. <!-- NOT IN SOLUTION CODE CURRENTLY: If the input is any other value (e.g. not part of the enum `Letter`), you should throw an `IllegalArgumentException` with the message `“Invalid grade”`. To compare strings, we use a method on strings called `equals`, as follows: ```=java "Kathi".equals("kathi") // this will return false ``` --> The constructor for `SNCGrade` should take in a `SNC` enum with three constants: SDIST, S, or NC. You should use this enum to set the fields `pass` and `passDistinction`. <!-- NOT IN SOLUTION CODE CURRENTLY: If the input string is any other string, you should throw an`IllegalArgumentException` with the message `“Invalid grade” --> <!-- TASK DESCRIPTION FOR STRINGS RATHER THAN ENUMS --> <!-- The constructor for `LetterGrade` should take in a string with values that are either `"A", "B", "C"`, or `"NC"` and store that string in its `grade` field. If the input string is any other string, you should throw an `IllegalArgumentException` with the message `“Invalid grade”`. To compare strings, we use a method on strings called `equals`, as follows: ```=java "Kathi".equals("kathi") // this will return false ``` <!-- The constructor for `SNCGrade` should take in a string with three possibilities: “SDIST”, “S”, or “NC”. You should use this string to set the fields `pass` and `passDistinction`. If the input string is any other string, you should throw an`IllegalArgumentException` with the message `“Invalid grade” --> --> **Task:** For each grade class, write a method `isPassing`, which takes no input and returns a boolean indicating whether the grade reflects the student having passed. For letter grades, any grade other than NC is a passing grade. <!--- **Task:** Write a `toString` method for each of `LetterGrade` and `SNCGrade`. In `SNCGrade`, the produced strings should be one of `"S"`, `"NC"`, or `"S (with distinction)"`. ---> **Task:** Define an interface `IGrade` that requires an `isPassing` method that takes no inputs and returns a `boolean`. **Task:** Change the type of `grade` in `GradeReport` from `int` to `IGrade`. ## Adding TAs In Homework 1A, we had students and faculty, but we omitted your invaluable TAs. TAs are interesting because they are students, but they have some of the same permissions that faculty do. We want to add them to our grading system. **Task:** Create a new class `TA`, in its own file. TAs should be students, but with an additional field called `assisting` that is of type `Course`. Create a constructor for the `TA` class that takes the TA's name, the two `Course`s that they are taking as students, and the `Course` that they are assisting on. TAs shouldn't be able to assist with a class they're taking, so raise a `IllegalArgumentException` with the message `"Cannot take and assist the same course"` if this is the case. **Study Question (food for thought):** Why did we make `TA` a subclass of `Student` rather than `Faculty`, given that TAs have elements of each of the other roles? TAs, like faculty, should be able to look up grades for courses on which they are assisting. **Task:** Write a method called `viewGrade` in both the `Faculty` and `TA` class that takes in a `GradeReport` and returns the grade in the report as a `String`. This method should not be available for students who are not TAs. If a Faculty member or TA tries to view a grade for a course they are not teaching/assisting throw a `RuntimeException` with the message `"Access denied"`. **Note:** To throw a `RuntimeException` in Java use the syntax: ```=java throw new RuntimeException("<error message>") ``` **Hint:** You will want to write a `toString` method for each class that represents a grade. For letter grades your `toString` method should return one of `"A"`, `"B"`, `"C"`, or `"NC"`. For S/NC grades, the method should return one of `"NC"`, `"S"`, or `"S*"` (for S with distinction). The method signature should be: ```java= @Override public String toString() ``` ## [Sharing Name Fields](https://www.youtube.com/watch?v=RSsTx2TBrww&ab_channel=JackJohnson-Topic) **Task:** At this point, each of the `Faculty`, `Student`, and `TA` classes have fields for a person's name. Create a new abstract superclass (parent class) called `Person` that shares the `name` field across these three classes. **Study Question (food for thought):** Why did we make the `Person` class abstract? What does the `abstract` annotation allow or prohibit regarding the `Person` class? ## [Testing](https://www.youtube.com/watch?v=-lJz8xdZQu4&ab_channel=BarenakedLadies%28official%29) Make sure to test your code iteratively as you work! That means writing tests for your methods *before* you write the methods. Testing and good code design make up a lot of your grade for this homework. Put your testing in the file `Homework1BTest.java`. For this and all assignments, you should test *all* of the methods that we have asked you to write. This includes testing all Exceptions mentioned in the problem statements. **Note:** When writing your test suite, you should test *only* the methods we have asked you to write in this handout. Do not reference fields or methods that are not required by the assignment in your tests, or the autograder may fail. <!--- ## Testing :::warning Testing instructions still getting cleaned up ::: Please make sure to test your code! Testing and good code design make up a lot of your grade for this homework. Put your testing in a file named `Homework1TestSuite.java`. We are autograding your test suites by running it against a series of [chaffs](https://drive.google.com/uc?export=view&id=1Rr6jxELllMUV9dJKGTWmadtfOVKm6U-N#page=6) (bad implementations) of the solution to see if your testsuite catches the bugs in those implementations. You do not need to catch every chaff. Instead, we are looking to see if your tests are covering relevant areas of the code. The chaffs are labeled with what area of the code their bug is in, and we want to see that your tests are catching at least a few chaffs in most of these areas of the code. A chaff might have an incorrect arithmetic formula, return the wrong value in an `if` statement, make an assumption about inputs (such as an arbitrary string input only getting lowercase strings), and so on (this list isn't exhaustive). Our goal in using chaffs is to help you get better at developing good sets of tests for programs. You should submit `Homework1ATestSuite.java` to the **Homework 1: Testing** assignment on Gradescope. See [our gradescope submission guide](https://hackmd.io/@cs18-spring-2021/HkESq1uJd) for an explanation on how we are grading your tests, and how you can use the Testing assignment on Gradescope to get a better understanding of the assignment. For this and all assignments, you should test *all* of the **methods** that we have asked you to write. This includes testing all `Exception`s mentioned in the problem statements (For this assignment, you do not have to include test cases for any exceptions that are thrown in the constructor of a class)! For more information on testing, see the [FAQ section of the handout](#FAQ). **Note:** When writing your test suite, you should test *only* the methods we have asked you to write in this handout. Do not reference fields or methods that are not required by the assignment in your tests, or the autograder may fail.--> ## [Handing In](https://www.youtube.com/watch?v=yQaARXcsa2U) Begin by cloning the github repository found by clicking the above github classroom link. The following files should be in the `sol` directory. You can move the files you wrote last week into this directory. We've also provided files on Canvas if would like to use our implementation. * `Course.java` containing public class `Course` * `Faculty.java` containing public class `Faculty` * `Student.java` containing public class `Student` * `Homework1BTest.java` containing public class `Homework1BTest` * `AutograderCompatibility.java` containing public class `AutograderCompatibility` After completing this assignment, you should be ready to turn in the following solution files: * `Course.java` containing public class `Course` * `Faculty.java` containing public class `Faculty` * `Student.java` containing public class `Student` * `Homework1BTest.java` containing public class `Homework1BTest` and your answers to the written questions about the `Animals` diagram. * **`Person.java`** containing public abstract class `Person` * **`TA.java`** containing public class `TA` * **`GradeReport.java`** containing public class `GradeReport` * **`IGrade.java`** containing public interface `IGrade` * **`Letter.java`** containing public enum `Letter` * **`LetterGrade.java`** containing public class `LetterGrade` * **`SNC.java`** containing public enum `SNC` * **`SNCGrade.java`** containing public class `SNCGrade` * **`HierarchyDiagram.pdf`** containing the hierarchy diagram :::info **You may also include other classes, interfaces, and abstract classes.** ::: Once you have handed in your homework, you should receive an email, more or less immediately, confirming that fact. If you don’t receive this email, try handing in again, or ask the TAs what went wrong. <!---You may have noticed a class `AutograderCompatibility`. Using this class is not required, but might help you debug if Gradescope tells you something along the lines of "The autograder failed to execute correctly." If Gradescope doesn't tell you "works with autograder" after it has finished running, try uncommenting the main method of `AutograderCompatibility` and check that it compiles and runs.--> **Note:** There should be a class in the stencil code named `AutograderCompatibility`. Using this class is required to ensure that your submission is working correctly with the autograder. You will be penalized if your code does not work with the autograder. **Note:** The initial stencil code's `AutograderCompatibility` class incorrectly had `giveGrade` methods required for this assignment. If you downloaded the stencil on Wednesday, please delete the lines of the `AutograderCompatibility` class which contain a `giveGrade` (lines 57-58). If Gradescope gives you message *“The autograder failed to execute correctly. Please ensure that your submission is valid. Contact your course staff for help in debugging this issue. Make sure to include a link to this page so that they can help you most effectively,"* uncomment the main method of `AutograderCompatibility` and check that it compiles and runs. If it still doesn't work, come to hours or post on Ed for help. ## FAQ **Do we have to test all the methods in the stencil?** No, you only need to test the methods you write. **For examples of tests, see the [Homework 1A FAQ](https://hackmd.io/xHXBAqnORz6BN7xrl-uCmQ?view#FAQ). If you have other questions, feel free to post on Ed or come to hours.** --- *Please let us know if you find any mistakes, inconsistencies, or confusing language in this or any other CS200 document by filling out the [anonymous feedback form](https://forms.gle/JipS5Y32eRUdZcSZ6)!*