0

以下のコードがあります。

public class Test {
    public static void main(String args[])
    {
        int i = 0;

        if(i==0){
            Beer obj = new Beer();
        }
        else {
            Rum obj = new Rum();
        }
        System.out.println(obj.brand);  //doesn't work
    } }

class Drink {
} 
class Beer extends Drink{
    public String brand = "BeerBrand"; }

class Rum extends Drink{
    public String brand = "RumBrand"; }
  1. 関数のオーバーライドや動的なクラスの読み込みを使用せずに上記を機能させる方法はありますか?
  2. JVM ではすべてのクラスが動的にロードされ、C のような静的なロードはありません。これは正しいですか?
4

3 に答える 3

3

Drinkは抽象クラスである必要があり、およびによってオーバーライドされる抽象メンバーgetBrand()または同様のものを提供する必要があります。BeerRum

次に、次のようにします。

Drink d = null;
if (...) {
   d = new Beer();
}

そのため、参照を適切にインスタンス化します。それはまだタイプであるためDrink、ブランドを参照できます。Drink リファレンスを使用すると、飲むことができるものすべてにアクセスでき、実装によって詳細が提供されます。a をインスタンス化できないため、これDrinkabstractであることに注意してくださいDrink。より具体的にする必要があります。

さらに質問に答えるには、基本メソッドを提供して、次のようにすることができます。

if (this instanceof Beer) {
   ...
}

オーバーライドを避けるために。しかし、なぜあなたは?

2 番目の質問に答えるために、クラスは参照時に JVM によって動的にロードされます。-verboseJVM にフラグを設定することで、その発生を監視できます。

于 2012-10-10T08:40:26.297 に答える
2

「obj」のスコープは if-else ブロック内にのみあるため、このコードは機能しません。Drink 型の if-else ブロックの上で宣言する必要があります。

于 2012-10-10T08:41:36.263 に答える
1

関数のオーバーライドや動的なクラスの読み込みを使用せずに上記を機能させる方法はありますか?

唯一の代替手段はリフレクションを使用することですが、クラスの設計を修正する方がはるかに簡単/優れています

JVM ではすべてのクラスが動的にロードされ、C のような静的なロードはありません。これは正しいですか?

はい。動的に複数回ロードしたり、アンロードしたりすることもできます。


オブジェクト指向のアプローチを使用すると、次のようになります。

public class Test {
    public static void main(String... args) {
        Drink drink;
        if (args.length == 0) {
            drink = new Beer();
        } else {
            drink = new Rum();
        }
        System.out.println(drink.getBrand());
    }
}

interface Drink {
    public String getBrand();
}

class Beer implements Drink {
    @Override
    public String getBrand() {
        return "BeerBrand"; 
    }
}

class Rum implements Drink {
    @Override
    public String getBrand() {
        return "RumBrand";
    }
}
于 2012-10-10T08:42:23.157 に答える