在Java中向上转换子类引用
我正在做Bruce Eckel的《Java第四版思考》中的以下练习: 练习16:(2)创建一个名为两栖动物的类。由此继承一个名为Frog的类。在基类中放置适当的方法。在main()中,创建一只青蛙并将其向上投射到两栖动物,并演示所有方法仍然有效在Java中向上转换子类引用,java,upcasting,Java,Upcasting,我正在做Bruce Eckel的《Java第四版思考》中的以下练习: 练习16:(2)创建一个名为两栖动物的类。由此继承一个名为Frog的类。在基类中放置适当的方法。在main()中,创建一只青蛙并将其向上投射到两栖动物,并演示所有方法仍然有效 Frog f=new Frog()之间的区别是什么和两栖动物f=新青蛙()在: class Amphibian { void go() { System.out.println("go"); } void stop() { System.
Frog f=new Frog()之间的区别是什么代码>和两栖动物f=新青蛙()代码>在:
class Amphibian {
void go() { System.out.println("go"); }
void stop() { System.out.println("stop!"); }
}
class Frog extends Amphibian {
void go() { System.out.println("not go"); }
}
public class EFrog {
public static void main(String[] args) {
Frog f = new Frog();
f.go();
}
}
在这个简单的程序中,实际上没有区别。但是如果你有一个两栖动物f
,它可以指任何两栖动物,而不仅仅是青蛙
。您仍然使用两栖动物
提供的所有方法,即使它是青蛙
有关多态性的描述,请参阅。这就是我们所知道的多态性。那是许多形状。同一物体的许多形状。正如你所了解的,同一个物体可以被称为青蛙,也可以被称为两栖动物。当引用为两栖类时,原始对象仍然是Frog,因此调用重写的方法
但是我不明白青蛙f=新青蛙()之间的区别是什么;两栖动物f=新蛙()
为了理解差异,让我们在Frog
中添加另一个方法,该方法不在两栖动物中
class Frog extends Amphibian {
void go() { System.out.println("not go"); }
void come() { System.out.println("come"); }
}
现在让我们来看看有什么不同:
public class EFrog {
public static void main(String[] args) {
Frog f = new Frog();
f.go();
f.come();
Amphibian a = f;
a.come();//this won't compile
}
}
底线<代码>青蛙
是一种两栖动物
因此青蛙
可以做两栖动物
能做的任何事情<代码>两栖动物
不是青蛙
所以两栖动物
不能做青蛙
能做的一切
当您说两栖动物a=new Frog()
时,您正在编程一个接口(不是java接口,而是接口的一般含义)。当您说Frog f=new Frog()
时,您正在编程实现
现在来看看这本书要求你尝试的实际问题:
在main()中,创建一只青蛙并将其向上投射到两栖动物并演示
所有的方法仍然有效
我不认为你想问上溯有什么用,但既然标题已经被其他人编辑过,为什么不回答这个问题呢?向上转换在某些情况下很有用,例如显式调用重载方法的特殊形式。有关更多详细信息,请参见答案。也请参见区别,您可以向Frog添加一个方法jump()(但不能将其添加到基类两栖动物:
class Amphibian {
void go() { System.out.println("go"); }
void stop() { System.out.println("stop!"); }
}
class Frog extends Amphibian {
void go() { System.out.println("not go"); }
void jump() { System.out.println("jump!"); }
}
public class EFrog {
public static void main(String[] args) {
Frog f = new Frog();
f.go();
f.jump(); // works
Amphibian a = new Frog();
a.jump(); // will not compile!
}
}
这个很简单
如果你像下面这样使用
Frog f=new Frog();
然后,您不能将其强制转换为任何其他类型。但是,您可以调用所有Frog
方法
但是如果你像下面这样使用
两栖动物f=新青蛙();
通过这样做,您仍然可以将对象更改为其他两栖动物,而无需更改其引用
f=newsomeother两栖动物();
这种编码方式非常流行,称为对基类或接口进行编码
青蛙f=新青蛙();
和两栖动物f=新青蛙();
从您的示例中,我们可以看到,Frog
继承了两栖动物
。因此,在您的示例中,任何声明为两栖动物
类型的变量都可以始终存储具有超类的对象实例,如两栖动物
。至于示例代码,它没有区别
但是在这两个例子中找不到细微的差别。请考虑以下内容:
class Frog extends Amphibian {
void go() { System.out.println("not go"); }
void croak(){ System.out.println("croak");} //Added this extra line
}
现在,如果将Frog
实例存储为
Amphibian f = new Frog();
f.croak(); //This will not work.
这不起作用,因为JVM将f视为类型两栖动物
,并且在两栖动物
类中没有方法croak
。因此会引发错误。但如果您将其存储为:
Frog f = new Frog();
f.croak(); //This will work.
这是因为JVM将f视为类型Frog
,而类Frog
具有方法croak
当然,您可以通过将f转换为Frog
,使前面的案例生效,如下所示:
Amphibian f = new Frog();
((Frog)f).croak(); //This will work.
Amphibian f = new Frog();
((Frog)f).croak(); //This will work.