Герберт Шилдт - C# 4.0: полное руководство
- Название:C# 4.0: полное руководство
- Автор:
- Жанр:
- Издательство:ООО И.Д. Вильямс
- Год:2011
- Город:Москва -- Киев
- ISBN:978-5-8459-1684-6
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Герберт Шилдт - C# 4.0: полное руководство краткое содержание
В этом полном руководстве по C# 4.0 - языку программирования, разработанному специально для среды .NET, - детально рассмотрены все основные средства языка: типы данных, операторы, управляющие операторы, классы, интерфейсы, методы, делегаты, индексаторы, события, указатели, обобщения, коллекции, основные библиотеки классов, средства многопоточного программирования и директивы препроцессора. Подробно описаны новые возможности C#, в том числе PLINQ, библиотека TPL, динамический тип данных, а также именованные и необязательные аргументы. Это справочное пособие снабжено массой полезных советов авторитетного автора и сотнями примеров программ с комментариями, благодаря которым они становятся понятными любому читателю независимо от уровня его подготовки.
Книга рассчитана на широкий круг читателей, интересующихся программированием на C#.Введите сюда краткую аннотацию
C# 4.0: полное руководство - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
get { return pri_width; }
set { pri_width = value < 0 ? -value : value; }
}
public double Height {
get { return pri_height; }
set { pri_height = value < 0 ? -value : value; }
}
public string name { get; set; }
public void ShowDim() {
Console.WriteLine("Ширина и высота равны " +
Width + " и " + Height);
}
public virtual double Area() {
Console.WriteLine("Метод Area() должен быть переопределен");
return 0.0;
}
}
// Класс для треугольников, производный от класса TwoDShape.
class Triangle : TwoDShape {
string Style;
// Конструктор, используемый по умолчанию,
public Triangle() {
Style = "null";
}
// Конструктор для класса Triangle,
public Triangle(string s, double w, double h)
: base (w, h, "треугольник") {
Style = s;
}
//Сконструировать равнобедренный треугольник,
public Triangle(double x) : base(x, "треугольник") {
Style = "равнобедренный";
}
// Сконструировать копию объекта типа Triangle,
public Triangle(Triangle ob) : base(ob) {
Style = ob.Style;
}
// Переопределить метод Area() для класса Triangle,
public override double Area() {
return Width * Height / 2;
}
// Показать тип треугольника,
public void ShowStyle() {
Console.WriteLine("Треугольник " + Style);
}
}
// Класс для прямоугольников, производный от класса TwoDShape.
class Rectangle : TwoDShape {
// Конструктор для класса Rectangle,
public Rectangle(double w, double h)
: base (w, h, "прямоугольник") { }
// Сконструировать квадрат,
public Rectangle(double x) : base(x, "прямоугольник") { }
// Сконструировать копию объекта типа Rectangle,
public Rectangle(Rectangle ob) : base(ob) { }
// Возвратить логическое значение true, если
// прямоугольник окажется квадратом,
public bool IsSquare() {
if(Width == Height) return true;
return false;
}
// Переопределить метод Area() для класса Rectangle,
public override double Area() {
return Width * Height;
}
}
class DynShapes {
static void Main() {
TwoDShape[] shapes = new TwoDShape[5] ;
shapes[0] = new Triangle("прямоугольный", 8.0, 12.0);
shapes[1] = new Rectangle(10);
shapes[2] = new Rectangle(10, 4);
shapes[3] = new Triangle(7.0);
shapes[4] = new TwoDShape(10, 20, "общая форма");
for (int i=0; i < shapes.Length; i++) {
Console.WriteLine("Объект — " + shapes[i].name);
Console.WriteLine("Площадь равна " + shapes[i].Area());
Console.WriteLine();
}
}
}
При выполнении этой программы получается следующий результат.
Объект — треугольник
Площадь равна 48
Объект — прямоугольник
Площадь равна 100
Объект — прямоугольник
Площадь равна 40
Объект — треугольник
Площадь равна 24.5
Объект — общая форма
Метод Area() должен быть переопределен
Площадь равна 0
Рассмотрим данный пример программы более подробно. Прежде всего, метод Area()
объявляется как virtual
в классе TwoDShape
и переопределяется в классах Triangle
и Rectangle
по объяснявшимся ранее причинам. В классе TwoDShape
метод Area()
реализован в виде заполнителя, который сообщает о том, что пользователь данного метода должен переопределить его в производном классе. Каждое переопределение метода Area()
предоставляет конкретную его реализацию, соответствующую типу объекта, инкапсулируемого в производном классе. Так, если реализовать класс для эллипсов, то метод Area()
должен вычислять площадь эллипса.
У программы из рассматриваемого здесь примера имеется еще одна примечательная особенность. Обратите внимание на то, что в методе Main()
двумерные формы объявляются в виде массива объектов типа TwoDShape
, но элементам этого массива присваиваются ссылки на объекты классов Triangle
, Rectangle
и TwoDShape
. И это вполне допустимо, поскольку по ссылке на базовый класс можно обращаться к объекту прризводного класса. Далее в программе происходит циклическое обращения к элементам данного массива для вывода сведений о каждом объекте. Несмотря на всю свою простоту, данный пример наглядно демонстрирует преимущества наследования и переопределения методов. Тип объекта, хранящийся в переменной ссылки на базовый класс, определяется во время выполнения и соответственно обусловливает дальнейшие действия. Так, если объект является производным от класса TwoDShape
, то для получения его площади вызывается метод Area()
. Но интерфейс для выполнения этой операции остается тем же самым независимо от типа используемой двумерной формы.
Применение абстрактных классов
Иногда требуется создать базовый класс, в котором определяется лишь самая общая форма для всех его производных классов, а наполнение ее деталями предоставляется каждому из этих классов. В таком классе определяется лишь характер методов, которые должны быть конкретно реализованы в производных классах, а не в самом базовом классе. Подобная ситуация возникает, например, в связи с невозможностью получить содержательную реализацию метода в базовом классе. Именно такая ситуация была продемонстрирована в варианте класса TwoDShape
из предыдущего примера, где метод Area()
был просто определен как заполнитель. Такой метод не вычисляет и не выводит площадь двумерного объекта любого типа.
Создавая собственные библиотеки классов, вы можете сами убедиться в том, что у метода зачастую отсутствует содержательное определение в контексте его базового класса. Подобная ситуация разрешается двумя способами. Один из них, как показано в предыдущем примере, состоит в том, чтобы просто выдать предупреждающее сообщение. Такой способ может пригодиться в определенных ситуациях, например при отладке, но в практике программирования он обычно не применяется. Ведь в базовом классе могут быть объявлены методы, которые должны быть переопределены в производном классе, чтобы этот класс стал содержательным. Рассмотрим для примера класс Triangle
. Он был бы неполным, если бы в нем не был переопределен метод Area()
. В подобных случаях требуется какой-то способ, гарантирующий, что в производном классе действительно будут переопределены все необходимые методы. И такой способ в C# имеется. Он состоит в использовании абстрактного метода.
Интервал:
Закладка: