C# наследование метода

Конструкторы и наследование

В иерархии классов допускается, чтобы у базовых и производных классов были свои собственные конструкторы. В связи с этим возникает следующий резонный вопрос: какой конструктор отвечает за построение объекта производного класса: конструктор базового класса, конструктор производного класса или же оба? На этот вопрос можно ответить так: конструктор базового класса конструирует базовую часть объекта, а конструктор производного класса — производную часть этого объекта. И в этом есть своя логика, поскольку базовому классу неизвестны и недоступны любые элементы производного класса, а значит, их конструирование должно происходить раздельно.

Если конструктор определен только в производном классе, то все происходит очень просто: конструируется объект производного класса, а базовая часть объекта автоматически собирается его конструктором, используемым по умолчанию.

Когда конструкторы определяются как в базовом, так и в производном классе, процесс построения объекта несколько усложняется, поскольку должны выполняться конструкторы обоих классов. В данном случае приходится обращаться к ключевому слову base, которое находит двоякое применение: во-первых, для вызова конструктора базового класса; и во-вторых, для доступа к члену базового класса, скрывающегося за членом производного класса.

С помощью формы расширенного объявления конструктора производного класса и ключевого слова base в производном классе может быть вызван конструктор, определенный в его базовом классе. Ниже приведена общая форма этого расширенного объявления:

где список_аргументов обозначает любые аргументы, необходимые конструктору в базовом классе. Обратите внимание на местоположение двоеточия.

Давайте рассмотрим пример:

С помощью ключевого слова base можно вызвать конструктор любой формы, определяемой в базовом классе, причем выполняться будет лишь тот конструктор, параметры которого соответствуют переданным аргументам.

А теперь рассмотрим вкратце основные принципы действия ключевого слова base. Когда в производном классе указывается ключевое слово base, вызывается конструктор из его непосредственного базового класса. Следовательно, ключевое слово base всегда обращается к базовому классу, стоящему в иерархии непосредственно над вызывающим классом. Это справедливо даже для многоуровневой иерархии классов. Аргументы передаются базовому конструктору в качестве аргументов метода base(). Если же ключевое слово отсутствует, то автоматически вызывается конструктор, используемый в базовом классе по умолчанию.

Основы наследования

Наследование является одним из трех основополагающих принципов объектно-ориентированного программирования, поскольку оно допускает создание иерархических классификаций. Благодаря наследованию можно создать общий класс, в котором определяются характерные особенности, присущие множеству связанных элементов. От этого класса могут затем наследовать другие, более конкретные классы, добавляя в него свои индивидуальные особенности.

В языке C# класс, который наследуется, называется базовым, а класс, который наследует, — производным. Следовательно, производный класс представляет собой специализированный вариант базового класса. Он наследует все переменные, методы, свойства и индексаторы, определяемые в базовом классе, добавляя к ним свои собственные элементы.

Поддержка наследования в C# состоит в том, что в объявление одного класса разрешается вводить другой класс. Для этого при объявлении производного класса указывается базовый класс. При установке между классами отношения «является» строится зависимость между двумя или более типами классов. Базовая идея, лежащая в основе классического наследования, заключается в том, что новые классы могут создаваться с использованием существующих классов в качестве отправной точки:

Всякий раз, когда один класс наследует от другого, после имени производного класса указывается имя базового класса, отделяемое двоеточием. В C# синтаксис наследования класса удивительно прост и удобен в использовании. Ниже представлено схематичное представление класса CSharp из вышеуказанного примера:

Как видите класс CSharp получает доступ к полям и методам класса ProfessorWeb. Всегда помните, что наследование предохраняет инкапсуляцию, а потому приватные члены никогда не могут быть доступны через ссылку на объект. Т.е. поле inf из примера не может быть доступно для вызова с помощью экземпляра класса obj.

Для любого производного класса можно указать только один базовый класс. В C# не предусмотрено наследование нескольких базовых классов в одном производном классе. (В этом отношении C# отличается от С++, где допускается наследование нескольких базовых классов. Данное обстоятельство следует принимать во внимание при переносе кода С++ в C#.) Тем не менее можно создать иерархию наследования, в которой производный класс становится базовым для другого производного класса. (Разумеется, ни один из классов не может быть базовым для самого себя как непосредственно, так и косвенно.) Но в любом случае производный класс наследует все члены своего базового класса, в том числе переменные экземпляра, методы, свойства и индексаторы.

