Учебные материалы по математике | Синтаксис наследования | Matematiku5
Вузы по математике Готовые работы по математике Как писать работы по математике Примеры решения задач по математике Решить задачу по математике online

Синтаксис наследования


Рыбы Млекопитающие Птицы

 

Акула Карась Дельфин Слон Пингвин Петух

Пресмыкающиеся Насекомые

Динозавр Блоха

Это тривиальная классификация, а вернее её отсутствие, т. к. реальные классификации заглублённые. Это, фактически, напоминание о том, что иерархия существует и всякая наука начинается с систематизации знаний.

Синтаксис наследования:

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

Class (Имя класса потомка): (Имя класса предка)

{

}

Пример: класс Bird (Птица) наследует класс Vertebrate (Позвоночное)

class Vertebrate // класс "Позвоночное животное"

{

public int NumberOfLegs;

public void Eat()

{

//код, заставляющий есть

}

}

class Bird : Vertebrate //расширяется класс путём добавления в конец его двоеточия и имени базового класса

{

public double Wingspan;

public void Fly()

{

//код, заставляющий летать

}

}

class Program

{//запускалка:

static void Main()

{

//так как tweety — это экземпляр объекта Bird, то он имеет методы и поля этого объекта

Bird tweety = new Bird();

tweety. Wingspan = 7.5; // tweety-название птички

tweety. Fly();

//т. к. класс Bird — производный по отношению к классу Vertebrate, все экземпляры Bird имеют поля и методы, определённые в классе Verteble

tweety. NumberOfLegs = 2;

tweety. Eat();

}

}

С точки зрения наследования все классы являются потомками класса cObject.

Таким образом, понятие наследования — это попытка определить понятие подтипа или подкласса. Всякого рода явные преобразования возможны, а средства явного преобразования типов есть. Грубо говоря, это схема «всё-во-всё». Реализация очевидна: всё рассматривается на уровне двоичных полей.

Открытие реализации для проектирования классов — опция protected

Для реализации ограничения доступа применяется модификатор доступа — PROTECTED.

protected- виден классам-наследникам. Это даёт возможность скрыть от наследников переменную так, чтобы они не «напортачили» в ней.

-internal — модификатор доступа, который используется для методов, доступных всем классам, определённым в конкретной сборке

//Задача: Черепашья графика. Простая модель управления роботом-черепашкой, которая рисует на дискретной сетке.

using System;

using System. Collections. Generic;

using System. Linq;

using System. Text;

namespace Turtle//логически связанное определение имён

{

enum tColor {red, green, blue} //перечисляемый тип, состоящий из цветов

class cCell

{

protected internal tColor Color; // определение переменной Color типа tColor

//set-get:

public tColor GetColor() {return Color;}

cCell (tColor Color) {this. Color= Color;} // конструктор

} //class cCell

class cGrid //сетка

{

protected int Dim; //размерность

public int GetDim() {return Dim;}

protected internal cCell [,] Grid; //сама сетка(массив Grid) типа cCell (т. е. перечисляемого типа {red, green, blue})

// текущая позиция

protected internal int CurrentX; //, где internal означает то, что доступ ограничен текущей сборкой,

//а protected означает, что доступ ограничен содержащим классом или типами, которые являются производными от содержащего класса.

protected internal int CurrentY;

public int GetCurrentX() {return CurrentX; }

public int GetCurrentY() {return CurrentY; }

protected void Move (int x, int y )

{

//модульная арифметика(выход за границы)

CurrentX+=x; //эквивалентно выражению CurrentX = CurrentX + x

CurrentY+=y;

} // Move

cGrid (int Dim, tColor Color) //конструктор

{

this. Dim= Dim;

CurrentX=0;

CurrentY=0;

Grid= new cCell [Dim, Dim];

for (int i= 0; i<Dim; i++)

for (int j=0; j<Dim; j++)

Grid [i, j].Color= Color;

}

}

class TurtleGraphics: cGrid

{

//поля

public bool PenDown;// состояние пера — карандаш

public tColor PenColor;

public void GoUp()

{

Move(0,1);

if (PenDown) Grid[CurrentX, CurrentY].Color = PenColor;

}//PenGoUp

public void GoRight()

{

Move(1,0);

if (PenDown) Grid[CurrentX, CurrentY]. Color = PenColor;

}//PenRight

public void GoLeft()

{

Move(-1,0);

if (PenDown) Grid[CurrentX, CurrentY]. Color = PenColor;

}//PenLeft

public void GoDown ()

{

Move(0,-1);

if (PenDown) Grid[CurrentX, CurrentY]. Color = PenColor;

}//PenDown

}//class TurtleGraphics: cGrid

class Program

{ //запускалка

static void Main ()

{

}

}//class Program

}//namespace TurtleGraphics

