1+ public class Room {
2+ private Owner owner ;
3+ // | | | These are all arbitrary names, and are picked solely for
4+ // | | | convenience. Good code must be maintainable, maintainable
5+ // | | | code should make sense. Calling this
6+ // | | | private Human who;
7+ // | | | would make no difference for the machine, but it would for me.
8+ // | | In C++, this would be a pointer* to the Owner object in the heap,
9+ // | | but Java runs on a Virtual Machine, so having a pointer to a location
10+ // | | in memory is unnecessary, so Java uses what they call "references",
11+ // | | which are different from C++ "references" in that
12+ // | private allows me to impose certain access restrictions on myself (more so
13+ // | than the program) or anyone else who I want using my code, so that I limit
14+ // | the points where my code can break. E.g. restricting this now drastically
15+ // | changes how I write code later. Instead of calling
16+ // | myRoom.owner = new Owner();
17+ // | elsewhere in the code, where I wouldn't normally think of looking when
18+ // | I go back for my next code update or rework that involves the Room class,
19+ // | and potentially breaking something because I later decided to change how
20+ // | I want my program to assign or remove owners, I might instead call
21+ // | myRoom.assignOwner(trustees.getChairman());
22+ // | and assume that the only code that touches the Room's owner field is
23+ // | the Room class itself.
24+
25+ private double width ;
26+ private double length ;
27+
28+ // Overloaded constructors - might be useful for certain applications,
29+ // but constructors with fewer arguments might introduce errors down the line
30+ // if you don't check for null references
31+ // You can also call the superclass constructor within this constructor
32+ // for further control, e.g. super(args...); instead of this(args...);
33+ public Room (){
34+ this (0 , 0 , null );
35+ }
36+ public Room (double width , double length ){
37+ this (width , length , null );;
38+ }
39+ public Room (double width , double length , Owner owner ){
40+ // The only time I'll directly assign these variables is the constructor
41+ this .width = width ;
42+ this .length = length ;
43+ this .owner = owner ;
44+ }
45+
46+ public double getWidth (){
47+ // The benefit of having getter methods is similar to the benefits of
48+ // having setter methods. However, the most important difference is that
49+ // regardless of the method's signature (specifically, its return type),
50+ // a getter method allows the abstraction of the actual data into whatever
51+ // form we want. We could have just as easily not stored the actual width
52+ // of the room (say, if the Room itself has many Compartments) and instead
53+ // called a class method that would calculate it for us (e.g. a method
54+ // like sumCompartmentWidths() or something similar). With a getter method,
55+ // the internals of the class do not matter to anyone working WITH the class
56+ // (not working ON the class). Again, we black box the internals, and
57+ // instead present a method that is guaranteed to give an integer width.
58+ // However, for this example, we'll just return Room.width:
59+ return width ;
60+ }
61+ public void setWidth (double newWidth ){
62+ // The benefit of having setter methods is that you can now manipulate the
63+ // input - something that wouldn't be guaranteed if Room wasn't an object,
64+ // and its member variables weren't private. That is to say, separating
65+ // the assignment as a method (instead of setting .width, for example)
66+ // allows you to do any number of things, including
67+ // * input sanitization (e.g. trim, reencode, or cherry-pick stuff)
68+ // * input validation (e.g. throw errors if provided with bad input,
69+ // or silently substitute a valid value)
70+ // * user experience "niceties" such as log messages, warnings, etc.
71+ // * feeding the input into some other function before using it
72+ // * etc.
73+ // and allows you to do much more "under the hood" than a simple value
74+ // change. For example, let us now require our widths to be greater than
75+ // 0, but less than 100, for the sake of example, and display a warning
76+ // if the method argument is outside that range. We can then choose how
77+ // we process the input. Let us say that we wish to use the range as a
78+ // sort of threshold, and that arguments >100 fall back to 100, and
79+ // arguments <0 fall back to 0.
80+ if (newWidth <0 ){
81+ System .out .println ("Warning: You tried to set the width of a room to <0." );
82+ System .out .println (" Assuming new width of 0." );
83+ newWidth = 0 ;
84+ }else if (newWidth >100 ){
85+ System .out .println ("Warning: You tried to set the width of a room to >100." );
86+ System .out .println (" Assuming new width of 100." );
87+ newWidth = 100 ;
88+ }
89+ width = newWidth ;
90+ }
91+
92+ public double getLength (){
93+ return length ;
94+ }
95+ public void setLength (double newLength ){
96+ length = newLength ;
97+ }
98+
99+ public Owner getOwner (){
100+ return owner ;
101+ }
102+ public void setOwner (Owner newOwner ){
103+ owner = newOwner ;
104+ }
105+
106+ // For debugging purposes, let's override the standard Object.toString() method
107+ // that is called when "casting" the class to a string e.g. when you say
108+ // System.out.println("Some String: " + someClassInstance);
109+ @ Override public String toString (){
110+ return "Room [" +(int )width +"x" +(int )length +" | Sq.ft. " +(int )(width *length )+" | Owner: " +owner +"]" ;
111+ }
112+ }
0 commit comments