Downcasting

Last updated

In class-based programming, downcasting or type refinement is the act of casting a reference of a base class to one of its derived classes.

Contents

In many programming languages, it is possible to check through type introspection to determine whether the type of the referenced object is indeed the one being cast to or a derived type of it, and thus issue an error if it is not the case.

In other words, when a variable of the base class (parent class) has a value of the derived class (child class), downcasting is possible.

Examples

Java

publicclassFruit{}// parent classpublicclassAppleextendsFruit{}// child classpublicstaticvoidmain(Stringargs[]){// 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);deleteparent;}

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(Stringargs[]){// 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.

Criticism

Some languages, such as OCaml, disallow downcasting altogether. [1]

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, 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.

C++ General-purpose programming language

C++ is a general-purpose programming language created by Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significantly over time, and modern C++ now has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation. It is almost always implemented as a compiled language, and many vendors provide C++ compilers, including the Free Software Foundation, LLVM, Microsoft, Intel, Oracle, and IBM, so it is available on many platforms.

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 programming languages, a type system is a logical system comprising a set of rules that assigns a property called a type to the various constructs of a computer program, such as variables, expressions, functions or modules. These types formalize and enforce the otherwise implicit categories the programmer uses for algebraic data types, data structures, or other components. The main purpose of a type system is to reduce possibilities for bugs in computer programs by defining interfaces between different parts of a computer program, and then checking that the parts have been connected in a consistent way. This checking can happen statically, dynamically, or as a combination of both. Type systems have other purposes as well, such as expressing business rules, enabling certain compiler optimizations, allowing for multiple dispatch, providing a form of documentation, etc.

In computer science, a type signature or type annotation defines the inputs and outputs for a function, subroutine or method. A type signature includes the number, types and order of the arguments contained by a function. A type signature is typically used during overload resolution for choosing the correct definition of a function to be called among many overloaded forms.

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 science, type safety is the extent to which a programming language discourages or prevents type errors. A type error is erroneous or undesirable program behaviour caused by a discrepancy between differing data types for the program's constants, variables, and methods (functions), e.g., treating an integer (int) as a floating-point number (float). Type safety is sometimes alternatively considered to be a property of a computer program rather than the language in which that program is written; that is, some languages have type-safe facilities that can be circumvented by programmers who adopt practices that exhibit poor type safety. The formal type-theoretic definition of type safety is considerably stronger than what is understood by most programmers.

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

Java syntax

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

Many programming language type systems support subtyping. Variance refers to how subtyping between more complex types relates to subtyping between their components.

In computer programming, an entry point is where the first instructions of a program are executed, and where the program has access to command line arguments.

The top type in the type theory of mathematics, logic, and computer science, commonly abbreviated as top or by the down tack symbol (⊤), is the universal type, sometimes called the universal supertype as all other types in any given type system are subtypes of top. In most cases it is the type which contains every possible object in the type system of interest. It is in contrast with the bottom type, or the universal subtype, which every other type is supertype of and in most cases it is the type that contains no members at all.

Oxygene (programming language) 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 based on Delphi's Object Pascal, but also has influences from C#, Eiffel, Java, F# and other languages.

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 cannot be altered by the program during normal execution, i.e., the value is constant. 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, i.e., the value is variable. Constants are useful for both programmers and compilers: For programmers they are a form of self-documenting code and allow reasoning about correctness, while for compilers they allow compile-time and run-time checks that verify that constancy assumptions are not violated, and allow or simplify some compiler optimizations.

Nemerle is a general-purpose, high-level, statically typed programming language designed for platforms using the Common Language Infrastructure (.NET/Mono). It offers functional, object-oriented and imperative features. It has a simple C#-like syntax and a powerful metaprogramming system. In June 2012, the core developers of Nemerle were hired by the Czech software development company JetBrains. The team is focusing on developing Nitra, a framework to implement extant and new programming languages. This framework will likely be used to create future versions of Nemerle.

In computer programming, programming languages are often colloquially classified as to whether the language's type system makes it strongly typed or weakly typed.

Objective-C is a general-purpose, object-oriented programming language that adds Smalltalk-style messaging to the C programming language. It was the main programming language supported by Apple for macOS, iOS, and their respective application programming interfaces (APIs), Cocoa and Cocoa Touch, until the introduction of Swift in 2014.

References

  1. 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.