8

たとえば、「Vehicle」という抽象クラスがあるとします。Vehicleクラスには、特に、初期化されていないwheelsと呼ばれる静的変数があります。私がやりたいのは、「Motorcycle」や「Truck」など、Vehicleクラスから拡張された他のサブクラスを用意し、これらのサブクラスでホイールを初期化することです。

コード:

public abstract class Vehicle {
    static int wheels; //number of wheels on the vehicle
}

ただし、以下は機能しません。

public class Motorcycle extends Vehicle {
    wheels = 2;
}

これを効果的に行う方法はありますか?

編集:これまでに返信してくれたすべての人に感謝します。インスタンスを作成する方が、すべてを別々のクラスに配置するよりもおそらく良い方法だと思いますが、Javaの「静的」部分を完全に取得することはできないため、ここで少し助けが必要です。

私がプログラムでやろうとしているのは、オートバイとトラックのクラスに別々のスプライトを用意することです。オートバイやトラックのインスタンスを作成するたびに画像をリロードする必要がないように、それらを静的にしたいと思います。 。ただし、それ以外は、互いにほぼ同じプロパティを持ちます。そのため、両方ともVehicleスーパークラスから拡張されます。

これが行われていることを確認できる他の唯一の方法は、Vehicleクラスではなく、Motorcycle/Truckクラスでスプライト変数を宣言することです。

public abstract class Vehicle {
//Other coding
}

public class Motorcycle extends Vehicle {
static BufferedImage sprite = //initialize image
//Other coding
}

public class Truck extends Vehicle {
static BufferedImage sprite = //initialize image
//Other coding
}
4

7 に答える 7

12

'wheels'が静的である場合、1つだけであり、すべての車両に同時に適用されます。したがって、三輪車、オートバイ、18輪トラック、およびフォードはすべて同じ数の車輪を持ちます。

それは私には意味がありません。'wheels'を親クラスにあるインスタンス変数にする方がよいでしょうが、各サブクラスは適切に設定されます。

しかし、あなたは試すことができます

Vehicle.wheels = 2;

注:あなたが質問に追加したので、私は私の答えに追加しています。

各サブクラスに静力学を含めるというあなたのアイデアが好きです。ただし、それらを非公開にする必要があります。次に、次のような抽象メソッドを親クラス(Vehicle)に配置します。

public abstract BufferedImage getSprite();

次に、各直接サブクラスは同じメソッドを持つ必要があり、プライベート静的変数を返すことができます。

変数を静的にして、一度だけロードする必要があるようにします。クラス自体の外部のコードがそれをだましてバグを導入しないように、それらをプライベートにします。可能であれば、それらを「最終」にして、クラス自体のコードが事後に変更してバグを導入できないようにすることができます。(「final」変数はその値を変更できませんが、その値の内容は変更できます。したがって、「final」は素晴らしいものではありません。)

于 2012-12-28T22:49:57.343 に答える
6

あなたがやろうとしていることは根本的に欠陥があります。初期化を1回行うことができます。Motorcyclewheels

// Static initializer
static
{
    wheels = 2;
}

...またはインスタンスが作成されるたびに:

// Instance initializer
{
    wheels = 2;
}

ただし、変数は1つMotorcycleだけです。変数は、、などではありません。とTruckの両方に対して同じことを行った場合、最後に初期化された方が「勝ち」ます。TruckMotorcycle

とにかくこのフィールドをどのように使用するかは明確ではありませんが、静的フィールドが1つしかない場合は、サブクラスごとに1つではなく、1つの値になります。

于 2012-12-28T22:48:56.257 に答える
2

静的メンバーは一度だけ定義され、すべての拡張クラスに共通です。そのうちの 1 つの値を変更すると、他のすべてに影響します。これは、あなたが本当に達成したいと私が信じていることです。

public abstract class Vehicle {
    private int _wheels; //number of wheels on the vehicle
    public int getWheels(){return _wheels;}

    protected Vehicle(int wheels){
        _wheels = wheels;
    }
}

public class Motorcycle extends Vehicle {
    public Motorcycle(){
        super(2);
    }
}

public class Car extends Vehicle {
    public Car(){
        super(4);
    }
}
于 2012-12-28T22:59:25.490 に答える
2

元のクラス宣言:

public abstract class Vehicle {
    static int wheels; //number of wheels on the vehicle
}

public class Motorcycle extends Vehicle{...}
public class Truck extends Vehicle{...}

静的変数はそれが宣言されたクラスと一致するため、機能しません。静的クラス変数は、クラス オブジェクトごとではなく、クラスごとに変数のインスタンスを 1 つだけ格納するメモリ ストレージを作成します。コンパイラ (jvm) は、Vehicle クラスの静的変数を検出すると、その変数にメモリを割り当て、そのメモリ位置は静的です (変化しません)。Vehicle クラスが拡張されているか、オブジェクトとしてインスタンス化されているかに関係なく、その後の各車両クラスの使用は、静的変数のメモリ内の同じ場所を指します。

子クラスで静的変数を使用するには、メソッド内で使用する必要があります。つまり、Motorcycle クラスを次のように書き直すことができます。

class Motorcycle extends Vehicle{
    public Motorcycle(){
        wheels = 2;
    }
}

そしてコンパイルされます。ただし、期待した結果が得られない場合があります。たとえば、コードでこれを行う場合 (Truck クラスが Motorcycle クラスのように宣言され、車輪に 4 が割り当てられ、車輪の値を返す getter メソッドがあると仮定します)。

Motorcycle cycle = new Motorcycle();
Truck pickup = new Truck();
...
System.out.println("Motorcycle has " + cycle.getWheels() + " wheels.");

印刷されます:

オートバイには 4 つの車輪があります。

于 2016-06-29T18:27:51.410 に答える
1

オブジェクトに静的変数を作成すると、抽象Vehicleクラスに別のサブクラスを作成する場合でも、作成するすべてのVehicleクラスで同じになります。これは、静的変数の「性質」によるものです。

非静的変数を使用して、抽象Vehicleクラスのサブクラスのすべてのインスタンスについて、ホイールの値を決定できるようにする必要があると思います。これは次のように実行されます。

public abstract class Vehicle {
    public int wheels; //number of wheels on the vehicle
}

および任意のサブクラス:

public foo extends Vehicle{

     public void someMethode(){
         this.wheels = 2;
     }
}

静的変数に対してもこれを行うことができますが、その後、Vehicleのサブクラスのすべてのインスタンスに対して変更します。

私があなたを助けたことを願っています

于 2012-12-28T22:56:52.390 に答える
0

使用しているコンストラクターについて考えたいと思うかもしれません。

public Vehicle(int wheels) {
    this.wheels = wheels; 
}

public Motorcycle(int wheels) {
    super(wheels);
}

public Motorcycle cycle = new Motorcycle(2);

オートバイは、パラメーターの処理方法を知っているスーパー コンストラクターを使用します。自動的にホイールを 2 に設定します。

于 2012-12-28T22:53:25.367 に答える