Avoid downcasting

From CSSEMediaWiki
(Difference between revisions)
Jump to: navigation, search
m
m (Reverted edits by Ebybymic (Talk); changed back to last version by Josh Oosterman)
 
(7 intermediate revisions by 6 users not shown)
Line 1: Line 1:
Typically one downcasts when one has a collection of mixed objects of a certain superclass (for instance, several Cars, several Bicycles and several Trains, all subclasses of Vehicle). This is almost certainly the sub-optimal technique to accomplish your chosen task, because it's an indication ([[Code smells|code smell]]) that you're not using polymorphism properly. The resulting code will inevitably have a [[Switch statement smell]], another reason you should probably be restructuring your code.
+
Typically one downcasts when one has a collection of mixed objects of a certain superclass (for instance, several Cars, several Bicycles and several Trains, all subclasses of Vehicle). This is almost certainly the sub-optimal technique to accomplish your chosen task, because it's an indication ([[Code smells|code smell]]) that you're not using [[Polymorphism|polymorphism]] properly. The resulting code will inevitably have a [[Switch statement smell]], another reason you should probably be restructuring your code.
  
 
Using our example, here's a pseudocode method that uses bad downcasting:
 
Using our example, here's a pseudocode method that uses bad downcasting:
Line 21: Line 21:
 
This clearly is disgusting. The problem here is that we are manually engaging a different method depending on the type, which means there is a problem relating to the superclass.
 
This clearly is disgusting. The problem here is that we are manually engaging a different method depending on the type, which means there is a problem relating to the superclass.
  
This means we are not taking advantage of polymorphism. The better way to go is this:
+
This means we are not taking advantage of [[polymorphism]]. The better way to go is this:
  
 
  foreach (Vehicle v in vehicleCollection)
 
  foreach (Vehicle v in vehicleCollection)
Line 32: Line 32:
  
 
Thus downcasting strongly indicates problems with your class hierarchy (or interface).
 
Thus downcasting strongly indicates problems with your class hierarchy (or interface).
 +
 +
[[Double Dispatch]] as used in the [[Visitor]] pattern can be a useful way of removing downcasts.
 +
 +
Downcasting can be a problem when trying to conform to [[Design by contract]]. By downcasting you are not conforming to the contract of a design.
 +
 +
==Automatability==
 +
This rule is well suited to automation. The Java compiler already complains about this to some extent. In Java you'll get a compiler warning if you downcast without first checking the type of the object.
 +
 +
==See Also==
 +
 +
* [[Refactoring]]: [[Encapsulate Downcast]]
 +
* [[Double Dispatch]]
 +
 +
[[Category:RuleAutomation]]

Latest revision as of 03:10, 25 November 2010

Typically one downcasts when one has a collection of mixed objects of a certain superclass (for instance, several Cars, several Bicycles and several Trains, all subclasses of Vehicle). This is almost certainly the sub-optimal technique to accomplish your chosen task, because it's an indication (code smell) that you're not using polymorphism properly. The resulting code will inevitably have a Switch statement smell, another reason you should probably be restructuring your code.

Using our example, here's a pseudocode method that uses bad downcasting:

method turnonallvehicles()
{
 foreach (Vehicle v in vehicleCollection)
 {
  if v is Car
   Car c = (Car)v
   c.turnKey()
  else if v is Bicycle 
   Bicycle b = (Bicycle) v
   b.startPedalling()
  else if v is Train
   Train t = (Train) v
   t.lightCoal()
 }
}

This clearly is disgusting. The problem here is that we are manually engaging a different method depending on the type, which means there is a problem relating to the superclass.

This means we are not taking advantage of polymorphism. The better way to go is this:

foreach (Vehicle v in vehicleCollection)
{
 v.start()
}


This would be the obvious technique if your superclass was defined correctly.

Thus downcasting strongly indicates problems with your class hierarchy (or interface).

Double Dispatch as used in the Visitor pattern can be a useful way of removing downcasts.

Downcasting can be a problem when trying to conform to Design by contract. By downcasting you are not conforming to the contract of a design.

Automatability

This rule is well suited to automation. The Java compiler already complains about this to some extent. In Java you'll get a compiler warning if you downcast without first checking the type of the object.

See Also

Personal tools