看到了"动态方法调度",有这两个概念弄不明白,能给我说一下吗?
17 个解决方案
#1
这种问题还是好好去看书的好,三言两语也说不清楚
#2
我自认为这涉及到实参和形参的问题
引用变量实际就是使用形式参数,是一个参数传递过程
引用对象实际是使用实际参数,是不用传值而直接使用
这是我写程序体会出来的,不知正步正确,自己体会体会
引用变量实际就是使用形式参数,是一个参数传递过程
引用对象实际是使用实际参数,是不用传值而直接使用
这是我写程序体会出来的,不知正步正确,自己体会体会
#3
引用变量(主类型)就是值传递, 无论怎么变都不影响实参。
应用对象是直接使用,你就当它是指针。
应用对象是直接使用,你就当它是指针。
#4
大家能举个例子吗?
书上有句话是这样说的:
"理解是引用变量的类型--而不是引用对象的类型--决定了什么成员可以被访问.也就是说,当一个子类对象的引用被赋给一个超类引用变量时,你只能访问超类定义的对象的那一部分.这是为什么plainbox不能访问weight的原因,甚至是它引用了一个BoxWeight对象也不行."
超类Box
子类BoxWeight
BoxWeight weightbox = new BoxWeight();
Box plainbox = new Box();
plainbox = weightbox;
weight是子类BoxWeight的一个变量...
书上有句话是这样说的:
"理解是引用变量的类型--而不是引用对象的类型--决定了什么成员可以被访问.也就是说,当一个子类对象的引用被赋给一个超类引用变量时,你只能访问超类定义的对象的那一部分.这是为什么plainbox不能访问weight的原因,甚至是它引用了一个BoxWeight对象也不行."
超类Box
子类BoxWeight
BoxWeight weightbox = new BoxWeight();
Box plainbox = new Box();
plainbox = weightbox;
weight是子类BoxWeight的一个变量...
#5
plainbox是超类Box的引用变量吗?
#6
不是引用变量
是一个实例
是一个实例
#7
那书上怎么这么讲呢?
"当一个子类对象的引用被赋给一个超类引用变量时,你只能访问超类定义的对象的那一部分."
plainbox = weightbox;
"当一个子类对象的引用被赋给一个超类引用变量时,你只能访问超类定义的对象的那一部分."
plainbox = weightbox;
#8
大侠,能告诉我吗?
#9
当plainbox = weightbox;以后有以下特点:
1、plainbox的类型是Box(即上述的各“引用变量类型”,这是变量声明时定义的);
2、plainbox变量所指向的具体对象是BoxWeight类型的;(即上述的“引用对象类型”);
此时假设Box定义的成员有A、B;BoxWeight则包括继承而来的A、B以及自己定义的C。因为plainbox变量所指向的具体对象是BoxWeight类型的,所以实际上他有A、B、C三个成员。但是其中只有A、B可访问(因为plainbox的类型是Box,而对于Box类型来说公开可知的成员只有A、B,子类定义的C是不可知的),这就是所谓的“引用变量的类型(而不是引用对象的类型)决定了什么成员可以被访问”。
1、plainbox的类型是Box(即上述的各“引用变量类型”,这是变量声明时定义的);
2、plainbox变量所指向的具体对象是BoxWeight类型的;(即上述的“引用对象类型”);
此时假设Box定义的成员有A、B;BoxWeight则包括继承而来的A、B以及自己定义的C。因为plainbox变量所指向的具体对象是BoxWeight类型的,所以实际上他有A、B、C三个成员。但是其中只有A、B可访问(因为plainbox的类型是Box,而对于Box类型来说公开可知的成员只有A、B,子类定义的C是不可知的),这就是所谓的“引用变量的类型(而不是引用对象的类型)决定了什么成员可以被访问”。
#10
那为什么以下程序会输出这样的结果呢?
class A{
void Callme()
{
System.out.println("Inside A's Callme method");
}
}
class B extends A{
void Callme()
{
System.out.println("Inside B's Callme method");
}
}
class C extends A{
void Callme()
{
System.out.println("Inside C's Callme method");
}
}
class Dispatch
{
public static void main(String[] args)
{
A a = new A();
B b = new B();
C c = new C();
A r;
r = a;
r.callme();
r = b;
r.callme();
r = c;
r.callme();
}
}
结果:
Inside A's callme method
Inside B's callme method
Inside C's callme method
class A{
void Callme()
{
System.out.println("Inside A's Callme method");
}
}
class B extends A{
void Callme()
{
System.out.println("Inside B's Callme method");
}
}
class C extends A{
void Callme()
{
System.out.println("Inside C's Callme method");
}
}
class Dispatch
{
public static void main(String[] args)
{
A a = new A();
B b = new B();
C c = new C();
A r;
r = a;
r.callme();
r = b;
r.callme();
r = c;
r.callme();
}
}
结果:
Inside A's callme method
Inside B's callme method
Inside C's callme method
#11
记住<thinking in java>的作者Bruce Eckel的一句经典的话吧,对象就是神奇的变量。
#12
你能给我解释一下,我上面提的两种情况,为什么不一样吗?
第1个:
"当一个子类对象的引用被赋给一个超类引用变量时,你只能访问超类定义的对象的那一部分"
第2个:
r = b;后,r.callme();显示子类b的方法callme()
第1个:
"当一个子类对象的引用被赋给一个超类引用变量时,你只能访问超类定义的对象的那一部分"
第2个:
r = b;后,r.callme();显示子类b的方法callme()
#13
两种情况并不冲突啊:
1、当r = b;后,根据A类型定义你对r能访问的依然是callme()成员。
2、而此时的r所指向的对象虽然是B型的,其中callme()虽然重载了其超类方法,但编译器依然知道该对象里有一个名为callme的方法可以访问。假设该对象里还包括了其他的在子类中定义的成员方法,那么在此这些子类里定义的方法就不可用了。
3、你的程序里之所以对每各对象调用相同方法而得出了不同结果,其实就是因为对编译器而言,它只知道每个对象里都有一个名为callme的方法可以访问,至于具体每个对象里的callme()执行什么动作是在运行时动态绑定的,这也是多态的一个体现。
1、当r = b;后,根据A类型定义你对r能访问的依然是callme()成员。
2、而此时的r所指向的对象虽然是B型的,其中callme()虽然重载了其超类方法,但编译器依然知道该对象里有一个名为callme的方法可以访问。假设该对象里还包括了其他的在子类中定义的成员方法,那么在此这些子类里定义的方法就不可用了。
3、你的程序里之所以对每各对象调用相同方法而得出了不同结果,其实就是因为对编译器而言,它只知道每个对象里都有一个名为callme的方法可以访问,至于具体每个对象里的callme()执行什么动作是在运行时动态绑定的,这也是多态的一个体现。
#14
也就是,只能方法重载的时候,超类对象才可以访问子类对象,是吗?
#15
子类对象赋值给超类的变量时,只可以访问该对象里符合超类定义(范围)的成员。跟重载方法无关,即便不重载,因为子类是继承自超类的,所以他本就有对应方法。关键问题是对象里有这个方法(其内部动作可不关心);而且根据引用该对象的变量声明编译器可以知道这个方法可用。
#16
是对象(实例)决定调用哪个函数,而非引用。
所以不可能用超类的引用调用到被覆盖的函数版本。
这也是必然的,否则类的继承结构就没意义了。
就好像C++中的虚拟函数,即使用父类的指针指向子类的对象,调用函数也会自动调用子类的函数版本,一个道理。
所以不可能用超类的引用调用到被覆盖的函数版本。
这也是必然的,否则类的继承结构就没意义了。
就好像C++中的虚拟函数,即使用父类的指针指向子类的对象,调用函数也会自动调用子类的函数版本,一个道理。
#17
HERE
#1
这种问题还是好好去看书的好,三言两语也说不清楚
#2
我自认为这涉及到实参和形参的问题
引用变量实际就是使用形式参数,是一个参数传递过程
引用对象实际是使用实际参数,是不用传值而直接使用
这是我写程序体会出来的,不知正步正确,自己体会体会
引用变量实际就是使用形式参数,是一个参数传递过程
引用对象实际是使用实际参数,是不用传值而直接使用
这是我写程序体会出来的,不知正步正确,自己体会体会
#3
引用变量(主类型)就是值传递, 无论怎么变都不影响实参。
应用对象是直接使用,你就当它是指针。
应用对象是直接使用,你就当它是指针。
#4
大家能举个例子吗?
书上有句话是这样说的:
"理解是引用变量的类型--而不是引用对象的类型--决定了什么成员可以被访问.也就是说,当一个子类对象的引用被赋给一个超类引用变量时,你只能访问超类定义的对象的那一部分.这是为什么plainbox不能访问weight的原因,甚至是它引用了一个BoxWeight对象也不行."
超类Box
子类BoxWeight
BoxWeight weightbox = new BoxWeight();
Box plainbox = new Box();
plainbox = weightbox;
weight是子类BoxWeight的一个变量...
书上有句话是这样说的:
"理解是引用变量的类型--而不是引用对象的类型--决定了什么成员可以被访问.也就是说,当一个子类对象的引用被赋给一个超类引用变量时,你只能访问超类定义的对象的那一部分.这是为什么plainbox不能访问weight的原因,甚至是它引用了一个BoxWeight对象也不行."
超类Box
子类BoxWeight
BoxWeight weightbox = new BoxWeight();
Box plainbox = new Box();
plainbox = weightbox;
weight是子类BoxWeight的一个变量...
#5
plainbox是超类Box的引用变量吗?
#6
不是引用变量
是一个实例
是一个实例
#7
那书上怎么这么讲呢?
"当一个子类对象的引用被赋给一个超类引用变量时,你只能访问超类定义的对象的那一部分."
plainbox = weightbox;
"当一个子类对象的引用被赋给一个超类引用变量时,你只能访问超类定义的对象的那一部分."
plainbox = weightbox;
#8
大侠,能告诉我吗?
#9
当plainbox = weightbox;以后有以下特点:
1、plainbox的类型是Box(即上述的各“引用变量类型”,这是变量声明时定义的);
2、plainbox变量所指向的具体对象是BoxWeight类型的;(即上述的“引用对象类型”);
此时假设Box定义的成员有A、B;BoxWeight则包括继承而来的A、B以及自己定义的C。因为plainbox变量所指向的具体对象是BoxWeight类型的,所以实际上他有A、B、C三个成员。但是其中只有A、B可访问(因为plainbox的类型是Box,而对于Box类型来说公开可知的成员只有A、B,子类定义的C是不可知的),这就是所谓的“引用变量的类型(而不是引用对象的类型)决定了什么成员可以被访问”。
1、plainbox的类型是Box(即上述的各“引用变量类型”,这是变量声明时定义的);
2、plainbox变量所指向的具体对象是BoxWeight类型的;(即上述的“引用对象类型”);
此时假设Box定义的成员有A、B;BoxWeight则包括继承而来的A、B以及自己定义的C。因为plainbox变量所指向的具体对象是BoxWeight类型的,所以实际上他有A、B、C三个成员。但是其中只有A、B可访问(因为plainbox的类型是Box,而对于Box类型来说公开可知的成员只有A、B,子类定义的C是不可知的),这就是所谓的“引用变量的类型(而不是引用对象的类型)决定了什么成员可以被访问”。
#10
那为什么以下程序会输出这样的结果呢?
class A{
void Callme()
{
System.out.println("Inside A's Callme method");
}
}
class B extends A{
void Callme()
{
System.out.println("Inside B's Callme method");
}
}
class C extends A{
void Callme()
{
System.out.println("Inside C's Callme method");
}
}
class Dispatch
{
public static void main(String[] args)
{
A a = new A();
B b = new B();
C c = new C();
A r;
r = a;
r.callme();
r = b;
r.callme();
r = c;
r.callme();
}
}
结果:
Inside A's callme method
Inside B's callme method
Inside C's callme method
class A{
void Callme()
{
System.out.println("Inside A's Callme method");
}
}
class B extends A{
void Callme()
{
System.out.println("Inside B's Callme method");
}
}
class C extends A{
void Callme()
{
System.out.println("Inside C's Callme method");
}
}
class Dispatch
{
public static void main(String[] args)
{
A a = new A();
B b = new B();
C c = new C();
A r;
r = a;
r.callme();
r = b;
r.callme();
r = c;
r.callme();
}
}
结果:
Inside A's callme method
Inside B's callme method
Inside C's callme method
#11
记住<thinking in java>的作者Bruce Eckel的一句经典的话吧,对象就是神奇的变量。
#12
你能给我解释一下,我上面提的两种情况,为什么不一样吗?
第1个:
"当一个子类对象的引用被赋给一个超类引用变量时,你只能访问超类定义的对象的那一部分"
第2个:
r = b;后,r.callme();显示子类b的方法callme()
第1个:
"当一个子类对象的引用被赋给一个超类引用变量时,你只能访问超类定义的对象的那一部分"
第2个:
r = b;后,r.callme();显示子类b的方法callme()
#13
两种情况并不冲突啊:
1、当r = b;后,根据A类型定义你对r能访问的依然是callme()成员。
2、而此时的r所指向的对象虽然是B型的,其中callme()虽然重载了其超类方法,但编译器依然知道该对象里有一个名为callme的方法可以访问。假设该对象里还包括了其他的在子类中定义的成员方法,那么在此这些子类里定义的方法就不可用了。
3、你的程序里之所以对每各对象调用相同方法而得出了不同结果,其实就是因为对编译器而言,它只知道每个对象里都有一个名为callme的方法可以访问,至于具体每个对象里的callme()执行什么动作是在运行时动态绑定的,这也是多态的一个体现。
1、当r = b;后,根据A类型定义你对r能访问的依然是callme()成员。
2、而此时的r所指向的对象虽然是B型的,其中callme()虽然重载了其超类方法,但编译器依然知道该对象里有一个名为callme的方法可以访问。假设该对象里还包括了其他的在子类中定义的成员方法,那么在此这些子类里定义的方法就不可用了。
3、你的程序里之所以对每各对象调用相同方法而得出了不同结果,其实就是因为对编译器而言,它只知道每个对象里都有一个名为callme的方法可以访问,至于具体每个对象里的callme()执行什么动作是在运行时动态绑定的,这也是多态的一个体现。
#14
也就是,只能方法重载的时候,超类对象才可以访问子类对象,是吗?
#15
子类对象赋值给超类的变量时,只可以访问该对象里符合超类定义(范围)的成员。跟重载方法无关,即便不重载,因为子类是继承自超类的,所以他本就有对应方法。关键问题是对象里有这个方法(其内部动作可不关心);而且根据引用该对象的变量声明编译器可以知道这个方法可用。
#16
是对象(实例)决定调用哪个函数,而非引用。
所以不可能用超类的引用调用到被覆盖的函数版本。
这也是必然的,否则类的继承结构就没意义了。
就好像C++中的虚拟函数,即使用父类的指针指向子类的对象,调用函数也会自动调用子类的函数版本,一个道理。
所以不可能用超类的引用调用到被覆盖的函数版本。
这也是必然的,否则类的继承结构就没意义了。
就好像C++中的虚拟函数,即使用父类的指针指向子类的对象,调用函数也会自动调用子类的函数版本,一个道理。
#17
HERE