X


Historia wymaga pasterzy, nie rzeźników.

DrawWindow( );
}
All the compiler knows is that it has three Window objects and that you've called DrawWindow( )on each. If you had not marked DrawWindow as virtual, Window's DrawWindow( ) method would be page 90
Programming C#
called three times. However, because you did mark DrawWindow( ) as virtual and because the derived classes override that method, when you call DrawWindow( ) on the array, the compiler determines the runtime type of the actual objects (a Window, a ListBox and a Button) and calls the right method on each. This is the essence of polymorphism. The complete code for this example is shown in Example 5-2.
This listing uses an array, which is a collection of objects, all of the same type.
You access the members of the array with the index operator:
// set the value of the element
// at offset 5
MyArray[5] = 7;
The first element in any array is at index 0. The use of the array in this
example should be fairly intuitive. Arrays are explained in detail in Chapter 9.

Example 5-2. Using virtual methods
using System;

public class Window
{
// constructor takes two integers to
// fix location on the console
public Window(int top, int left)
{
this.top = top;
this.left = left;
}

// simulates drawing the window
public virtual void DrawWindow( )
{
Console.WriteLine("Window: drawing Window at {0}, {1}",
top, left);
}

// these members are private and thus invisible
// to derived class methods. We'll examine this
// later in the chapter
protected int top;
protected int left;

}

// ListBox derives from Window
public class ListBox : Window
{
// constructor adds a parameter
public ListBox(
int top,
int left,
string contents):
base(top, left) // call base constructor
{

listBoxContents = contents;
}

// a new version (note keyword) because in the

page 91
Programming C#
// derived method we change the behavior
public override void DrawWindow( )
{
base.DrawWindow( ); // invoke the base method
Console.WriteLine ("Writing string to the listbox: {0}",
listBoxContents);
}

private string listBoxContents; // new member variable
}

public class Button : Window
{
public Button(
int top,
int left):
base(top, left)
{
}

// a new version (note keyword) because in the
// derived method we change the behavior
public override void DrawWindow( )
{
Console.WriteLine("Drawing a button at {0}, {1}\n",
top, left);
}
}

public class Tester
{
static void Main( )
{
Window win = new Window(1,2);
ListBox lb = new ListBox(3,4,"Stand alone list box");
Button b = new Button(5,6);
win.DrawWindow( );
lb.DrawWindow( );
b.DrawWindow( );

Window[] winArray = new Window[3];
winArray[0] = new Window(1,2);
winArray[1] = new ListBox(3,4,"List box in array");
winArray[2] = new Button(5,6);

for (int i = 0;i < 3; i++)
{
winArray[i].DrawWindow( );
}
}
}

Output:
Window: drawing Window at 1, 2
Window: drawing Window at 3, 4
Writing string to the listbox: Stand alone list box
Drawing a button at 5, 6

Window: drawing Window at 1, 2
Window: drawing Window at 3, 4
Writing string to the listbox: List box in array
Drawing a button at 5, 6

page 92
Programming C#
Note that throughout this example, we've marked the new overridden methods with the keyword override:

public override void DrawWindow( )
The compiler now knows to use the overridden method when treating these objects polymorphically. The compiler is responsible for tracking the real type of the object and for handling the "late binding" so that it is ListBox.DrawWindow( ) that is called when the Window reference really points to a ListBox object.
C++ programmers take note: you must explicitly mark the declaration of any method that overrides a virtual method with the keyword override.


5.3.3 Versioning with the new and override Keywords
In C#, the programmer's decision to override a virtual method is made explicit with the override keyword. This helps you release new versions of your code; changes to the base class will not break existing code in the derived classes. The requirement to use the keyword override helps prevent that problem.
Here's how: assume for a moment that the Window base class of the previous example was written by Company A. Suppose also that the ListBox and RadioButton classes were written by programmers from Company B using a purchased copy of the Company A Window class as a base.
The programmers in Company B have little or no control over the design of the Window class, including future changes that Company A might choose to make.
Now suppose that one of the programmers for Company B decides to add a Sort( ) method to ListBox:
public class ListBox : Window
{
public virtual void Sort( ) {...}
}
This presents no problems until Company A, the author of Window, releases Version 2 of its Window class, and it turns out that the programmers in Company A have also added a Sort( ) method to their public class Window:
public class Window
{
// ...
public virtual void Sort( ) {...}
}
In other object-oriented languages (such as C++), the new virtual Sort( ) method in Window would now act as a base method for the virtual Sort( ) method in ListBox. The compiler would call the Sort( ) method in ListBox when you intend to call the Sort( ) in Window. In Java, if the Sort(

Drogi uĚźytkowniku!

W trosce o komfort korzystania z naszego serwisu chcemy dostarczać Ci coraz lepsze usługi. By móc to robić prosimy, abyś wyraził zgodę na dopasowanie treści marketingowych do Twoich zachowań w serwisie. Zgoda ta pozwoli nam częściowo finansować rozwój świadczonych usług.

Pamiętaj, że dbamy o Twoją prywatność. Nie zwiększamy zakresu naszych uprawnień bez Twojej zgody. Zadbamy również o bezpieczeństwo Twoich danych. Wyrażoną zgodę możesz cofnąć w każdej chwili.

 Tak, zgadzam się na nadanie mi "cookie" i korzystanie z danych przez Administratora Serwisu i jego partnerĂłw w celu dopasowania treści do moich potrzeb. Przeczytałem(am) Politykę prywatności. Rozumiem ją i akceptuję.

 Tak, zgadzam się na przetwarzanie moich danych osobowych przez Administratora Serwisu i jego partnerĂłw w celu personalizowania wyświetlanych mi reklam i dostosowania do mnie prezentowanych treści marketingowych. Przeczytałem(am) Politykę prywatności. Rozumiem ją i akceptuję.

Wyrażenie powyższych zgód jest dobrowolne i możesz je w dowolnym momencie wycofać poprzez opcję: "Twoje zgody", dostępnej w prawym, dolnym rogu strony lub poprzez usunięcie "cookies" w swojej przeglądarce dla powyżej strony, z tym, że wycofanie zgody nie będzie miało wpływu na zgodność z prawem przetwarzania na podstawie zgody, przed jej wycofaniem.