-2

オーバーライドメソッドを使用したコンストラクタチェーンの実行中に呼び出されるメソッドはどれですか?次の2つのクラスを考えると、MountainBikeオブジェクトを作成するときにどのsetGearメソッドが呼び出されるかを知る必要があります。私の実際のプロジェクトは自転車とは何の関係もありません。クラスをオーバーライドして、スーパークラスのコンストラクターで呼び出される1つのメソッドの動作を変更しようとしていますが、どのように機能するかわかりません...

public class Bicycle {
    public int cadence;
    public int gear;
    public int speed;

    public Bicycle(int startCadence,
                   int startSpeed,
                   int startGear) {
        setGear(startGear);
        setCadence(startCadence);
        setSpeed(startSpeed);
    }

    public void setCadence(int newValue) {
        cadence = newValue;
    }

    public void setGear(int newValue) {
        gear = newValue;
    }

    public void applyBrake(int decrement) {
        speed -= decrement;
    }

    public void speedUp(int increment) {
        speed += increment;
    }        
}

public class MountainBike extends Bicycle {
    public int seatHeight;

    public MountainBike(int startHeight,
                        int startCadence,
                        int startSpeed,
                        int startGear) {
        super(startCadence, startSpeed, startGear);
        seatHeight = startHeight;
    }   

    public void setHeight(int newValue) {
        seatHeight = newValue;
    }

    public void setGear(int newValue) {
    if(newValue<4)
            gear = newValue;
        else{
            gear = 4;
        }

    }    
}
4

6 に答える 6

1

ここにはまだいくつかの良い答えがありますが、代わりにコンポジションを使用することを検討する必要があることを述べておきます。私は、より良い方法で合成を行うことができた機能に継承が使用された多くのプロジェクトを見てきました。プロジェクトの後の段階で、これは深刻な問題やコードの臭いにつながる可能性があります。

「継承よりもコンポジションを優先する」を参照してください。効果的なJava:アイテム16

于 2012-01-28T01:01:27.123 に答える
1

これを呼び出すと、サブクラスのメソッドが実行されます。ただし、現在は呼び出されていません。

于 2012-01-28T00:49:36.290 に答える
1

他の人が指摘しているように、呼び出されるのはサブクラスのsetGearです。

ただし、コンストラクターでオーバーライドされたメソッドを呼び出すことは危険であり、特にそれらのメソッドがサブクラスのフィールドに依存している場合は、危険であることに言及したいと思います。たとえば、MountainBikeにフィールドがある場合、maxGearとsetGearが(マジック定数4の代わりに)それを参照していました。問題は、MountainBikeコンストラクターが次のようになっていることです。

public MountainBike(args...) {
  super(args);  // must come first!!!
  maxGear = 4;
}

BicycleコンストラクターがsetGear()を呼び出すと、MountainBikeのsetGearが呼び出されますが、maxGearはまだ設定されていません。0になります。

于 2012-01-28T01:30:27.020 に答える
0

オーバーライドするクラスをインスタンス化すると、そのオーバーライドするメソッドが実行されるメソッドになります。

Bicycle bike;

bike = new Bicycle(1,2,3);
bike.setGear(8);//Bicycle's setGear is run

bike = new MountainBike(1,2,3,4);
bike.setGear(8);//MountainBike's setGear is run

--編集:OPで編集された質問を反映します(setGear現在はBicycleのコンストラクター内から呼び出されます)-

Bicycle b=new MountainBike(1,2,3,4);

をインスタンス化するMountainBikeと、MountainBike'ssetGearが実行されます。

于 2012-01-28T00:50:32.187 に答える
0

より一般的には、「this」をパラメーターとして別のクラスのメソッドに渡すか、オーバーライド可能なメソッドを呼び出すことによって、オブジェクト参照をコンストラクターからエスケープさせないでください。

可能であっても、スーパークラスコンストラクターからオーバーライドされたメソッドを呼び出さないでください。その理由は、スーパークラスのコンストラクターがサブクラスのコンストラクターの前に実行され、オブジェクトの状態に一貫性がない可能性があるためです。たとえば、サブクラスのfinalフィールドはまだ設定されていません。

于 2012-01-28T08:26:16.763 に答える
-1

はい、派生クラスで新しい機能を作成して対応するために基本クラスのメソッドをオーバーライドすることが、サブタイプ(ポリモーフィック機能)を定義するものです。

class A{methodA...}
class B extends A{methodA...}
A a=new B;
a.methodA(); <<<< this should call B's methodA
于 2012-01-28T00:55:36.083 に答える