Несложно догадаться, что на помощь здесь приходят интерфейсные типы. После того как интерфейс определен, он может быть реализован любым классом либо структурой, в любой иерархии и внутри любого пространства имен или сборки (написанной на любом языке программирования .NET Core). Как видите, интерфейсы являются
ICloneable, определенный в пространстве имен System. В нем определен единственный метод по имени Clone:public interface ICloneable
{
object Clone;
}
Во время исследования библиотек базовых классов .NET Core вы обнаружите, что интерфейс ICloneable
System.Array, System.Data.SqlClient.SqlConnection, System.OperatingSystem, System.String и т.д.). Хотя указанные типы не имеют общего родителя (кроме System.Object), их можно обрабатывать полиморфным образом посредством интерфейсного типа ICloneable. Первым делом поместите в файл Program.cs следующий код:using System;
using CustomInterfaces;
Console.WriteLine("***** A First Look at Interfaces *****\n");
CloneableExample;
Далее добавьте к операторам верхнего уровня показанную ниже локальную функцию по имени CloneMe
ICloneable, что позволит передавать любой объект, реализующий указанный интерфейс:static void CloneableExample
{
// Все эти классы поддерживают интерфейс ICloneable.
string myStr = "Hello";
OperatingSystem unixOS =
new OperatingSystem(PlatformID.Unix, new Version);
// Следовательно, все они могут быть переданы методу,
// принимающему параметр типа ICloneable.
CloneMe(myStr);
CloneMe(unixOS);
static void CloneMe(ICloneable c)
{
// Клонировать то, что получено, и вывести имя.
object theClone = c.Clone;
Console.WriteLine("Your clone is a: {0}",
theClone.GetType.Name);
}
}
После запуска приложения в окне консоли выводится имя каждого класса, полученное с помощью метода GetType
System.Object. Как будет объясняться в главе 17, этот метод позволяет выяснить строение любого типа во время выполнения. Вот вывод предыдущей программы:***** A First Look at Interfaces *****
Your clone is a: String
Your clone is a: OperatingSystem
Еще одно ограничение абстрактных базовых классов связано с тем, что
Shape определен новый абстрактный метод по имени GetNumberOfPoints, который позволяет производным типам возвращать количество вершин, требуемых для визуализации фигуры:namespace CustomInterfaces
{
abstract class Shape
{
...
// Теперь этот метод обязан поддерживать каждый производный класс!
public abstract byte GetNumberOfPoints;
}
}
Очевидно, что единственным классом, который в принципе имеет вершины, будет Hexagon
Circle, Hexagon и ThreeDCircle) обязан предоставить конкретную реализацию метода GetNumberOfPoints, даже если в этом нет никакого смысла. И снова интерфейсный тип предлагает решение. Если вы определите интерфейс, который представляет поведение "наличия вершин", то можно будет просто подключить его к классу Hexagon, оставив классы Circle и ThreeDCircle незатронутыми.Бьёрн Страуструп , Ирина Сергеевна Козлова , Бьерн Страуструп , Валерий Федорович Альмухаметов
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT