Downcasting

Last updated

In class-based programming, downcasting, or type refinement, is the act of casting a base or parent class reference, to a more restricted derived class reference. [1] This is only allowable if the object is already an instance of the derived class, and so this conversion is inherently fallible.

Contents

In many environments, type introspection can be used to obtain the type of an object instance at runtime, and then use this result to explicitly evaluate its type compatibility with another type. The possible results of comparing polymorphic types—besides them being equivalent (identical), or unrelated (incompatible)—include two additional cases: namely, where the first type is derived from the second, and then the same thing but swapped the other way around (see: Subtyping § Subsumption).

With this information, a program can test, before performing an operation such as storing an object into a typed variable, whether that operation is type safe, or whether it would result in an error. If the type of the runtime instance is derived from (a child of) the type of the target variable (therefore, the parent), downcasting is possible.

Some languages, such as OCaml, disallow downcasting. [2]

Examples

Java

publicclassFruit{}// parent classpublicclassAppleextendsFruit{}// child classpublicstaticvoidmain(String[]args){// The following is an implicit upcast:Fruitparent=newApple();// The following is a downcast. Here, it works since the variable `parent` is// holding an instance of Apple:Applechild=(Apple)parent;}

C++

// Parent class:classFruit{public:// Must be polymorphic to use runtime-checked dynamic-cast.virtual~Fruit()=default;};// Child class:classApple:publicFruit{};intmain(intargc,constchar**argv){// The following is an implicit upcast:Fruit*parent=newApple();// The following is a downcast. Here, it works since the variable `parent` is// holding an instance of Apple:Apple*child=dynamic_cast<Apple*>(parent);}

Uses

Downcasting is useful when the type of the value referenced by the Parent variable is known and often is used when passing a value as a parameter. In the below example, the method objectToString takes an Object parameter which is assumed to be of type String.

