8.1 Parameter variance
First, be sure you understand the co-variance problem stated above. Why is it problematic to execute aref.Op(sref)in the class Client?
The parameter variance problem, and the distinction between covariance and contravariance, is not really a topic in C#. The program with the classes A/B/S/T on the previous page compiles and runs without problems. Explain why!
The program with the classes A/B/S/T is OK because the methods A.Op and B.Op are different from each other due to the rules about overloading. Recall that two methods of the same name, but with different formal parameter types, can coexist without problems in C#. When one of the methods are called, the static type of the formal parameters are used to find out, which of the methods to call.
Thus, aref.Op(sref) call A.OP, and not B.OP. And therefore there are no problems (no bomb) whatsoever.
8.2 A specialization of Stack
It is noteworthy that the abstract Stack is programmed without any instance variables (that is, without any data representation of the stack). Notice also that we have been able to program a single non-abstract method ToggleTop, which uses the abstract methods Top, Pop, and Push.
Make a non-abstract specialization of Stack, and decide on a reasonable data representation of the stack.
In this exercise it is OK to ignore exception/error handling. You can, for instance, assume that the capacity of the stack is unlimited; That popping an empty stack an empty stack does nothing; And that the top of an empty stack returns the string "Not Possible". In a later lecture we will revisit this exercise in order to introduce exception handling. Exception handling is relevant when we work on full or empty stacks.
Write a client of your stack class, and demonstrate the use of the inherited method ToggleTop. If you want, you can also adapt my stack client class .
Here is my version of the non-abstract specialization of the abstract class Stack:
Here follows a sample client program:
8.3 Course and Project classes
In the earlier exercise about courses and projects (found in the lecture about classes) we programmed the classes BooleanCourse, GradedCourse, and Project. Revise and reorganize your solution (or the model solution) such that BooleanCourse and GradedCourse have a common abstract superclass called Course.
Be sure to implement the method Passed as an abstract method in class Course.
In the Main method (of the client class of Course and Project) you should demonstrate that both boolean courses and graded courses can be referred to by variables of static type Course.
Here is my solution:
Please take notice of the comments in the source program.
8.4 The interface ITaxable
For the purpose of this exercise you are given a couple of very simple classes called Bus and House. Class Bus specializes the class Vehicle. Class House specializes the class FixedProperty. All the classes are here.
First in this exercise, program an interface ITaxable with a parameterless operation TaxValue. The operation should return a decimal number.
Next, program variations of class House and class Bus which implement the interface ITaxable. Feel free to invent the concrete taxation of houses and busses. Notice that both class House and Bus have a superclass, namely FixedProperty and Vehicle, respectively. Therefore it is essential that taxation is introduced via an interface.
Demonstrate that taxable house objects and taxable bus objects can be used together as objects of type ITaxable.
First, we show the given classes Bus and House together with their superclasses:
Here follows the the interface ITaxable together with the classes TaxableBus and TaxableHouse. Notice the way they the two classes implement the interface ITaxable. At the bottom, the class App serves as a client that demonstrates how taxable houses and taxable busses can be used together.
8.5 An abstract GameObject class
Restructure this program such that class Die and class Card both inherit an abstract class GameObject. You should write the class GameObject.
The client program should survive this restructuring. (You may, however, need to change the name of the type IGameObject to GameObject). Compile and run the given client program with your classes.
The abtract class GameObject is here:
The class Die specializes the abstract class GameObject:
Similarly, the class Card specializes the abstract class GameObject:
Here is the client class, which shows a mixed used of dies and playing cards on the basis of the abstract class GameObject:
Only few modifications where necessary in our transition from the interface IGameObject to the abstract class GameObject:
8.6 Comparable Dice
In this exercise we will arrange that two dice can be compared to each other. The result of die1.CompareTo(die2) is an integer. If the integer is negative, die1 is considered less than die2; If zero, die1 is considered equal to die2; And if positive, die1 is considered greater than die2. When two dice can be compared to each other, it is possible sort an array of dice with the standard Sort method in C#.
Program a version of class Die which implements the interface System.IComparable.
Consult the documentation of the (overloaded) static method System.Array.Sort and locate the Sort method which relies on IComparable elements.
Make an array of dice and sort them by use of the Sort method.
We show a solution which relies on the non-generic version of class IComparable
The listing below is relatively long. You should focus on the method CompareTo in class Die. Notice the necessary casting of other to Die in the body of CompareTo.
Also notice the use of Array.Sort(Array) at the very bottom of the client class App. There are many overloaded Sort methods in class Array. According to the documentation, the method Array.Sort(Array) relies on Icomparable elements.
The following output appears when I run the program:
You do probably not get the same output if you run the program, because randomness is involved in the class Die.
Generated: Monday February 7, 2011, 12:18:08