【发布时间】:2018-03-13 08:27:02
【问题描述】:
所以我在理解动态绑定与向上转换时有些困惑。
我最初的理解是,当您创建 base_class 引用并将其分配给派生类对象时,例如:
base_class obj = new derived_class();
您现在可以使用obj.method_of_derived class() 调用derived_class 的方法/成员函数,而无需动态绑定。
我认为您只需要在 base_class 和 derived_class 具有同名的函数/方法时才需要动态绑定,并且在编译期间需要进行某种覆盖才能正确分配它们。
我完全错了吗?
或者下面的代码不起作用还有其他原因吗?
public class Ticket {
protected String flightNo;
public Ticket(){
this.flightNo = new String();
}
public void setTicket(lnode ticket){
this.flightNo= ticket.getFlightNumber();
}
public void displayTicket(){
System.out.println("Flight number: " + this.flightNo);
}
}
以及从上述类扩展而来的派生类
public class originalTicket extends Ticket {
protected boolean catchAnotherFlight;
protected boolean baggageTransfer;
public originalTicket(){
catchAnotherFlight = false;
baggageTransfer = false;
}
public void setoriginalTicket(lnode ticket){
setTicket(ticket);
}
}
我无法做到这一点:
Ticket object = new originalTicket();
object.setoriginalTicket();//Can't call the originalTicket method.
我在 C++ 中使用向上转换编写了一些程序,但我总是使用动态绑定。我只是想学习 Java,现在我有点吃惊,我一直把所有的概念都弄错了。谢谢。
【问题讨论】:
-
"...当您创建一个 base_class 指针并将其分配给派生类对象时..." 当您将 object 分配给变量(这是一个引用变量,我们在 Java 中通常不使用“指针”),而不是相反。 :-)
-
@T.J.Crowder 抱歉,这是我第一次尝试使用 Java。我的意思是参考。完全相反。
-
您始终只能访问已声明类的字段和方法。如果您的对象被声明为
Ticket,您将始终看到Ticket类的属性和方法,那么您将无法在没有强制转换的情况下使用originalTicket方法。这就是为什么你不能在object上调用setoriginalTicket(你也有一个缺失的参数,但这不是它不起作用的主要原因) -
@BackSlash 好的,很困惑。所以这不是选角吗?
base_class ref1 = new derived_class();现在ref1不应该可以调用派生类的方法了吗? -
@LucAux 您可以将其视为隐式向上转换;来自 C++,不过我更喜欢“转换”这个词。无论哪种措辞,您都将派生类的接口简化为基类的接口。基类中的任何未知内容都无法通过引用(Java 和 C++)或指针(C++)在没有显式向下转换的情况下访问(除了具有覆盖虚拟基类的方法/函数的派生类)。
标签: java dynamic-binding upcasting