publicstaticStringobjectToString(ObjectmyObject){// This will only work when the myObject currently holding value is string.return(String)myObject;}publicstaticvoidmain(String[]args){// This will work since we passed in String, so myObject has value of String.Stringresult=objectToString("My String");ObjectiFail=newObject();// This will fail since we passed in Object which does not have value of String.result=objectToString(iFail);}

In this approach, downcasting prevents the compiler from detecting a possible error and instead causes a run-time error. Downcasting myObject to String ('(String)myObject') was not possible at compile time because there are times that myObject is String type, so only at run time can we figure out whether the parameter passed in is logical. While we could also convert myObject to a compile-time String using the universal java.lang.Object.toString(), this would risk calling the default implementation of toString() where it was unhelpful or insecure, and exception handling could not prevent this.

In C++, run-time type checking is implemented through dynamic_cast. Compile-time downcasting is implemented by static_cast, but this operation performs no type check. If it is used improperly, it could produce undefined behavior.

Considerations

A popular example of a badly considered design is containers of top types,[ citation needed ] like the Java containers before Java generics were introduced, which requires downcasting of the contained objects so that they can be used again.

See also

Related Research Articles

OCaml is a general-purpose, high-level, multi-paradigm programming language which extends the Caml dialect of ML with object-oriented features. OCaml was created in 1996 by Xavier Leroy, Jérôme Vouillon, Damien Doligez, Didier Rémy, Ascánder Suárez, and others.

In computer programming, lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed. It is a kind of lazy evaluation that refers specifically to the instantiation of objects or other resources.

In computer programming, a type system is a logical system comprising a set of rules that assigns a property called a type to every term. Usually the terms are various language constructs of a computer program, such as variables, expressions, functions, or modules. A type system dictates the operations that can be performed on a term. For variables, the type system determines the allowed values of that term. Type systems formalize and enforce the otherwise implicit categories the programmer uses for algebraic data types, data structures, or other components.

A method in object-oriented programming (OOP) is a procedure associated with an object, and generally also a message. An object consists of state data and behavior; these compose an interface, which specifies how the object may be used. A method is a behavior of an object parametrized by a user.

In programming language theory and type theory, polymorphism is the use of a single symbol to represent multiple different types.

In computer science, type conversion, type casting, type coercion, and type juggling are different ways of changing an expression from one data type to another. An example would be the conversion of an integer value into a floating point value or its textual representation as a string, and vice versa. Type conversions can take advantage of certain features of type hierarchies or data representations. Two important aspects of a type conversion are whether it happens implicitly (automatically) or explicitly, and whether the underlying data representation is converted from one representation into another, or a given representation is merely reinterpreted as the representation of another data type. In general, both primitive and compound data types can be converted.

In computer programming, run-time type information or run-time type identification (RTTI) is a feature of some programming languages that exposes information about an object's data type at runtime. Run-time type information may be available for all types or only to types that explicitly have it. Run-time type information is a specialization of a more general concept called type introspection.

In computer science, type safety and type soundness are the extent to which a programming language discourages or prevents type errors. Type safety is sometimes alternatively considered to be a property of facilities of a computer language; that is, some facilities are type-safe and their usage will not result in type errors, while other facilities in the same language may be type-unsafe and a program using them may encounter type errors. The behaviors classified as type errors by a given programming language are usually those that result from attempts to perform operations on values that are not of the appropriate data type, e.g., adding a string to an integer when there's no definition on how to handle this case. This classification is partly based on opinion.

This article compares two programming languages: C# with Java. While the focus of this article is mainly the languages and their features, such a comparison will necessarily also consider some features of platforms and libraries. For a more detailed comparison of the platforms, see Comparison of the Java and .NET platforms.

In class-based, object-oriented programming, a constructor is a special type of function called to create an object. It prepares the new object for use, often accepting arguments that the constructor uses to set required member variables.

<span class="mw-page-title-main">Java syntax</span> Set of rules defining correctly structured program

The syntax of Java is the set of rules defining how a Java program is written and interpreted.

In mathematical logic and computer science, some type theories and type systems include a top type that is commonly denoted with top or the symbol ⊤. The top type is sometimes called also universal type, or universal supertype as all other types in the type system of interest are subtypes of it, and in most cases, it contains every possible object of the type system. It is in contrast with the bottom type, or the universal subtype, which every other type is supertype of and it is often that the type contains no members at all.

<span class="mw-page-title-main">Oxygene (programming language)</span> Object Pascal-based programming language

Oxygene is a programming language developed by RemObjects Software for Microsoft's Common Language Infrastructure, the Java Platform and Cocoa. Oxygene is based on Delphi's Object Pascal, but also has influences from C#, Eiffel, Java, F# and other languages.

Haxe is a high-level cross-platform programming language and compiler that can produce applications and source code for many different computing platforms from one code-base. It is free and open-source software, released under the MIT License. The compiler, written in OCaml, is released under the GNU General Public License (GPL) version 2.

Generics are a facility of generic programming that were added to the Java programming language in 2004 within version J2SE 5.0. They were designed to extend Java's type system to allow "a type or method to operate on objects of various types while providing compile-time type safety". The aspect compile-time type safety was not fully achieved, since it was shown in 2016 that it is not guaranteed in all cases.

This article describes the syntax of the C# programming language. The features described are compatible with .NET Framework and Mono.

This comparison of programming languages compares how object-oriented programming languages such as C++, Java, Smalltalk, Object Pascal, Perl, Python, and others manipulate data structures.

In computer programming, a constant is a value that is not altered by the program during normal execution. When associated with an identifier, a constant is said to be "named," although the terms "constant" and "named constant" are often used interchangeably. This is contrasted with a variable, which is an identifier with a value that can be changed during normal execution. To simplify, constants' values remains, while the values of variables varies, both hence their names.

The computer programming language, C#, introduces several new features in version 2.0. These include:

The programming language C# version 3.0 was released on 19 November 2007 as part of .NET Framework 3.5. It includes new features inspired by functional programming languages such as Haskell and ML, and is driven largely by the introduction of the Language Integrated Query (LINQ) pattern to the Common Language Runtime. It is not currently standardized by any standards organisation.

References

  1. TylerMSFT (2021-08-03). "How to: Use safe_cast in C++/CLI". learn.microsoft.com. Retrieved 2023-12-01.
  2. Vouillon, Jérôme; Rémy, Didier; Garrigue, Jacques (September 12, 2013). "Objects in OCaml". The OCaml system release 4.01 : Documentation and user's manual.