logo search
CSharp_Prog_Guide

Использование ключевых слов "Override" и "New"

В C# методы в производных классах могут иметь такие же имена, как и методы в базовых классах (если четко соблюдаются различия в использовании новых методов). В следующем примере демонстрируется использование ключевых слов new и override.

Сначала объявим три класса: базовый класс Car и два класса, производных от него: ConvertibleCar и Minivan. Базовый класс содержит один метод с именем DescribeCar, отправляющий описание автомобиля на консоль. Методы производных классов также включают метод с именем DescribeCar, отображающий уникальные свойства этих классов. Эти методы также вызывают базовый класс DescribeCar, чтобы продемонстрировать, каким образом они унаследовали свойства класса Car.

Чтобы подчеркнуть разницу, класс ConvertibleCar определен с ключевым словом new, а класс Minivan — с ключевым словом override.

-----

We can now write some code that declares instances of these classes, and calls their methods so that the objects can describe themselves:

public static void TestCars1()

{

Car car1 = new Car();

car1.DescribeCar();

System.Console.WriteLine("----------");

ConvertibleCar car2 = new ConvertibleCar();

car2.DescribeCar();

System.Console.WriteLine("----------");

Minivan car3 = new Minivan();

car3.DescribeCar();

System.Console.WriteLine("----------");

}

As you might expect, the output looks like this:

Four wheels and an engine.

----------

Four wheels and an engine.

A roof that opens up.

----------

Four wheels and an engine.

Carries seven people.

----------

Теперь можно написать код, описывающий экземпляры этих классов и вызовы методов, чтобы объекты могли себя описывать:30

---

Как и предполагалось, результат выглядит следующим образом:

Four wheels and an engine.

----------

Four wheels and an engine.

A roof that opens up.

----------

Four wheels and an engine.

Carries seven people.

----------

However, in this next section of code, we declare an array of objects derived from the Car base class. This array can store Car, ConvertibleCar, and Minivan objects. The array is declared like this:

public static void TestCars2()

{

Car[] cars = new Car[3];

cars[0] = new Car();

cars[1] = new ConvertibleCar();

cars[2] = new Minivan();

}

We can then use a foreach loop to visit each Car object contained in the array, and call the DescribeCar method, like this:

foreach (Car vehicle in cars)

{

System.Console.WriteLine("Car object: " + vehicle.GetType());

vehicle.DescribeCar();

System.Console.WriteLine("----------");

}

The output from this loop is as follows:

Car object: YourApplication.Car

Four wheels and an engine.

----------

Car object: YourApplication.ConvertibleCar

Four wheels and an engine.

----------

Car object: YourApplication.Minivan

Four wheels and an engine.

Carries seven people.

----------

Notice how the ConvertibleCar description is not what you might expect. As the new keyword was used to define this method, the derived class method is not called—the base class method is called instead. The Minivan object correctly calls the overridden method, producing the results we expected.

If you want to enforce a rule that all classes derived from Car must implement the DescribeCar method, you should create a new base class that defines the method DescribeCar as abstract. An abstract method does not contain any code, only the method signature. Any classes derived from this base class must provide an implementation of DescribeCar.

Однако в следующем фрагменте кода мы объявляем массив объектов, производных от класса Car. В этом массиве могут храниться объекты Car, ConvertibleCar и Minivan. Массив объявляется следующим образом:

public static void TestCars2()

{

Car[] cars = new Car[3];

cars[0] = new Car();

cars[1] = new ConvertibleCar();

cars[2] = new Minivan();

}

Затем можно использовать цикл foreach для посещения каждого объекта Car в машине и вызова метода DescribeCar:

foreach (Car vehicle in cars)

{

System.Console.WriteLine("Car object: " + vehicle.GetType());

vehicle.DescribeCar();

System.Console.WriteLine("----------");

}

Результат выполнения этого цикла выглядит следующим образом:31

Car object: YourApplication.Car

Four wheels and an engine.

----------

Car object: YourApplication.ConvertibleCar

Four wheels and an engine.

----------

Car object: YourApplication.Minivan

Four wheels and an engine.

Carries seven people.

----------

Обратите внимание, что описание ConvertibleCar не такое, как ожидалось. Поскольку ключевое слово new было использовано для определения этого метода, метод производного класса не вызван, вместо него вызван метод базового класса32. Объект Minivan правильно вызывает переопределенный метод и выдает ожидаемый результат.

Чтобы принудительно выполнялось правило, согласно которому все классы, производные от Car, должны реализовать метод DescribeCar, нужно создать новый базовый класс, определяющий метод DescribeCar как abstract. Абстрактный метод содержит только подпись метода и не содержит никакого кода. Любые классы, производные от этого базового класса, должны предоставлять реализацию DescribeCar. Дополнительные сведения см. в разделе abstract.

How to: Override the ToString Method

Every object in C# inherits the ToString method, which returns a string representation of that object. For example, all variables of type int have a ToString method, which enables them to return their contents as a string:

int x = 42;

string strx = x.ToString();

System.Console.WriteLine(strx);

When you create a custom class or struct, you should override the ToString method in order to provide information about your type to client code.

Security Note:

When you decide what information to provide through this method, consider whether your class or struct will ever be used by untrusted code. Be careful to ensure that you do not provide any information that could be exploited by malicious code.

To override the OnString method in your class or struct

  1. Declare a ToString method with the following modifiers and return type:

    public override string ToString(){}

  2. Implement the method so that it returns a string.

The following example returns not only the name of the class, but also the data specific to a particular instance of the class. Note that it also uses the ToString method on the age variable to covert the int to a string that can be output.

class Person

{

string name;

int age;

SampleObject(string name, int age)

{

this.name = name;

this.age = age;

}

public override string ToString()

{

string s = age.ToString();

return "Person: " + name + " " + s;

}

}