}
public string name { get; set; } public void ShowDimO {
Console.WriteLine("Ширина и высота равны " +
Width + " и " + Height);
}
// Теперь метод Area() является абстрактным, public abstract double Area();
}
// Класс для треугольников, производный от класса TwoDShape. class Triangle : TwoDShape { string Style;
// Конструктор, используемый по умолчанию, public Triangle() {
Style = "null";
}
// Конструктор для класса Triangle, public Triangle(string s, double w, double h) : base(w, h, "треугольник") {
Style = s;
I/ Сконструировать равнобедренный треугольник, 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 AbsShape {
static void Main() {
TwoDShape[] shapes = new TwoDShape[4];
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);
for(int i=0; i < shapes.Length; i++) {
Console.WriteLine("Объект — " + shapes[i].name);
Console.WriteLine("Площадь равна " + shapes[i].Area());
Console.WriteLine() ;
}
}
> t
Как показывает представленный выше пример программы, во всех производных классах метод Area () должен быть непременно переопределен, а также объявлен абстрактным. Убедитесь в этом сами, попробовав создать производный класс, в котором не переопределен метод Area (). В итоге вы получите сообщение об ошибке во время компиляции. Конечно, возможность создавать ссылки на объекты типа TwoDShape по-прежнему существует, и это было сделано в приведенном выше примере программы, но объявлять объекты типа TwoDShape уже нельзя. Именно поэтому массив shapes сокращен в методе Main () до 4 элементов, а объект типа TwoDShape для общей двухмерной формы больше не создается.
Обратите также внимание на то, что в класс TwoDShape по-прежнему входит метод ShowDim () и что он не объявляется с модификатором abstract. В абстрактные классы вполне допускается (и часто практикуется) включать конкретные методы, которые могут быть использованы в своем исходном виде в производном классе. А переопределению в производных классах подлежат только те методы, которые объявлены как abstract.
Предотвращение наследования с помощью ключевого слова sealed
Несмотря на всю эффективность и полезность наследования, иногда возникает потребность предотвратить его. Допустим, что имеется класс, инкапсулирующий последовательность инициализации некоторого специального оборудования, например медицинского монитора. В этом случае требуется, чтобы пользователи данного класса не могли изменять порядок инициализации монитора, чтобы исключить его неправильную настройку. Но независимо от конкретных причин в C# имеется возможность предотвратить наследование класса с помощью ключевого слова sealed.
Для того чтобы предотвратить наследование класса, достаточно указать ключевое слово sealed перед определением класса. Как и следовало ожидать, класс не допускается объявлять одновременно как abstract и sealed, поскольку сам абстрактный класс реализован не полностью и опирается в этом отношении на свои производные классы, обеспечивающие полную реализацию.
Ниже приведен пример объявления класса типа sealed.
sealed class А {
// . . .
}
// Следующий класс недопустим.
class В : A { // ОШИБКА! Наследовать класс А нельзя / / ...