2017-09-21 9 views
0

仮想ガレージには車両(車と自転車)が格納されています。クラス間の自動インクリメントID - JAVA

私は自動インクリメントIDシステムを望んでいますが、正しく設定する方法が完全にはわかりません。あなたが識別子のシーケンスを生成する場合

public class Vehicle { 
    String make; 
    String model; 
    int year; 
    int id; 
    double bill; 
} 

車(車両を拡張)

public class Car extends Vehicle { 
private int noDoors; 
public Car(String make, String model, int year, int noDoors) { 
    this.id = id++; 
    this.noDoors = noDoors; 
    this.make = make; 
    this.model = model; 
    this.year = year; 
} 

}

+0

この宿題はありますか?実際に何か試しましたか? – Oleg

+0

DBを使用してデータを格納します。これが単なるテストプログラムであれば、おそらくシングルトンを使うことができます。このコードに複数のスレッドがアクセスした場合に何が起きるか注意してください。 – TeaCode

+1

これを見てください:https://softwareengineering.meta.stackexchange.com/questions/6166/open-letter-to-students-with-homework-problems – larsgrefer

答えて

0

良いアプローチをファクトリパターンを使用することです。ファクトリは、オブジェクトのインスタンスを生成するオブジェクトです。次に、すべてのオブジェクトに対してIDを管理できる1つの場所があります。

にオブジェクトを登録することもできます。 IDを手渡すオフィスのように。使用量がより快適に行うためのシングルトンパターンを使用して

登録オフィス、::ここで

登録方法を使用した例である

public class IdProvider { 
    private static IdProvider instance = null; 

    public IdProvider getInstance() { 
     if (instance == null) { 
      instance = new IdProvider(); 
     } 

     return instance; 
    } 

    private int nextID = 0; 

    public int getUniqueId() { 
     if (nextId < 0) { 
      throw new IllegalStateException("Out of IDs!"); 
     } 

     int uniqueId = nextId; 
     nextId++; 

     return uniqueId; 
    } 
} 

あなたオブジェクト

public class Vehicle { 
    String make; 
    String model; 
    int year; 
    int id; 
    double bill; 

    public Vehicle() { 
     // Get an ID 
     this.id = IdProvider.getInstance().getUniqueId(); 
    } 
} 

public class Car extends Vehicle { 
    private int noDoors; 
    public Car(String make, String model, int year, int noDoors) { 
     // An ID is fetched implicitly because 
     // the super-constructor of Vehicle is 
     // always called 

     this.noDoors = noDoors; 
     this.make = make; 
     this.model = model; 
     this.year = year; 
    } 
} 

あなたは迅速かつ汚いソリューションを探している場合は別の方法として、あなたはVehicle静的カウンターを使用することができます。

public class Vehicle { 
    private static int nextId = 0; 

    String make; 
    String model; 
    int year; 
    int id; 
    double bill; 

    public Vehicle() { 
     // Get an ID 
     this.id = Vehicle.nextId; 

     // Increase the ID for the next vehicle 
     Vehicle.nextId++; 
    } 
} 

静的変数は、クラスのすべてのインスタンス間で共有されます。だから、すべての車両にはただ1つのnextIdオブジェクトがあり、それらはすべてそれにアクセスできます。


あなたは並列環境(マルチスレッドプログラミング)でそのコードを使用する場合、あなたはIdProvidergetUniqueId方法で世話をしなければならないことに注意してください。

synchronizeが必要です。または、idカウンタのタイプをAtomicIntegerに置き換えて、AtomicInteger#getAndIncrementdocumentation)のようなスレッドセーフメソッドを提供することもできます。

+1

ヘルプ@ Zabuzaありがとう。迅速かつ汚れた方法は、私が探していたものと過去に見たものでした。私は元々 "this.id = id"として "id ++"を持っていましたが、それはまったく動作しませんでした。再度ありがとう – physicsboy

+0

それが助けてくれてうれしい。変数上の 'static'キーワードを忘れてしまったため、うまくいきませんでした。それがなければ 'Vehicle'のすべてのインスタンスに' id 'という独自のカウンタがありますが、*グローバルカウンタは1つだけ必要です*。これは 'static'で到達することができます。インスタンスから変数を切り離し、クラス自体の名前空間に持ち込みます(* static-context *)。 – Zabuza

0

...以下の私のコードを参照してください。 JVMの存続期間内で一意である場合は、AtomicIntegerカウンタを使用できますスーパークラスで。 、そして、

public abstract class Vehicle { 

    protected int id; 
    protected String make; 
    protected String model; 
    protected int year; 

    private static AtomicInteger idSequence = new AtomicInteger(); 

    protected Vehicle(String make, String model, int year) { 
     this.id = idSequence.incrementAndGet(); 
     // set the super class fields 
    } 
} 

サブクラスであなたは、サブクラス固有のフィールドを設定する前に、スーパークラスのコンストラクタを呼び出します。次のようにカウンタは、スーパークラスのコンストラクタでインクリメントされるだろう

public class Car extends Vehicle { 
    private int noDoors; 

    public Car(String make, String model, int year, int noDoors) { 
     super(make, model, year); 
     // set the sub-class fields 
    } 
} 
関連する問題