昨天我接受了两个小时的技术电话采访(我通过了,哇喔!),但我完全消除了关于Java中动态绑定的以下问题.这让我感到非常困惑,因为几年前,当我还是TA时,我曾经向大学生传授这个概念,所以我给他们错误信息的前景有点令人不安......
这是我给出的问题:
/* What is the output of the following program? */
public class Test {
public boolean equals( Test other ) {
System.out.println( "Inside of Test.equals" );
return false;
}
public static void main( String [] args ) {
Object t1 = new Test();
Object t2 = new Test();
Test t3 = new Test();
Object o1 = new Object();
int count = 0;
System.out.println( count++ );// prints 0
t1.equals( t2 ) ;
System.out.println( count++ );// prints 1
t1.equals( t3 …Run Code Online (Sandbox Code Playgroud) 我正在为我的一个类做一个任务,在其中,我必须使用Java语法给出静态和动态绑定的示例.
我理解基本概念,即静态绑定在编译时发生,动态绑定在运行时发生,但我无法弄清楚它们实际上是如何工作的.
我在网上找到了一个静态绑定的例子,给出了这个例子:
public static void callEat(Animal animal) {
System.out.println("Animal is eating");
}
public static void callEat(Dog dog) {
System.out.println("Dog is eating");
}
public static void main(String args[])
{
Animal a = new Dog();
callEat(a);
}
Run Code Online (Sandbox Code Playgroud)
并且这将打印"动物正在吃"因为调用callEat使用静态绑定,但我不确定为什么这被认为是静态绑定.
到目前为止,我所看到的所有来源都没有设法以我能够遵循的方式解释这一点.
我对动态绑定和静态绑定感到困惑.我已经读过在编译时确定对象的类型称为静态绑定,在运行时确定它称为动态绑定.
以下代码中会发生什么:
静态绑定还是动态绑定?
这显示了什么样的多态性?
class Animal
{
void eat()
{
System.out.println("Animal is eating");
}
}
class Dog extends Animal
{
void eat()
{
System.out.println("Dog is eating");
}
}
public static void main(String args[])
{
Animal a=new Animal();
a.eat();
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试让ASP.NET 3.5 GridView在显示时将所选值显示为字符串,并显示DropDownList以允许我在编辑时从给定的选项列表中选择一个值.看起来很简单?
我的gridview看起来像这样(简化):
<asp:GridView ID="grvSecondaryLocations" runat="server"
DataKeyNames="ID" OnInit="grvSecondaryLocations_Init"
OnRowCommand="grvSecondaryLocations_RowCommand"
OnRowCancelingEdit="grvSecondaryLocations_RowCancelingEdit"
OnRowDeleting="grvSecondaryLocations_RowDeleting"
OnRowEditing="grvSecondaryLocations_RowEditing"
OnRowUpdating="grvSecondaryLocations_RowUpdating" >
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblPbxTypeCaption" runat="server"
Text='<%# Eval("PBXTypeCaptionValue") %>' />
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlPBXTypeNS" runat="server"
Width="200px"
DataTextField="CaptionValue"
DataValueField="OID" />
</EditItemTemplate>
</asp:TemplateField>
</asp:GridView>
Run Code Online (Sandbox Code Playgroud)
不处于编辑模式时,网格显示OK - 所选PBX类型在asp:Label控件中显示其值.这并不奇怪.
我将DropDownList的值列表加载到窗体事件中调用的本地成员_pbxTypes中OnLoad.我验证了这一点 - 它有效,值得存在.
现在我的挑战是:当网格进入特定行的编辑模式时,我需要绑定存储在其中的PBX列表_pbxTypes.
很简单,我想 - 只需抓住RowEditing事件中的下拉列表对象并附加列表:
protected void grvSecondaryLocations_RowEditing(object sender, GridViewEditEventArgs e)
{
grvSecondaryLocations.EditIndex = e.NewEditIndex;
GridViewRow editingRow = grvSecondaryLocations.Rows[e.NewEditIndex];
DropDownList ddlPbx = (editingRow.FindControl("ddlPBXTypeNS") as DropDownList);
if (ddlPbx != null)
{ …Run Code Online (Sandbox Code Playgroud) 因此,vtable是由编译器维护的表,其中包含指向该类中的虚函数的函数指针.
和
将派生类的对象分配给祖先类的对象称为向上转换.
向上转换使用基类指针或引用处理派生类实例/对象; 对象不是"赋值给",这意味着覆盖值ala operator = invocation.
(感谢:Tony D)
现在,如何在运行时知道"哪个"类的虚函数应该被调用?
vtable中的哪个条目指的是应该在运行时调用的"特定"派生类的功能?
在下面的代码中,第一个和第二个打印语句如何打印出SubObj?顶部和子指向同一个Sub类吗?
class Top {
public String f(Object o) {return "Top";}
}
class Sub extends Top {
public String f(String s) {return "Sub";}
public String f(Object o) {return "SubObj";}
}
public class Test {
public static void main(String[] args) {
Sub sub = new Sub();
Top top = sub;
String str = "Something";
Object obj = str;
System.out.println(top.f(obj));
System.out.println(top.f(str));
System.out.println(sub.f(obj));
System.out.println(sub.f(str));
}
}
Run Code Online (Sandbox Code Playgroud)
以上代码返回以下结果.
SubObj
SubObj
SubObj
Sub
Run Code Online (Sandbox Code Playgroud) 我做了一些研究,找出为什么构造函数不能虚拟.我在这里巩固了我的理解.
我将首先解释什么是虚函数,然后根据第一个解释解释为什么构造函数不能是虚函数.
什么是virtual function?
虚函数是基类中的函数或方法,可以通过具有相同签名的函数在派生类中重新定义或覆盖.换句话说,虚函数允许在派生类中具有基类方法的自定义实现.它需要使用
virtual关键字声明.在虚函数调用时,决定在运行时选择函数定义的哪个版本(在基类或派生类中),具体取决于调用对象的类型(动态绑定).当函数声明为virtual时,它告诉编译器应该仅在运行时确定调用虚函数的对象的类型.然后根据对象的类型,函数调用应该绑定到函数定义,并且应该调用适当的函数.
为什么一个constructor不能虚拟?
当函数声明为virtual时,它告诉编译器应该仅在运行时确定调用该函数的对象的类型,然后根据对象的类型调用该函数的相应版本.
如果要将构造函数声明为virtual,它将告诉编译器应该在运行时确定将调用构造函数的对象类型.但是对于构造对象,应该在编译时而不是在运行时知道对象的确切类型.这就是构造函数不能虚拟的原因.
我希望SO成员纠正两个答案中的错误,如果有的话.我认为这对我和其他人有帮助,如果你可以通过重写它作为你的答案来纠正答案,而不是仅仅指出错误.
匿名类在c#中只读取属性.这通常用于在linq select query中声明从数据库中获取特定值.在我的代码中,我有以下查询.让我混淆使用新语句选择匿名类的新对象的事情.我有一个模型类StudentClerkshipsLogModel.当我使用模型名称时,查询结果允许编辑.
var query = (from entity in _tblStudentClerkshipsLog.GetQueryable()
where entity.StudentID == intStudentID
select new StudentClerkshipsLogModel
{
StudentClerkshipID = entity.StudentClerkshipID,
StudentID = entity.StudentID,
ClerkshipID = entity.ClerkshipID,
}).ToList();
Run Code Online (Sandbox Code Playgroud)
当我new在select声明后没有提到类型时我无法退出.编译器引发错误.匿名对象是只读的.
var query = (from entity in _tblStudentClerkshipsLog.GetQueryable()
where entity.StudentID == intStudentID
select new
{
StudentClerkshipID = entity.StudentClerkshipID,
StudentID = entity.StudentID,
ClerkshipID = entity.ClerkshipID,
}).ToList()
Run Code Online (Sandbox Code Playgroud)
我的问题是linq如何以不同方式绑定两个查询.两个查询都有动态绑定,或者第一个是静态的.
谢谢
由于方法的静态绑定的C++性质,这会影响多态调用.
来自维基百科:
尽管此调度机制所涉及的开销很低,但对于该语言设计为目标的某些应用程序区域,它仍然可能很重要.出于这个原因,C++的设计者Bjarne Stroustrup选择了动态调度可选和非默认.只有使用virtual关键字声明的函数才会根据对象的运行时类型进行调度; 其他函数将根据对象的静态类型进行调度.
所以代码:
Polygon* p = new Triangle;
p->area();
Run Code Online (Sandbox Code Playgroud)
如果它area()是Child类non-virtual中Parent类中的函数overridden,则上面的代码将调用Parent's class method开发人员可能不期望的函数.(感谢我介绍的静态绑定)
所以,如果我想编写一个供其他人使用的类(例如库),我是否应该将所有函数都设置为虚拟,以便以前的代码按预期运行?
dynamic-binding ×10
java ×4
c++ ×3
polymorphism ×2
asp.net ×1
binding ×1
c# ×1
constructor ×1
gridview ×1
inheritance ×1
linq ×1
oop ×1
overloading ×1
upcasting ×1
virtual ×1
vtable ×1