Nedkastande

I klassbaserad programmering är nedkastning eller typförfining handlingen att gjuta en referens för en basklass till en av dess härledda klasser.

I många programmeringsspråk är det möjligt att kontrollera genom typintrospektion för att avgöra om typen av det refererade objektet verkligen är den som castas till eller en härledd typ av det, och därmed utfärda ett fel om så inte är fallet.

Med andra ord, när en variabel i basklassen ( förälderklass ) har ett värde för den härledda klassen ( barnklass ), är nedsändning möjlig.

Vissa språk, som OCaml , tillåter inte nedsändning.

Exempel

Java

    
      

     
    
        
    
    
       

 public  class  Fruit  {}  // parent class  public  class  Apple  extends  Fruit  {}  // child class  public  static  void  main  (  String  []  args  )  {  // Följande är en implicit uppsändning:  Fruit  parent  =  new  Apple  ();  // Följande är en nedslagen. Här fungerar det eftersom variabeln `parent` är   // som innehåller en instans av Apple:  Apple  child  =  (  Apple  )  parent  ;  //Där Apple är barnklass men frukt är föräldraklass  } 

C++


  
 
  
     



     

      
  
      
  
  
     
 // Föräldraklass:  class  Fruit  {  public  :  // Måste vara polymorf för att använda runtime-checked dynamic-cast.  virtuell  ~  Fruit  ()  =  default  ;  };  // Barnklass:  klass  Apple  :  public  Fruit  {};  int  main  (  int  argc  ,  const  char  **  argv  )  {  // Följande är en implicit uppsändning:  Fruit  *  parent  =  new  Apple  ();  // Följande är en nedslagen. Här fungerar det eftersom variabeln `parent` är   // som innehåller en instans av Apple:  Apple  *  child  =  dynamic_cast  <  Apple  *>  (  parent  );  } 

Används

Nedsändning är användbart när typen av värde som refereras till av den överordnade variabeln är känd och används ofta när ett värde skickas som en parameter. I exemplet nedan tar metoden objectToString en Object-parameter som antas vara av typen String.

     
    
     


     
    
       
        
    
      
 public  static  String  objectToString  (  Object  myObject  )  {  // Detta fungerar bara när det myObject som för närvarande håller värdet är string.  return  (  String  )  myObject  ;  }  public  static  void  main  (  String  []  args  )  {  // Detta kommer att fungera sedan vi passerade i String, så myObject har värdet av String.  String  result  =  objectToString  (  "Min sträng"  );  Objekt  iFail  =  nytt  objekt  ();  // Detta kommer att misslyckas eftersom vi skickade in Object som inte har värdet av String.  result  =  objectToString  (  iFail  );  } 

I detta tillvägagångssätt förhindrar nedsändning kompilatorn från att upptäcka ett möjligt fel och orsakar istället ett körtidsfel. Nedsändning av myObject till String ('(String)myObject') var inte möjligt vid kompileringstillfället eftersom det finns tillfällen då myObject är av String-typ, så endast vid körning kan vi ta reda på om parametern som skickas in är logisk. Även om vi också kunde konvertera myObject till en kompilerings-tidssträng med den universella java.lang.Object.toString(), skulle detta riskera att anropa standardimplementeringen av toString() där den var ohjälpsam eller osäker, och undantagshantering kunde inte förhindra detta .

I C++ implementeras typkontroll av körtid genom dynamic_cast . Nedsändning av kompileringstid implementeras av static_cast , men denna operation utför ingen typkontroll. Om den används felaktigt kan den ge odefinierat beteende.

Överväganden

Ett populärt exempel på en dåligt övervägd design är behållare av topptyper , [ citat behövs ] som Java- behållarna innan Java-generika introducerades, vilket kräver nedkastning av de inneslutna objekten så att de kan användas igen.

Se även

externa länkar