Итак, появляются отношения использования и отношения наследования.

Полиморфизм

Полиморфизм как уточнение семантики типа переменной

Полиморфизм (многообразие) — возможность уточнения (изменения) не только значений, состояний объекта, но и поведения объекта, то есть связанных с ним функций изменения состояния или алгоритмов реализации (изменение (уточнение) фактического типа переменной в ходе выполнения программы).

Описание типа переменной теперь означает лишь присвоение начального типа по умолчанию.

Тип

Строгая типизация – алгоритмика (типы минимизируют ошибки алгоритмов). Поэтому тип переменной описывается до появления переменной. Строгая типизация ориентирована на создание надёжных программ.

Бестиповая логика — свободная типизация (например, языки низкого уровня (ассемблер)). Свободная типизация ближе к системному программированию (ближе к эффективным реализациям)

Полиморфизм радикально изменяет взгляд на понятие типа. Если раньше переменная принадлежала одному фиксированному типу, то теперь она изменяет его, то есть тип становится атрибутом переменной.

Полиморфное программирование – сложное программирование ещё и потому, что не во всём адекватно поддерживается реализация.

Пример:

Пусть Dad – объект класса cDad,

Son – выражение класса cSon, где cDad – предок cSon в отношении наследования.

1) Присваивание Son:=Dad — синтаксическая ошибка.

Допустимо явное присваивание типов переменной любого класса любому другому классу:

Son:=Dad as cSon; — не является синтаксической ошибкой, но обращение к полям и методам сына, отсутствующим у отца, будет ошибкой времени выполнения.

2) В любом случае допустимо присваивание:

Dad:=Son и, соответственно, употребление выражений типа cSon вместо значений типа cDad, например, при обращении к процедуре.

Замечание:

Как всегда происходит присваивание ссылок. Это означает, что ссылка на предыдущие значения, связанная со ссылкой Dad, будет потеряна. Переменная Dad изменяет свой тип с формально описанного статического типа cDad на фактический тип cSon.

Что это означает для значений? Преображает ли Dad новые поля?

Фактически – да, формально – нет. Для таких полей обращение Dad. p неверно, а верно (Dad as cSon).p, где оператор as используется для выполнения определенных типов преобразований между совместимыми ссылочными типами.

Точно так же дело обстоит с методами, которые есть у сына, но нет у отца.

Изменяются ли значения, то есть реализация одноимённых функций?

1)  Да, если таковые при объявлении класса cDad объявлены как виртуальные (virtual) или динамические (dynamic) (одна семантика, разная реализация), а при определении класса cSon – как переписывающие метод предка (override).

Наташа

Автор

Наташа — контент-маркетолог и блогер, но все это не мешает ей оставаться адекватным человеком. Верит во все цвета радуги и не верит в теорию всемирного заговора. Увлекается «нефрохиромантией» и тайно мечтает воссоздать дома Александрийскую библиотеку.

Распродажа дипломных

 Скидка 30% по промокоду Diplom2020