- •Вопрос 2) Понятие класса и объекта
- •Вопрос 3) Структура класса и синтаксис декларации класса
- •Вопрос 4) Доступ к членам класса. Закрытые и открытые члены класса.
- •Вопрос 5) Принцип инкапсуляции
- •Вопрос 6) Методы. Способы передачи параметров
- •Вопрос 7) Реализация методов класса. Конструкторы и деструкторы. Методы и их параметры
- •Конструкторы и деструкторы
- •Вопрос 8) Полиформизм, перегрузка методов
- •Виртуальные методы
- •Абстрактные классы
- •Вопрос 10) Интерфейсы c#
- •Вопрос 11) Классы и структуры Класс
- •Вопрос 12) Создание нового экземпляра класса.
- •13. Преобразование методов базового класса. Вызов методов базового класса.
- •Вопрос 14) Свойства и методы в ооп
- •Вопрос 15) События и методы в ооп События
- •Вопрос 16) Индексаторы с#
- •Вопрос 17) Делегаты в классах с#
- •Вопрос 18) Обобщенные классы или шаблоны.
Вопрос 12) Создание нового экземпляра класса.
Одна из возможностей передачи свойств нескольких классов другому классу - это создание экземпляров классов. Тогда возможно будет вызвать методы и переменные этих классов через вызов этих классов. Этот механизм не является в полном смысле слова механизмом наследования, однако он предусматривает передачу свойств одного класса (как бы суперкласса) другому (подклассу).
Чтобы создать экземпляр класса нужно воспользоваться оператором new:
MyNewClass mNewCl = new MyNewClass ();
Переменной mNewCl типа MyNewClass (напомню, что типом любого элемента может быть как встроенный тип, так и имя любого существующего класса).
В одном и том же классе можно создать несколько экземпляров одного и того же класса, присвоив его значения двум или нескольким переменным. В приведенном ниже примере создается два экземпляра класса Thread (подпроцессы):
Thread firstThread = Thread.currentThread ();
Thread secondThread = new Thread (this, "Second Thread");
Теперь чтобы вызвать, например, метод isAlexanderVanin класса MyNewClass (смотрите первый пример), нужно записать следующий код:
mNewCl.isAlexanderVanin ();
Оператор точка служит для отделения имени пакетов от имен вложенных пакетов и классов, входящих в пакет, а также имени класса от имени переменной или метода, принадлежащих этому классу.
13. Преобразование методов базового класса. Вызов методов базового класса.
Основные определения
Класс — это тип данных, описывающий устройство объектов и подразумевает некоторое поведение и способ представления.
Объект — это экземпляр некоторого класса.
Метод — это функция или процедура, принадлежащая какому-то классу или объекту.(поведение)
Наследование — это вид взаимодействия классов, при котором есть класс родитель и класс потомок.
1) Класс потомок наследует все методы и поля родителя;
2) Потомок может добавлять свои поля и методы или переопределять методы родителя.
В результате наследование часто необходимо переопределить методы, которые были в базовом классе. Под базовым классом понимается класс родителя. Полиморфизм — использование одного и того же имени для решения нескольких похожих, но разных по реализации задач. Например, метод "Ехать" объекта - экземпляра класса "Корабль" наверняка отличается от метода "Ехать" объекта класса "Машина".
С++
class Car
{
public:
double Benzin; // бензин
void Go( float dist )
{
Benzin -= dist / 10; // 1 литр бенза на 10 км
Rasst += dist; // проехали
}
protected: double Rasst; // пройденное расстояние};
class Truck : public Car
{
public int K;
void Go( float dist )
{
Benzin -= dist / 5; // 1 литр бенза на 5 км
Rasst += dist; // проехали
}
};
Стандартны следующие декларации объектов:
Car * car = new Car;
Truck * truck = new Truck;
Однако принцип полиморфизма допускает и такую запись:
Car * car = new Truck;
Переменная ссылочного, более общего типа допускает хранение ссылки на дочерний тип.
А вот запись Truck * truck = new Car;
будет ошибочной. Однако можно принудительно выполнить подобный оператор, если явно указать приведение типов:
Truck * truck = (Truck*)(new Car);
Здесь создается новый экземпляр класса Car, и ссылка на него приводится к типу ссылки на объект класса Truck. В результате в переменных car и truck будут храниться ссылки на объекты других классов! Переменая car хранит ссылку на объект-грузовик, наследник Car, а переменная truck хранит ссылку на экземпляр родительского класса Car.
Теперь зададим вызовы метода Go(), который имеется и в классе Car, и в классе Truck:
Car * car = new Truck;
car->Go(100);
Truck * truck = (Truck*)(new Car);
truck->Go(100);
Какие конкретно версии метода Go() будут вызваны - класса Car или Truck? Это и определяет принцип полиморфизма. В соответствии с ним в языке С++ определены так называемые статическое связывание и динамическое связывание. Связывание методов с объектом.
Статическое связывание - это связывание метода с родительским объектом на этапе компиляции. Так как компилятор не знает, как конкретно будет работать программа, он всегда исходит из известного и явно заданного типа объекта-владельца метода. Если используется переменная car класса Car, то будет вызван метод Go() класса Car, хотя физически в переменной car хранится экземпляр класса Truck.
Так же и в случае с переменной truck - хотя мы принудительно записали в нее ссылку на объект класса Car, компилятор об этом не знает и исходит из типа переменной truck - вызывает метод Go() класса Truck.
Динамическое связывание - это связывание метода с объектом, которое происходит во время работы программы. При этом нужный метод определяется уже не типом переменной-владельца, а реальным типом объекта, ссылку на который она хранит. Но такое связывание возможно только для так называемых виртуальных методов, - разделение типов методов нужно, чтобы подсказать компилятору, где какое связывание реализовывать.
Виртуальный метод - это обычный метод, в заголовке которого используется ключевое слово virtual. Например:
class Car
{
public: ...
virtual void Go( float dist )
{
...
}
…
}
Теперь метод Go() класса Car описан как виртуальный. Пусть имеются команды
Truck * truck = (Truck*)(new Car);
truck->Go(100);
Если бы метод Go() класса Car был невиртуальным, то выполнилось бы статическое связывание. Но в данном случае вызывается метод Go() класса Car, потому что переменная truck типа Truck хранит ссылку на экземпляр класса Car.
C#
Под полиморфизмом понимается возможность оперировать объектами, не обладая точными знаниями их типов.
В ООП понятие полиморфизм тесно связан с наследованием и интерфейсами.
Интерфейсы(функции с множеством элементов; четко определенные соглашения)
Типы(определяют на интерфейсы объектов и их реализации; переменные могут быть также типизированными)
void Poly(object o)
{
Console.WrieLine(o.ToString());
}
Приведенный пример представляет собой описание полиморфной функции Poly, которая выводит на монитор произвольный объект o, преобразованный к строковому формату (o.ToString())
Применения функции Poly:
Poly(25); Poly(“John”); Poly(3,14)
Заметим, что независимо от типа аргумента(в первом случаи это целое число, во втором – символьная строка, в третьем – вещественное число), обработка происходит единообразно, функция генерирует корректный результат.