class A {
  double i, j;
  A( double i, double j ) {
    this.i = i; this.j = j;
  }
  // add()は2つのdouble型フィールドの値の合計値を返す
  double add(){ return i + j; }
}

class B extends A {
  B( double i, double j ){ super( i, j ); }
  // add()は2つのdouble型フィールドの値をかけあわせた
  // 値を返すようにオーバライドされてしまった
  double add(){ return i * j; }
}

class C {
  // ave()は，aの2つのフィールドの平均値を求める
  double ave( A a ){
    return a.add() / 2.0;
  }
}

class UnexpectedChange {
  public static void main( String args[] ) {
    C c = new C();
    // A型オブジェクトをave()に渡すと正常な値が得られる
    System.out.println( c.ave( new A( 3, 4 ) ) );
    // B型オブジェクトをave()に渡すと結果が予想と異なる
    System.out.println( c.ave( new B( 3, 4 ) ) );
  }
}