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()或类似的,被and覆盖BeerRum

然后你会做类似的事情:

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

所以你适当地实例化引用。因为它仍然是类型Drink,所以您可以参考品牌。Drink 参考将让您访问任何可饮用的东西,并且实现提供了细节。请注意,这Drinkabstract,因为您无法实例化 a Drink- 您必须更具体。

要回答您的进一步问题,您可以提供一个基本方法并执行以下操作:

if (this instanceof Beer) {
   ...
}

以避免覆盖。但是你为什么会呢?

为了回答您的第二个问题,JVM 在引用时动态加载类。您可以通过-verbose在 JVM 上设置标志来观察这种情况。

于 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 回答