Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Н.Р. Бухараев (3 семестр)(ООП в интегрированной...doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.41 Mб
Скачать

Основные отличия интерфейса и абстрактного класса

1) -абстрактный класс может содержать свойства

-интерфейс не содержит свойств

2) -абстрактный класс может содержать тела методов

-интерфейс не содержит тел методов, только их объявление

3) -абстрактный класс наследуется (etxends)

-интерфейс реализуется (implements)

4) -наследник в абстрактном классе имеет только одного родителя

-наследник может реализовывать методы нескольких интерфейсов

5) -наследник не обязан содержать реализацию методов абстрактного класса-родителя

-наследник обязан содержать реализацию всех методов реализуемого интерфейса

Следовательно, интерфейс не часть класса, а частный случай - абстрактный класс, наследование которого обязывает к реализации.

Пример: иерархия животных (основная - по строению, вторичная - по передвижению):

// Компонентно-ориентированное программирование

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks; // предоставляет типы, которые упрощают работу по написанию параллельного и асинхронного кода

namespace Hierarchy

{

class cAnimals

{

protected string Name;

public void SetName(string x)

{

this.Name = x;

}

public string GetName()

{

return Name;

}

public cAnimals() // конструктор по умолчанию

{

}

public cAnimals(string x) // конструктор

{

this.Name = x;

}

}

class cMammals : cAnimals // класс «Млекопитающие», который наследуется от класса «Животные»

{

}

class cFishes : cAnimals // класс «Рыбы»

{

}

class cBirds : cAnimals // класс «Птицы»

{

}

//Разница между интерфейсами и абстрактными классами

//предок обязан / может дать реализацию

//иными словами, здесь интерфейс не часть класса, но частный случай- абстрактный класс, наследование которого обязывает к реализации

abstract class FlyAble

{

public abstract void Fly();

}

//интерфейсы: только заголовки методов без модификаторов (public по умолчанию)

//в частности, нет полей (но может быть set-get) и невозможна инициализация

//движение с переменной скоростью

interface IMoveAble

{

void SetSpeed(int x); // фиксируем скорость

int GetSpeed(); //получаем скорость, с которой двигается животное

}

//вносится коллизия имён для демонстрации проблем множественного наследования

//ошибка проектирования?

//см. далее также обсуждение конфликта реализации и способы разрешения (склеивание, переименование)

interface IFlyAble : IMoveAble

{

void Fly();

}

interface IRunAble : IMoveAble

{

void Run();

}

interface ISwimAble : IMoveAble

{

void Swim();

}

class Elephant : cMammals, IRunAble, ISwimAble

{

//явное описание интерфейса - реализация:

void IRunAble.Run()

{

//выполнение метода:

Console.WriteLine("Elephant" + GetName() + "runs");

}

void ISwimAble.Swim()

{

//выполнение метода

Console.WriteLine("Elephant" + GetName() + "swims");

}

public Elephant()

{

}

public Elephant(string x)

{

this.Name= x;

}

//разрешение коллизии - "склеивание"

void IMoveAble.SetSpeed(int x) // сомнительно с точки зрения предметной области

{

}

int IMoveAble.GetSpeed()

{

return 0;

}

//иной вариант- переименование

//реализуем как закрытие, открываем под другими именами

// см. Duck

} //class Elephant

class Dolphin : cMammals, ISwimAble

{

//Явное описание интерфейса (реализация)

void ISwimAble.Swim()

{

//выполнение метода

}

void IMoveAble.SetSpeed(int x)// устанавливается скорость движениия

{

}

int IMoveAble.GetSpeed()

{

return 0;

}

} //class Dolphin

class Duck : cBirds, ISwimAble, IRunAble, IFlyAble

{

//Явное описание интерфейса-реализация:

void ISwimAble.Swim()

{

//Выполнение метода

}

void IRunAble.Run()

{

//выполнение метода

}

void IFlyAble.Fly()

{

//выполнение метода

}

void IMoveAble.SetSpeed(int x)

{

}

int IMoveAble.GetSpeed()

{

return 0;

}

}//class Duck

class Program

{

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

static void Main()

{

Elephant E1 = new Elephant();

E1.SetName("John");

//E1.Run_Method(); //ошибка - нужно явно выбирать интерфейс

((IRunAble)E1).Run(); //ok

IRunAble E2 = E1;

E2.Run(); // ok

//E2.SetName("???"); //ошибка

// объявление объекта интерфейсного класса

IRunAble E = new Elephant("Pete");

//E.SetName("???"); //ошибка

// объект, функционирующий по правилам метода

E.Run();

ISwimAble obj_Dolphin = new Dolphin();

obj_Dolphin.Swim;

ISwimAble obj_Duck_1= new Duck();

obj_Duck_1.Swim;

IRunAble obj_Duck_2= new Duck();

obj_Duck_2.Run();

IFlyAble obj_Duck_3= new Duck();

obj_Duck_3.Fly();

Console.ReadKey();

}

}// class Program

} //namespace Hierarchy