7.1 Polygons, Quadrangles and Squares
The purpose of this exercise is to get some experience with programming of classes in a pure specialization hierarchy. I have programmed the class Polygon. The well-known class Point, which we have seen several times during the course, is used as a building block of class Polygon type. (Notice that class Point has a MidPoint operation and a RotateAroundPoint operation). The class Polygon has the following public operations:
Now program the following specializations of Polygon:
For the sake of simplicity you are allowed (but not forced) to assume that the edges of the square are parallel with the x-axis and the y-axis. Please refer to the Polygon type hierarchy on the accompanying slide. Quadrangle and Square should support the same operations as Polygon. In particular Quadrangle and Square should support adequate constructors of their own. It is not necessary to use four points for representation of a square. Discuss this problem and try to find a solution. |
Solution
My solution can be seen below. Square is implemented in a general way. My solution contains two versions of Square. The last, SimpleSquare, has its own minimalistic representation of a Square. It worth noticing that the constructor of SimpleSquare calls a constructor in Polygon which allocates only minimal space to the general polygon. My solution starts with class Polygon and class Line.
|
7.2 Point3D: A client or a subclass of Point2D?
The purpose of this exercise is to sharpen your understanding of the difference between "being a client of class C" and "being af subclass of class C". The class Point3D extends Point2D by means of inheritance. As an alternative, the class Point3D may be implemented as a client of Point2D. In more practical terms this means that the class Point3D has an instance variable of type Point2D. Now implement Point3D as a client of Point2D - such that a 3D point has a 2D point as a part. Be sure that the class Point3D has the same interface as the version of class Point3D from the course material. Evaluate the difference between "being a client of" an "extending" class Point2D. Which of the solutions do you prefer? |
Solution
The new Point3D class is here
When the following client program runs
the output is
which is identical to the output from the accompanying slide. It requires a bit more work to implement Point3D by aggregation instead of by extension of class Point2D. |
7.3 Private Visibility and inheritance
Take a look at the classes shown below:
Answer the following questions before you run the program:
Run the program and confirm your answers. |
Solution
The program that we discuss is the following:
An instance of B has an instance variable i, inherited from class A, but i is not visible in B. The method F from class A is also inherited by class B. F is protected in A, and therefore it is visible and applicable in the method G. The first WriteLine in G is illegal, because i is invisible in class B. The second WriteLine is OK, because F is visible in class B. In order to compile the program, you must eliminate the first WriteLine in G. As expected, the output of the modified program is
|
7.4 Internal Visibility
The purpose of this exercise is to get some experience with the visibility modifier called internal. Take a look at the slide to which this exercise belongs. In this exercise, it is recommended to activate the compiler from a command prompt. Make a namespace N with two classes P and I:
Compile the classes in the namespace N to a single assembly, for instance located in the file x.dll. Demonstrate that the class I can be used in class P. Also demonstrate that P.i can be seen and used in class P. After this, program a class A, which attempts to use the classes P and I from x.dll. Arrange that class A is compiled separately, to a file y.dll. Answer the following questions about class A:
Finally, arrange that class A is compiled together with N.P and N.I to a single assembly, say y.dll. Does this alternative organization affect the answers to the questions asked above? |
Solution
The namespace N with classes P and I are here: namespace N{ public class P{ internal static int i = 5; public static int p = 6; private I anI; } internal class I{ internal static int i = P.i; public static int p = P.p; } } The class A is here: using N; class A { public static void M(){ P aP; // I aI; // Not accessible // int x = P.i; // Not visible outside x.dll int y = P.p; // int z = I.i; // Not visible outside x.dll // int w = I.p; // Not visible outside x.dll } } Here are the answers to the questions:
If class A and the classes in the namespace N are compiled together, to a single assembly, all the visibility problems vanish. This compilation can be done with: csc /t:library /out:y.dll n.cs aa.cs |
7.5 A subclass of LotteryAccount
On the slide, to which this exercise belongs, we have emphasized inheritance of methods and properties in the bank account class hierarchy. From the web-version of the material there is direct access to the necessary pieces of program. The LotteryAccount uses an instance of a Lottery object for adding interests. Under some lucky circumstances, the owner of a LotteryAccount will get a substantial amount of interests. In most cases, however, no interests will be added. There exists a single file which contains the classes BankAccount, CheckAccount, SavingsAccount, Lottery, together with a sample client class. Program a specialization of the LotteryAccount, called LotteyPlusAccount, with the following redefinitions of Deposit and Withdraw.
Notice that the Deposit and Withdraw methods in LotteryPlusAccount should combine with the method in LotteryAccount (method combination). Thus, use the Deposit and Withdraw methods from LotteryAccount as much as possible when you program the LotteryPlusAccount. Test-drive the class LotteryPlusAccount from a sample client class. |
Solution
Here are all the classes in my solution:
The following sample output from the program illustrates the case where difficulty in Lottery is 3 (one out of three wins):
|
7.6 Casting of BankAccounts
In the program "An illustration of type casting (C)v" the static types of the variables baRes1 .. baRes6 are BankAccount. Now change the static types of the variables baRes1 .. baRes6 to CheckAccount. This is done simply by declaring baRes1 .. baRes6 as CheckAccounts. Predict the compilers reaction before you attempt a compilation of the modified program. Afterwards compile the program and confirm your predictions. |
Solution
Here is the program we deal with. The comments explain each of the six cases.
|
7.7 Static and dynamic types
Type conversion with v as T was illustrated with a program on the accompanying slide. The output of the program was confusing and misleading. We want to report the static types of the expressions ba1 as BankAccount, ba1 as CheckAccount, etc. If you access this exercise from the web-version there will be direct links to the appropriate pieces of program. Explain the output of the program. You can examine the classes BankAccount, CheckAccount, SavingsAccount and LotteryAccount, if you need it. Modify the program such that the static type of the expressions bai as BanktypeAccount is reported. Instead of baRes1 = ba1 as BankAccount; Report(baRes1); you should activate some method on the expression ba1 as BankAccount which reveals its static type. In order to do so, it is allowed to add extra methods to the bank account classes. |
Solution
The cause of confusion is that the method Report (implicitly) uses the virtual method ToString to print out the accounts. Therefore the dynamic types - and not the static types - are reported. We can add a non-virtual method, StaticTypeString, to each of the bank account classes in order to get access to the static type of expressions of the form bai as BanktypeAccount. Here is the modified program
Here are the modified bank account classes. Notice in particular the non-virtual methods StaticTypeString, marked with new throughout the BankAccount class hierarchy:
|
7.8 Non-virtual variables - Virtual Methods
Take a look at the following program
and figure out what it prints. Explain the behaviour. |
Solution
The program prints 1 2 2 1 The first output line reflects that instance variables are non-virtual. The static type of the variable a controls the result. The second output line reflects that the method Op1 is virtual. Op1 in class B accesses v in B. The third output line shows, like the first one, that instance variables are non-virtual. The fourth output line shows that the variable v from A is present in an instance of class B. |
Generated: Monday February 7, 2011, 12:17:06