Главное преимущество наследования заключается в следующем: как только будет создан базовый класс, в котором определены общие для множества объектов атрибуты, он может быть использован для создания любого числа более конкретных производных классов. А в каждом производном классе может быть точно выстроена своя собственная классификация.

Наследование в C#

Всем доброго времени суток. На связи Алексей Гулынин. В прошлой статье вы узнали немного о том, что такое делегаты в C#. В данной статье я бы хотел рассказать про наследование в C#. Простыми словами, «Наследование» означает то, что мы создаём класс на основе другого. Получается, у нас есть родительский класс и дочерний класс, который наследует все поля и методы родительского класса. Для того, чтобы понять, что такое наследование и для чего его нужно использовать, вернёмся к понятию объекта.

Объект представляет собой некую абстрактную сущность. Допустим мы хотим создать класс «Animal» (Животное). Но животных же существует великое множество и вряд ли мы одним классом сможем описать их всех. В классе «Animal» мы можем создать поля и методы, присущие всем животным. Например, полями общими для всех животных могут быть «Вес», «Средняя продолжительность жизни», «Имеется хвост или нет». Методом может быть «eat()» (кушать), ведь все же животные питаются. От такого общего класса мы можем создать дочерний класс, который расширяет родительский класс. Например, класс «Dog» (собака) может расширять класс «Animal» уже конкретными полями и методами, которые соответствуют именно собакам.

Отношение наследования — это отношение перехода от более общей абстракции к более конкретной.

В C# наследование является одиночным, то есть нельзя наследоваться от двух и более классов. Наследование определяется через «:».

Интересный момент: если вы пишете обычный класс, который не имеет родителя, то, по умолчанию, этот класс является наследником класса «Object». Класс «Object» является родителем абсолютно для всех классов в .NET.

Немного поговорим про понятия, так или иначе связанные с наследованием.

Абстрактный класс — это класс, объекты которого нельзя создавать, т.е. нельзя будет использовать ключевое слово «new». Абстрактные классы используются при наследовании и используются как прародители к другим классам (реальным, не абстрактным). Т.е. в нашем примере можно класс «Animal» пометить как «abstract». Абстрактным может быть также и метод (это метод без реализации). Если в классе присутствует хотя бы один абстрактный метод, то и сам класс обязан быть абстрактным. В обратную сторону правило не действует.

С помощью ключевого слова «sealed» можно запретить создавать наследников от класса. Пример: класс «String». От этого класса мы не сможем создать наследников. Применение ключевого слова «sealed» к методу означает, что мы запрещаем переопределение этого метода в классах-наследниках.

Ключевое слово «virtual» применяется только к методам, и используется для того, чтобы превратить метод в виртуальный. Это делается для того, чтобы метод можно было переопределить в классах-наследниках. Переопределение метода означает, что мы внутри класса-наследника создаём метод, у которого заголовок полностью совпадает с заголовком метода класса-родителя. При этом в классе-наследнике нужно указать ключевое слово «override», чтобы явно указать, что мы переопределяем метод.

Давайте на примере разберем всё то, что мы только что узнали. Для простоты все поля и методы сделаем публичными (в реальных программах так, конечно, делать не нужно):

Конструкторы при наследовании.

Конструкторы не наследуются. Если в родительском классе определены различные конструкторы, то при наследовании эти конструкторы будут недоступны у класса-наследника. Несмотря на то, что конструкторы не наследуются — они автоматически вызываются. Когда вызывается конструктор класса-наследника автоматом вызывается конструктор класса-родителя. По умолчанию будет вызываться дефолтный конструктор класса-наследника без параметров. Обращаю ваше внимание на то, что если такого конструктора без параметров не будет, то будет получена ошибка при компиляции.

Если мы хотим, чтобы вызывался другой родительский конструктор, то это можно указать с помощью ключевого слова «base» .

С помощью «base» также можно вызывать родительский метод.

Разберем на эту тему вот такой пример: пусть имеется родительский класс «Degree», имеющий одной поле «degrees» и один метод, который возвращает значение данного поля. Создадим дочерний класс «Radiance», который, используя метод родительского класса, возвращает градусы, переведенные в радианы:

Напоследок, обобщу особенности наследования:

  • Ключевые слова «sealed» и «static» (статический класс, про него поговорим в отдельной статье) запрещают наследование
  • Если в базовом классе определен какой-то метод «abstract», то базовый класс тоже должен быть абстрактным. В классе-наследнике такой абстрактный метод нужно переопределить. Абстрактный метод, по умолчанию, является виртуальным.
  • При проектировании программы важным является понимание того, что от чего можно унаследовать, а что нельзя. Для проверки условия наследования используется слово «является». В нашем примере: «Собака является животным? — является», «Питбуль является собакой? — является». А вот наоборот лучше не делать (технически конечно можно, но программы лучше сразу проектировать правильно), «Животное является собакой? — не является». Поэтому класс «Animal» от класса «Dog» наследовать нельзя.

В данной статье вы узнали про механизм наследования в C# и о том, как его лучше использовать.

На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.

C# наследование метода

Рассмотрим основные принципы наследование классов в C#.

Вспомним из предыдущей статьи синтаксис класса:

[атрибуты]
[модификаторы] class Имя_класса : [родитель]
<
>
Под родителем понимается класс, от которого наследуется данный. Существует несколько понятий, имеющих одно и то же значение, обозначающие наследуемый класс — базовый класс (base class) , родительский класс (parent class), предок. Класс, который наследует, называется производным, потомком или наследником. Потомок наследует все поля, свойства, методы, индексаторы, операторы от предка, помеченные соответствующим модификатором доступа. Кроме этого он может иметь собственные элементы или переопределить существующие.
Наследование можно рассмотреть на примере класса Point2D и класса Point3D, который от него наследуется.

class Point2D
<
protected double x; // поле доступно только в производных классах
protected double y; // поле доступно только в производных классах
public Point2D(double x, double y)
<
this.x = x;
this.y = y;
>
protected Point2D()
:this(0,0)
< >
>

class Point3D : Point2D
<
private double z;
Point3D(double x, double y, double z)
:base(x,y)
<
this.z = z;
>
>

В данном случае класс Point3D наследует переменные x, y, а также конструктор базового класса. Параметр base действует аналогично this, только используется он всегда для доступа к членам класса-предка, в то время как this — ссылается на текущий экземпляр класса. В этом случае часть объекта, соответствующая базовому классу, создается через вызов его конструктора. А часть, соответствующая производному, — с помощью конструктора потомка. Через параметр base можно вызвать любой конструктор базового класса с соответствующими параметрами.
Добавим по методу GetRadius() в оба класса:

// в Point2D
public double GetRadius()
<
return Math.Sqrt(x * x + y * y);
>
// в Point3D
public new double GetRadius()
<
return Math.Sqrt(x * x + y * y + z * z);
>

Это называется перекрытием метода, а точнее скрытием. В данном случае модификатор new явно скрывает базовый метод GetRadius() и заменяет его методом в производном классе.
Класс, помеченный модификатором sealed не может быть унаследован.

0. В «синтаксисе класса» навскидку пропущено два пункта. Если пропустили сознательно — почему бы не написать «в упрощенном синтаксисе класса» или что-то вроде этого?

1. В предыдущей статье ошибка — у класса может быть только один родитель.

2. Зачем?
protected Point2D()
:this(0,0)

3. protected double x; // поле доступно только в производных классах
В комментарии оговорка, еще и в объекте этого класса.

4. В данном случае класс Point3D наследует переменные x, y, а также конструктор базового класса
Point3D наследует конструктор базового класса? Почему же пример ниже не работает? ?
Point3D point = new Point3D (3, 4);

5. Последний пример (с сокрытием метода) явно вредный. Люди потом удивляются, почему же код вроде этого работает через ..опу?

Point2D point = new Point3D(3, 4, 5);
Console.WriteLine(point.GetRadius);

6. Про всякие «оговорки» вроде «this ссылается на этот класс» (к которым придираются на собеседованиях/экзаменах) даже говорить не буду.

Вот честное слово, так люблю читать твои комментарии. Они всегда конструктивные. Автор статьи в ближайшее время ответит на них.

0. Как угодно, «упрощенный синтаксис». Тут цель — просто показать запись класса-предка в объявлении.
1. Конечно, исправил.
2. Если честно, не понял вопроса. Не нравится, что нулевые значения передаются?
3. Согласен.
4. Я фигню написал.) Конструкторы классов наследников вызывают конструкторы класса-предка, например, непараметризованный конструктрор Point3D() будет вызывать Point2D(). Мы можем только явно указать, какой из конструкторов будет вызываться.
5. Ну я не написал, что это приветствуется. Просто надо знать, что такая вещь есть.
6. Ссылается на текущий экземпляр класса.

