我有以下代码。
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"; }
答案 0 :(得分:3)
Drink
应该是一个抽象类,并由getBrand()
和Beer
提供抽象成员Rum
或类似的重写。
然后你会做类似的事情:
Drink d = null;
if (...) {
d = new Beer();
}
所以你适当地实例化了引用。因为它仍然是Drink
类型,您可以参考该品牌。饮料参考将让您访问任何可饮用的东西,并且实施提供了具体细节。请注意,Drink
是 abstract ,因为您无法实例化Drink
- 您必须更加具体。
要回答您的其他问题,可以提供基本方法并执行以下操作:
if (this instanceof Beer) {
...
}
避免重写。但你为什么要这样做?
要回答第二个问题,JVM会在引用时动态加载类。您可以通过在JVM上设置-verbose
标志来观察这种情况。
答案 1 :(得分:2)
此代码无效,因为'obj'的范围仅在if-else块中。 你需要在上面if-else块类型Drink声明它。
答案 2 :(得分: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";
}
}