Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

C# ПІДРУЧНИКИ / c# / MS Press - Msdn Training Programming Net Framework With C#

.pdf
Скачиваний:
173
Добавлен:
12.02.2016
Размер:
16.87 Mб
Скачать

Module 5: Common Type System

29

 

 

 

Nested Classes

When classes are nested, the nested classes cannot exceed the accessibility of the containing class. For example, if a nested class is marked as public, but the containing class is marked as internal, the nested class must also be internal.

The following example shows the effect of access modifiers on nested classes:

internal class COuter1

{

public class CInner1

{

public static short MyPublicShort = 0; internal static short MyInternalShort = 0; private static short MyPrivateShort = 0;

}

internal class CInner2

{

public static short MyPublicShort = 0; internal static short MyInternalShort = 0; private static short MyPrivateShort = 0;

}

private class CInner3

{

public static short MyPublicShort = 0; internal static short MyInternalShort = 0; private static short MyPrivateShort = 0;

}

}

public class MainClass

{

public static void Main()

{

COuter1.CInner1.MyPublicShort = 1; //Success because internal at class level //and in same assembly

COuter1.CInner2.MyPublicShort = 2;

//Success because internal and in same assembly

COuter1.CInner3.MyPublicShort = 3;

//Failure because class is private, and all members are private

}

}

30 Module 5: Common Type System

Inheritance

Topic Objective

To explain how inheritance works in the Common Type System.

Lead-in

Inheritance is a method of reuse that enables one class to reuse, or inherit, the fields, properties, and methods of another class.

!Inheritance Is the Reuse of Class Members in Other Classes

!The Common Type System Only Supports Single Inheritance for Classes

!Member Hiding

#Redefine the same method in the derived class

#Use the new keyword

!Abstract Members

!Sealed Classes

*****************************ILLEGAL FOR NON-TRAINER USE******************************

In object-oriented programming, inheritance is a method of reuse that enables one class to reuse, or inherit, the fields, properties, and methods of another class. Inheritance represents an “is a” relationship between classes. For example, if a square class inherits from a shape class, the square “is a” kind of shape.

Inheritance is useful when multiple classes share the same methods or data. The common methods and data can be abstracted into a separate class that the other classes inherit from.

Inheritance is pervasive in the Common Type System. Every class must inherit from System.Object, so all classes will have the members of System.Object.

Single Inheritance

The Common Type System only supports single inheritance of class types. Single inheritance means a class can inherit directly from only one other class. Some object-oriented systems, such as C++, allow multiple inheritance, which means that one class can inherit from many other classes.

The Common Type System does support multiple inheritance through interfaces. In that case, one class can inherit from one other class and from zero or more interfaces. For more information about multiple inheritance through interfaces, see Module 6, “Working with Types,” in Course 2349B,

Programming with the Microsoft .NET Framework (Microsoft Visual C#

.NET).

In the simplest form of inheritance, a class inherits its members from the base class and gains all the functionality of the base class, and at the same time it adds additional functionality of its own.

Module 5: Common Type System

31

 

 

 

In the following example, three classes are defined. The base class is called Animal; it implements an Age property and a Move method. The second class is called Dog; it inherits from Animal and implements an additional method called Bark. The third class is called Cat; it also inherits from Animal and implements an additional method called Meow.

public class Animal

{

protected short age = 0; public short Age

{

get

{

return age;

}

set

{

if (value > 0) age = value;

}

}

public void Move()

{

Console.WriteLine("Animal is Moving");

}

}

public class Dog : Animal

{

public void Bark()

{

Console.WriteLine("Bark!");

}

}

public class Cat : Animal

{

public void Meow()

{

Console.WriteLine("Meow!");

}

}

public class MainClass

{

public static void Main()

{

Dog d = new Dog(); Cat c = new Cat(); d.Age = 3; d.Move(); d.Bark();

c.Age = 2; c.Move(); c.Meow();

}

}

32 Module 5: Common Type System

This code generates the following output:

Animal is Moving

Bark!

Animal is Moving

Meow!

In the Main method, a Dog object and Cat object are created. Methods and properties of the Animal class are called on the Dog object and the Cat object. In this way, the Animal class functionality for storing the age of an animal and implementing movement in an animal can be written once and reused in multiple classes.

Member Hiding

Sometimes you will want a class to inherit from a base class, but you will want to modify some of the base class’s functionality. For example, you may want a new kind of animal class called Slug to inherit from the Animal class, but you will want to use the Move method to make the slug move slowly. You can accomplish this effect by creating a method with the same name and parameter list as the base class method.

The following example shows how you can customize the Move method for slugs by making the Slug class replace the Move method of the Animal class:

public class Slug : Animal

{

public new void Move()

{

Console.WriteLine("Moving very slowly");

}

}

public class MainClass

{

public static void Main()

{

Slug s = new Slug(); s.Move();

}

}

This code generates the following output:

Moving very slowly

In the preceding example, the new keyword is used to signal that a method was replaced. In this context, the new keyword denotes that a method was hidden. This use of the new keyword should not be confused with the use of the new keyword to allocate a new object. While the new keyword is not required for method hiding, it enhances readability. The C# compiler will issue a warning if the new keyword is not used on replaced methods.

Module 5: Common Type System

33

 

 

 

Abstract Members

Methods, fields, and properties can also be abstract. A method, field, or property is abstract when the base class does not implement the member, and the derived class must implement the member.