Спасибо Вам за обучающую информацию. Очень много полезного для начинающих. Есть пара вопросов:
1. Будет ли продолжение статей по С#?
2. Есть ли у Вас какой-нибудь сборник задач по программированию? Для разных уровней мастерства)
А в остальном еще раз спасибо за сайт)

C# наследование метода

ZORK>Более конкретно смотри раздел 10.5.5 в C# спецификации

Пардон, я та глубоко не рыл. Смотрел по книге Э. Руннерсона «Введение в C#» (она есть в RSDN
Ресурсы/Книги/.Net). Там говорится о sealed только для классов. На будущее буду знать.

Здравствуйте Mishka, Вы писали:

M>Всем спасибо! Действительно работает.

Слушай, а зачем тебе нужно помечать виртуальный метод как saled? Я просто немогу себе представить такой ситуации. 🙁

Здравствуйте VladD2, Вы писали:

VD>Здравствуйте Mishka, Вы писали:

M>>Всем спасибо! Действительно работает.

VD>Слушай, а зачем тебе нужно помечать виртуальный метод как saled? Я просто немогу себе представить такой ситуации. 🙁

Ну такие потребности настпают, когда работаешь с многоуровневым коллекитивом программистов, или просто делаешь библиотеку классов для третей компании. Тогда, может оказаться что тебе надо виртуальный метод, для того чтобы исползьзвать полиморфизм в своей библиотек, но с другой стороны, может быть важно что-бы пользователи этой библиотеки не могли так просто изменить поведение базовых классов — так как при их неосведомленость о дизайне библиотеки, ни до чего хорошего не доведет.

С этим очевидно можно спорить, но например в американском контрактно программировнии я нашел важным иметь возиможность защитить свои классы и код в целом на уровне дизайна. Например: не дать возможно сломать твои классы, простым наследованием и писанием всякой ерунды — от непонимания.

Это интересно:

  • Autodesk учебное пособие Autodesk учебное пособие Издательство: Вузовское образование Автор: Алпатова Н.С., Карпова С.А., Федосеева Е.С. Год издания: 2018 Издательство: Вузовское образование Автор: Бобров А.А. Год издания: 2018 Издательство: Ай Пи Эр Медиа Автор: Седов В.А., Седова Н.А. Год издания: […]
  • Услуги юриста благовещенск УСЛУГИ АДВОКАТОВ В БЛАГОВЕЩЕНСКЕ Вам нужны услуги адвоката или юридическая помощь в Благовещенске? Выбор адвоката – задача не из легких. Из сотен специалистов, называющих себя адвокатами, необходимо выбрать одного, своего, которому можно полностью довериться, который сможет грамотно и в […]
  • Взыскание неустойки с застройщика услуги Сколько стоят услуги юриста по взысканию неустойки с застройщика Застройщик КСК (Спб) задерживает срок сдачи квартиры. По договору ДДУ должен был передать 31.12.2015г. Квартира 40м2, приобретена в ипотеку. На что можно рассчитывать и сколько будут стоить услуги юриста (акта приема […]
  • Регулирующие налоги кодекс Регулирующие налоги кодекс Порядок формирования региональных и местных бюджетов характеристика доходных источников, состав и порядок формирования расходных статей, понятие минимального бюджета, оценка доли закрепленных и регулирующих налогов, обоснование нормативов налогов и платежей, […]
  • Статистика по несовершеннолетним 2013 Современное состояние преступности несовершеннолетних в России Уголовная политика Российской Федерации в настоящее время продолжает оставаться нестабильной, носит несистемный характер [10, с. 21], в стране отсутствует четкое понимание того, каким образом должно осуществляться […]
  • Когда кончается страховка Когда кончается страховка Получите квалифицированную помощь прямо сейчас! Наши адвокаты проконсультируют вас по любым вопросам вне очереди. Штраф за просроченную страховку ОСАГО в 2018 году и сколько можно ездить без страховки после ее окончания У многих документов имеется срок действия, […]
  • Приказы о зачислении в кгму 2018 Нормативные документы Приемная комиссия Прием по образовательным программам высшего образования - программам бакалавриата, программам специалитета прием иностранных граждан в КГМУ На нашем сайте вы найдете всю необходимую информацию о правилах поступления в наш вуз, способах и сроках […]
  • Правила возврата обмена бытовой техники Самозащита потребителя Возврат бытовой техники в магазин Возврат бракованной бытовой техники Почти любая бытовая техника, кроме разве что пылесосов, подходит под перечень технически сложных товаров утвержденный Постановлением Правительства РФ от 10 ноября 2011 г. N 924 в связи с этим […]

Author: admin