|To keep these concepts fresh in your mind, answer the following questions, and then check your answers at the bottom. For best results as a memory tool, answer these questions a few hours after reading the original material.
1) For each scenario, identify an example of "programming stupidity".
a) A programmer creates a Cube class, which contains member variables for _width, _height and _depth. He then creates a _volume member variable, and exposes it with a GetVolume() method.
b) A programmer creates a Penguin class, and gives it three properties: PenguinAge, PenguinWeight, and PenguinName.
c) A programmer creates a ColoredCircle class, and gives it several public methods for manipulating its appearance. For debug purposes, he adds some Console.WriteLine() statements in the methods.
d) A programmer needs three separate instances of an Employee class he's written. Because it so happens that the three instances have nearly the same values, he uses the "=" operator to copy the first Employee object into the other two variables, and then changes the few properties that differ.
2) How could an email address best be represented in code? As a string variable, or as a struct/class?
3) Explain the following concepts:
b) Static vs. Member
1) Stupidity is in the eye of the beholder, but these are some things that I'd certainly object to:
a) The Cube class already has variables for tracking each of its dimensions. Volume is mathematically dependant on those dimensions, but by making "volume" its own variable, we've introduced the risk that it will become "out of sync" with the actual dimensions. We don't want a separate variable for volume; the GetVolume() method should calculate volume "on the fly" by using the width, height and depth variables.
b) These properties already belong to the Penguin class, so prefixing them with "Penguin" is totally redundant (and will only serve to hasten the programmer's development of carpal tunnel). Just call them Age, Weight and Name.
c) By putting Console.WriteLine() statements in a class, we make that class dependant on a console environment. This is particularly foolish in the case of a class like ColoredCircle, since there's a good chance that we might want to reuse it in a visual program, where we could actually draw it on the screen.
d) Objects are stored by reference. By using the "=" operator, the programmer has actually created three variables that point to the same object. If he wants to reuse an object's values by copying them into separate objects, he'll have to define a Clone() method or copy constructor in the Employee class.
2) This is actually a trick question! It completely depends on what you need to do with the email addresses that exist in your code. If you made a class for storing an email address, you could bundle a lot of useful functions with the address itself... for example, you could expose methods for getting or setting just the domain part of the email address, so that the user doesn't have to mess around with string manipulation. Or, if you're really good with network programming, you could even expose a MailTo() method in the class, which would allow the user to send an email to that address, right from your program. Then again, maybe your program is just maintaining a database of employee records, and an email address is one of twenty different pieces of information that's associated with each record. In that case, perhaps an email class would be overkill, and you're really only interested in representing it as a string member of an Employee class.
3) Explanations are as follows:
a) Encapsulation deals with providing a simplified interface to conceal a system's underlying complexities. For example, every car has a simple interface consisting of a steering wheel, a clutch, and two floor pedals. These controls do an awful lot of stuff under the car's hood, but you don't need to understand or even know about any of it. All you need to understand is how the car responds to the steering wheel, a clutch, and two floor pedals. Encapsulation is all the more critical in programming, where a lot of our code deals with abstract concepts that don't even have visible counterparts in the "real world".
b) A member variable is something that's specific to each instance of a class. Every object has its own separate copy of that variable, and potentially, its own separate value. Static variables, however, are shared between all the instances of a class. They are not associated with any particular class instance; they are associated with the class itself. It's easy to think of examples for member variables, because they reflect the way that things work in the real world: every person has their own name, age, hair color, etc., every building has its own height, location, tenant, etc., and so forth. Static variables and methods tend to be more about utility and logical grouping, than they are about representing a particular object. A simple example might be a static counter that increments in a class' constructor, thus tracking how many times an object from that class has been created.
c) Namespaces help to prevent naming conflicts, by placing your classes, structs, etc. within a certain context. Hypothetically, you might want to use the Table class from the Furniture namespace and the Table class from the Database namespace in the same context. Even though you have two classes named "Table", you can qualify them with Furniture.Table or Database.Table, so that C# can tell them apart. If those classes weren't defined in separate namespaces, however, there would be no way to use them in the same context. Namespaces are a bigger deal when using and creating libraries; when we're just dealing with our little "standalone" application we can mostly ignore them.