Abstract members are marked with the abstract keyword. When derived classes implement abstract methods, they must use the override keyword to indicate that they are overriding the base-class functionality.

The following example shows an abstract Shape class that has one abstract method called Draw. The Shape class implements a Move method, which, when called, will call the derived class Draw method. Thus the Shape class has information about how to move but does not have information about how to draw after it moves. The abstract method forces the derived class to implement the Draw method so that the Shape class can move properly.

using System;

abstract class Shape

{

protected int x, y;

//Derived class must implement next method public abstract void Draw();

public void Move(int x, int y)

{

this.x = x; this.y = y;

//Call derived class implementation Draw();

}

}

class Square : Shape

{

public override void Draw()

{

Console.WriteLine("Drawing a Square at {0},{1}",x,y);

}

}

class MainClass

{

public static void Main()

{

Square s = new Square();

//Call base class Move method, which in turn calls //derived class Draw method

s.Move(1,1);

}

}

34 Module 5: Common Type System

This code generates the following output:

Drawing a Square at 1,1

If a class contains any abstract members, the entire class becomes an abstract class. As a result, an instance of the abstract class cannot be created because it is missing functionality for a method. For this reason, the Shape class in the preceding example was marked as abstract.

Sealed Classes

You can prevent other classes from deriving from a specific class by sealing that class. Use the sealed modifier to make a sealed class.

sealed class SealedClass

{

public static void Foo()

{

}

}

The sealed modifier is primarily used to prevent unintended derivation, but it also enables certain run time optimizations. In particular, because a sealed class is known to never have any derived classes, it is possible to transform virtual function member invocations on sealed class instances into non-virtual invocations.

Module 5: Common Type System

35

 

 

 

Polymorphism

Topic Objective

To explain the use of polymorphism to define a base class.

Lead-in

In object-oriented programming, polymorphism allows you to define a base class that includes routines that perform standard operations on groups of related objects, without regard to the exact type of each object.

!Polymorphism Allows a Reference Variable to Call the Correct Method

!Virtual Methods Enable Polymorphism in the Common Type System

#Use the virtual keyword in the base class

#Use the override keyword in the derived class

!Sealed Methods

*****************************ILLEGAL FOR NON-TRAINER USE******************************

Polymorphism derives from the Greek for “many forms.” In object-oriented programming, polymorphism allows you to define a base class that includes routines that perform standard operations on groups of related objects, without regard to the exact type of each object. For example, in the preceding animal scenario, you could add a method called MakeNoise. When this method is called, Animal objects should print “Animal is making noise.” A dog object should print “Bark!”, and a cat object should print “Meow!”

In the following example, the code does not work as expected; it prints “Animal is making noise,” instead of the desired specific animal noise, such as “Bark” or “Meow”:

public abstract class Animal

{

//..Other properties and methods public void MakeNoise()

{

Console.WriteLine("Animal is making noise");

}

}

public class Dog : Animal

{

//..Other properties and methods public new void MakeNoise()

{

Console.WriteLine("Bark!");

}

}

(Code continued on the following page.)

36 Module 5: Common Type System

public class Cat : Animal

{

//..Other properties and methods public new void MakeNoise()

{

Console.WriteLine("Meow!");

}

}

public class MainClass

{

public static void Main()

{

Dog d = new Dog(); Cat c = new Cat(); d.Age = 3;

c.Age = 2; WorkWithAnimal(d); WorkWithAnimal(c);

}

public static void WorkWithAnimal(Animal a)

{

Console.WriteLine("Working with animal age {0}",a.Age); a.MakeNoise();

}

}

This code generates the following output:

Working with animal age 3

Animal is making noise

Working with animal age 2

Animal is making noise

In the preceding example, because the reference in the WorkWithAnimal method is type Animal, the Animal base class MakeNoise always gets called. The desired behavior would be a dog object making a noise like a dog, not an animal.

Module 5: Common Type System

37

 

 

 

To resolve this problem, use the virtual keyword to mark a method as virtual. Using the virtual keyword will ensure that the correct method call gets called on the basis of the object type, not the reference type. The derived class must then use the override keyword on the same method, as in the following example:

public abstract class Animal

{

//..Other properties and methods public virtual void MakeNoise()

{

Console.WriteLine("Animal is making noise");

}

}

public class Dog : Animal

{

//..Other properties and methods public override void MakeNoise()

{

Console.WriteLine("Bark!");

}

}

public class Cat : Animal

{

//..Other properties and methods public override void MakeNoise()

{

Console.WriteLine("Meow!");

}

}

public class MainClass

{

public static void Main()

{

Dog d = new Dog(); Cat c = new Cat(); d.Age = 3;

c.Age = 2; WorkWithAnimal(d); WorkWithAnimal(c);

}

public static void WorkWithAnimal(Animal a)

{

Console.WriteLine("Working with animal age {0}",a.Age); a.MakeNoise();

}

}

38 Module 5: Common Type System

This code generates the following output:

Working with animal age 3

Bark!

Working with animal age 2

Meow!

Sealed Methods

You can use the sealed modifier to prevent derived classes from overriding specific methods. Methods marked with the sealed modifier are called sealed methods. The sealed modifier can only be used in conjunction with the override modifier.

class A

{

public virtual void Foo() {/*...*/

}

}

class B : A

{

//Any class derived from B will //not be able to override Foo public sealed override void Foo() {/*..*/

}

}

Соседние файлы в папке c#