187 lines
No EOL
4.9 KiB
Text
187 lines
No EOL
4.9 KiB
Text
[](https://classroom.github.com/a/x4y2o3YI)
|
|
:sectnums:
|
|
:nofooter:
|
|
:toc: left
|
|
:icons: font
|
|
:data-uri:
|
|
:stem: latexmath
|
|
:source-highlighter: highlightjs
|
|
|
|
= OOB.01 -- Pupils
|
|
|
|
Your goal is to implement a `class` which represents a pupil.
|
|
Take a look at the following _class diagram_.
|
|
|
|
[plantuml]
|
|
----
|
|
@startuml
|
|
hide empty methods
|
|
|
|
class Pupil {
|
|
{static} -int _nextId
|
|
-DateOnly _dateOfBirth [readonly]
|
|
-int? _zipCode
|
|
+Pupil(string, string, DateOnly)
|
|
+int Age [readonly]
|
|
+string FirstName [readonly]
|
|
+int Id [readonly]
|
|
+string LastName [readonly]
|
|
+int? ZipCode
|
|
|
|
+bool IsOfAge(AgeType)
|
|
+bool IsOlderThan(Pupil)
|
|
+bool LivesNearby(Pupil)
|
|
}
|
|
enum AgeType {
|
|
VotingAge,
|
|
FullAge,
|
|
RetirementAge
|
|
}
|
|
|
|
@enduml
|
|
----
|
|
|
|
We will create several _instances_ of the `Pupil` class.
|
|
With those we perform some checks and comparisons, e.g. is one person older than the other or who lives nearby.
|
|
|
|
WARNING: _This_ time you have been provided with a detailed description of all class _members_. In future assignments you'll have to rely on the class diagram and the general task description only.
|
|
|
|
== Members
|
|
|
|
[cols="2,1,1,1,1,4"]
|
|
|===
|
|
|Name |DataType |Nullable |Static |Readonly |Description
|
|
|
|
|_nextId
|
|
|int
|
|
|false
|
|
|true
|
|
|false
|
|
a|
|
|
* Shared between all instances of the class
|
|
* Supplies the next free (incremented) id
|
|
** Which is assigned in the _constructor_
|
|
|
|
|_dateOfBirth
|
|
|DateOnly
|
|
|false
|
|
|false
|
|
|true
|
|
|The date of birth of the person
|
|
|
|
|_zipCode
|
|
|int
|
|
|true
|
|
|false
|
|
|false
|
|
a|
|
|
* Backing field for the `ZipCode` property
|
|
* Could be omitted in a class diagram, because implementation detail
|
|
|
|
|Age
|
|
|int
|
|
|false
|
|
|false
|
|
|true
|
|
|A _computed_ property which returns the current age in years based on the date of birth
|
|
|
|
|FirstName
|
|
|string
|
|
|false
|
|
|false
|
|
|true
|
|
|_Getter_ for retrieving the first name of a person
|
|
|
|
|Id
|
|
|int
|
|
|false
|
|
|false
|
|
|true
|
|
|_Getter_ for retrieving the unique id of a person
|
|
|
|
|LastName
|
|
|string
|
|
|false
|
|
|false
|
|
|true
|
|
|_Getter_ for retrieving the last name of a person
|
|
|
|
|ZipCode
|
|
|int
|
|
|true
|
|
|false
|
|
|false
|
|
a|
|
|
* Property for the ZIP Code of the pupil's living address
|
|
* *Constrained to the stem:[1000 \le x \le 9999] range*
|
|
** _Ignore_ invalid values
|
|
|===
|
|
|
|
Do _not_ forget the *visibility*! Some members are private, others public.
|
|
In the diagram above private is indicated as a red square and public as a green circle.
|
|
|
|
== Operations
|
|
|
|
[cols="1,2,3,5"]
|
|
|===
|
|
|Name |Input |Output |Description
|
|
|
|
|`IsOfAge`
|
|
|A single `AgeType` value
|
|
|A flag indicating if the pupil fulfills the age requirement
|
|
a|
|
|
* Checks if the age of the pupil _instance_ is high enough to satisfy the requirement of the `AgeType` value passed as parameter
|
|
* Thresholds:
|
|
** VotingAge = 16
|
|
** FullAge = 18
|
|
** RetirementAge = 65
|
|
|
|
|`IsOlderThan`
|
|
|A single `Pupil` reference
|
|
|A flag indicating if the one pupil is older than the other
|
|
|Checks if the `Pupil` _instance_ on which the method has been called is older than the `Pupil` instance passed as parameter
|
|
|
|
|`LivesNearby`
|
|
|A single `Pupil` reference
|
|
|A flag indicating if two pupils live near each other
|
|
a|
|
|
* Compares the ZIP codes of both pupils
|
|
** One from the current instance, the other from the passed instance
|
|
* If the first two digits match they live near each other
|
|
** Examples:
|
|
*** 4060 & 4030 => live nearby
|
|
*** 4060 & 1010 => don't live nearby
|
|
** If one or both pupils don't have a ZIP set (`null`) this method returns false
|
|
|===
|
|
|
|
TIP: Make sure you understand the difference between _value_ & _reference_ parameters! +
|
|
If you aren't confident read it up again, this should be clear by now.
|
|
|
|
== Impl. Requirements for `Pupil`
|
|
|
|
You have to create and implement the `Pupil` `class` yourself.
|
|
Thus, it is not already given in the starter code.
|
|
|
|
. Create the `class` and implement it (= add members and methods) as described above
|
|
** The usual requirements for _good_ & _clean_ code apply of course
|
|
. Create unit tests to test all your _public_ methods
|
|
** At least one 'happy path' test plus the major edge cases
|
|
. Write the XMLDoc for (at least) all your public methods and properties as well as for the `class`
|
|
|
|
== `Program` & Sample Run
|
|
|
|
CAUTION: The existence of the `Pupil` `class` (e.g. constructor, properties,...) is _required_ for the business logic to execute => the application will _not_ compile until you have completed `Pupil`. +
|
|
If you want to unit test your individual parts (https://en.wikipedia.org/wiki/Test-driven_development[TDD]) you can comment out parts of `Program` to allow your solution to compile.
|
|
|
|
The main `Program` has already been provided with the starter code.
|
|
It performs the following actions:
|
|
|
|
. It creates several `Pupil` instances
|
|
. It sets (valid & invalid) ZIP codes
|
|
. It performs several age checks
|
|
. It compares the ages of some pupils
|
|
. It checks if some pupils live each other
|
|
|
|
The results are printed to the terminal and should look like this:
|
|
|
|
image::pics/sample_run.png[Sample Run] |