▁Compar able ▁{ ▁▁▁▁▁ ▁int ▁compare To ( Object ▁o ); ▁} ▁ ▁The ▁draw back ▁of ▁this ▁is ▁that ▁the ▁method ▁is ▁specified ▁to ▁take ▁an ▁argument ▁of ▁type ▁. ▁A ▁typical ▁implementation ▁would ▁first ▁down - cast ▁this ▁argument ▁( throw ing ▁an ▁error ▁if ▁it ▁is ▁not ▁of ▁the ▁expected ▁type ): ▁ ▁class ▁R ational Number ▁implements ▁Compar able ▁{ ▁▁▁▁ ▁int ▁numer ator ; ▁▁▁▁ ▁int ▁denomin ator ; ▁▁▁▁ ▁// ▁... ▁▁▁▁▁▁ ▁public ▁int ▁compare To ( Object ▁other ) ▁{ ▁▁▁▁▁▁▁▁ ▁R ational Number ▁other Num ▁= ▁( R ational Number ) other ; ▁▁▁▁▁▁▁▁ ▁return ▁Integer . compare ( numer ator ▁* ▁other Num . den omin ator , ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ▁other Num . numer ator ▁* ▁denomin ator ); ▁▁▁▁ ▁} ▁} ▁ ▁In ▁a ▁language ▁with ▁cov ari ant ▁parameters , ▁the ▁argument ▁to ▁ ▁could ▁be ▁directly ▁given ▁the ▁desired ▁type ▁, ▁hiding ▁the ▁type cast . ▁( Of ▁course , ▁this ▁would ▁still ▁give ▁a ▁runtime ▁error ▁if ▁ ▁was ▁then ▁called ▁on ▁e . g . ▁a ▁. ) ▁ ▁A vo iding ▁the ▁need ▁for ▁cov ari ant ▁parameter ▁types ▁ ▁Other ▁language ▁features ▁can ▁provide ▁the ▁apparent ▁benefits ▁of ▁cov ari ant ▁parameters ▁while ▁pres erving ▁L isk ov ▁subst itut ability . ▁ ▁In ▁a ▁language ▁with ▁gener ics ▁( a . k . a . ▁paramet ric ▁polym orphism ) ▁and ▁bounded ▁quant ification , ▁the ▁previous ▁examples ▁can ▁be ▁written ▁in ▁a ▁type - safe