Jump to content

Даункастинг

В на основе классов программировании понижающее приведение или уточнение типа — это приведение или ссылки на базовый родительский класс к более ограниченной ссылке на производный класс . [1] Это допустимо только в том случае, если объект уже является экземпляром производного класса, и поэтому такое преобразование по своей сути ошибочно.

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

С помощью этой информации программа может перед выполнением такой операции, как сохранение объекта в типизированной переменной, проверить, является ли эта операция типобезопасной или приведет ли она к ошибке. Если тип экземпляра среды выполнения является производным (дочерним) от типа целевой переменной (следовательно, родительской), возможно понижающее приведение.

Некоторые языки, такие как OCaml , запрещают понижающее приведение. [2]

public class Fruit{}  // parent class
public class Apple extends Fruit{}  // child class

public static void main(String[] args) {
    // The following is an implicit upcast:
    Fruit parent = new Apple();
    // The following is a downcast. Here, it works since the variable `parent` is
    // holding an instance of Apple:
    Apple child = (Apple)parent;
}
// Parent class:
class Fruit {
 public:
  // Must be polymorphic to use runtime-checked dynamic-cast.
  virtual ~Fruit() = default;
};

// Child class:
class Apple : public Fruit {};

int main(int argc, const char** argv) {
  // The following is an implicit upcast:
  Fruit* parent = new Apple();
  // The following is a downcast. Here, it works since the variable `parent` is
  // holding an instance of Apple:
  Apple* child = dynamic_cast<Apple*>(parent);
}

Использование

[ редактировать ]

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

public static String objectToString(Object myObject) {
    // This will only work when the myObject currently holding value is string.
    return (String)myObject;
}

public static void main(String[] args) {
    // This will work since we passed in String, so myObject has value of String.
    String result = objectToString("My String");
    Object iFail = new Object();
    // This will fail since we passed in Object which does not have value of String.
    result = objectToString(iFail);
}

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

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

Соображения

[ редактировать ]

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

См. также

[ редактировать ]
  1. ^ ТайлерMSFT (3 августа 2021 г.). «Как использовать Safe_cast в C++/CLI» . Learn.microsoft.com . Проверено 1 декабря 2023 г.
  2. ^ Вуийон, Жером; Реми, Дидье; Гарриг, Жак (12 сентября 2013 г.). «Объекты в OCaml» . Система OCaml, версия 4.01: Документация и руководство пользователя .
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: cb270bed0b1187019a6df12b3f00c1d0__1709125500
URL1:https://arc.ask3.ru/arc/aa/cb/d0/cb270bed0b1187019a6df12b3f00c1d0.html
Заголовок, (Title) документа по адресу, URL1:
Downcasting - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)