Exercise index of this lecture   Alphabetic index   Course home   

Exercises
Specialization, Extension, and Inheritance


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:

  • A constructor.
  • Rank: The number of edges of the polygon
  • Circumference: The sum of the edge lengths.

Now program the following specializations of Polygon:

  • Quadrangle
  • Square

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


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


7.3   Private Visibility and inheritance  

Take a look at the classes shown below:

using System;

public class A{
  private int i = 7;

  protected int F(int j){
   return i + j;
  }
}

public class B : A{
  public void G(){
    Console.WriteLine("i: {0}", i);
    Console.WriteLine("F(5): {0}", F(5));
  }
}

public class Client {
  public static void Main(){
    B b = new B();
    b.G();
  }
}

Answer the following questions before you run the program:

  1. Does the instance of B, created in Main in Client, have an instance variable i?
  2. Is the first call to Console.WriteLine in G legal?
  3. Is the second call to Console.WriteLine in G legal?

Run the program and confirm your answers.

 

Solution


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:

  • P should be public. P should have a static public member p and a static internal member i.
  • I should be internal. I should also have a static public member p and a static internal member 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:

  1. Can you declare variables of type P in class A?
  2. Can you declare variables of type I in class A?
  3. Can you access P.i and and P.p in A?
  4. Can you access I.i and and I.p in 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


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.

  • The Deposit method doubles the deposited amount in case you draw a winning lottery number upon deposit. If you are not lucky, Deposit works as in LottoryAccount, but an administrative fee of 15 kroner will be withdrawn from your LotteryPlusAccount.
  • The Withdraw method returns the withdrawn amount without actually deducting it from the LotteryPlusAccount if you draw a winning lottery number upon withdrawal. If you are not lucky, Withdraw works as in LottoryAccount, and an additional administrative fee of 50 kroner will be withdrawn from the account as well.

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


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


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


7.8   Non-virtual variables - Virtual Methods  

Take a look at the following program

using System;

public class A {
 public int v = 1;
 public virtual int Op1(){return v;}
}

public class B: A{
 public new int v = 2;
 public override int Op1(){return v;}
 public int Op2(){return base.v;}
}

public class Client{

  public static void Main (){
    A a = new B();
    Console.WriteLine("{0}", a.v);
    Console.WriteLine("{0}", a.Op1());

    B b = new B();
    Console.WriteLine("{0}", b.v);
    Console.WriteLine("{0}", b.Op2());
  }

}

and figure out what it prints.

Explain the behaviour.

 

Solution


Generated: Monday February 7, 2011, 12:17:06