Понижение - Downcasting

В программирование на основе классов, понижение или уточнение типа - это действие Кастинг ссылка базового класса на один из его производных классов.

Во многих языки программирования, можно проверить тип интроспекции чтобы определить, действительно ли тип объекта, на который указывает ссылка, является типом, к которому выполняется приведение, или его производным типом, и, таким образом, выдает ошибку, если это не так.

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

Примеры

Ява

общественный учебный класс Фрукты{}  // родительский классобщественный учебный класс яблоко расширяет Фрукты{}  // дочерний классобщественный статический пустота главный(Нить аргументы[]) {    // Следующее - неявное восходящее преобразование:    Фрукты родитель = новый яблоко();    // Следующее - подавленное. Здесь это работает, поскольку переменная `parent`    // храним экземпляр Apple:    яблоко ребенок = (яблоко)родитель;}

C ++

// Родительский класс:учебный класс Фрукты { общественный:  // Должен быть полиморфным, чтобы использовать динамическое приведение с проверкой времени выполнения.  виртуальный ~Фрукты() = дефолт;};// Дочерний класс:учебный класс яблоко : общественный Фрукты {};int главный(int argc, const char** argv) {  // Следующее - неявное восходящее преобразование:  Фрукты* родитель = новый яблоко();  // Следующее - подавленное. Здесь это работает, поскольку переменная `parent`  // храним экземпляр Apple:  яблоко* ребенок = dynamic_cast<яблоко*>(родитель);  Удалить родитель;}

Использует

Понижающее преобразование полезно, когда известен тип значения, на которое ссылается родительская переменная, и часто используется при передаче значения в качестве параметра. В приведенном ниже примере метод objectToString принимает параметр Object, который, как предполагается, имеет тип String.

общественный статический Нить objectToString(Объект myObject) {    // Это будет работать, только если текущее значение myObject является строкой.    возвращаться (Нить)myObject;}общественный статический пустота главный(Нить аргументы[]) {    // Это будет работать, поскольку мы передали String, поэтому myObject имеет значение String.    Нить результат = objectToString("Моя строка");    Объект я проиграл = новый Объект();    // Это не удастся, так как мы передали Object, который не имеет значения String.    результат = objectToString(я проиграл);}

В этом подходе понижающее преобразование не позволяет компилятору обнаруживать возможную ошибку и вместо этого вызывает ошибку времени выполнения. Преобразование myObject в String ('(String) myObject') было невозможно во время компиляции, поскольку бывают случаи, когда myObject имеет тип String, поэтому только во время выполнения мы можем выяснить, логичен ли переданный параметр. Хотя мы также могли преобразовать myObject в строку времени компиляции с помощью универсального java.lang.Object.toString (), это могло бы вызвать риск вызова реализации toString () по умолчанию, если это было бесполезно или небезопасно, и обработка исключений не могла предотвратить это .

В C ++ проверка типов во время выполнения реализована через dynamic_cast. Понижение частоты во время компиляции реализуется static_cast, но эта операция не выполняет проверку типа. Если он используется неправильно, это может привести к неопределенному поведению.

Критика

Некоторые языки, например OCaml, полностью запретить отрицательное преобразование.[1]

Популярный пример плохо продуманного дизайна - контейнеры с лучшие типы,[нужна цитата ] словно Ява контейнеры до Дженерики Java были введены, что требует приведения содержащихся объектов вниз, чтобы их можно было использовать снова.

Смотрите также

Рекомендации

  1. ^ Вуйон, Жером; Реми, Дидье; Гарриг, Жак (12 сентября 2013 г.). «Объекты в OCaml». Версия системы OCaml 4.01: Документация и руководство пользователя.

внешняя ссылка