Java中的静态和动态绑定
请有人给我解释一下最后6行输出是如何打印出来的。我知道由于静电装订,前三行印刷得很恰当Java中的静态和动态绑定,java,oop,binding,polymorphism,dynamic-binding,Java,Oop,Binding,Polymorphism,Dynamic Binding,请有人给我解释一下最后6行输出是如何打印出来的。我知道由于静电装订,前三行印刷得很恰当 IpodPlayer player2 = null; if(ipl instance of IpodPlayer) player2 = (IpodPlayer)ipl; 我不知道为什么第5行会给出输出,因为它是Ipod类型,没有任何歌曲方法,但仍然会打印输出。 代码如下: package myferrari; import mycar.*; class IPOD { void PlayM
IpodPlayer player2 = null;
if(ipl instance of IpodPlayer)
player2 = (IpodPlayer)ipl;
我不知道为什么第5行会给出输出,因为它是Ipod类型,没有任何歌曲方法,但仍然会打印输出。
代码如下:
package myferrari;
import mycar.*;
class IPOD
{
void PlayMusic(Music m)
{
System.out.println("Music from Ipod");
}
}
class IpodPlayer extends IPOD
{
void PlayMusic(Music m)
{
System.out.println("Music from IpodPlayer");
}
void PlayMusic(Song m)
{
System.out.println("Song from IpodPlayer");
}
}
class Music{}
class Song extends Music{}
public class Main {
public static void main(String [] args)
{
IPOD ipod = new IPOD();
IpodPlayer iplayer = new IpodPlayer();
IPOD ipl = new IpodPlayer();
Music m = new Music();
Song s = new Song();
Music sm = new Song();
iplayer.PlayMusic(m);
iplayer.PlayMusic(s);
iplayer.PlayMusic(sm); // static binding refers to the reference type
ipod.PlayMusic(m);
ipod.PlayMusic(s);
ipod.PlayMusic(sm);
ipl.PlayMusic(m);
ipl.PlayMusic(s);
ipl.PlayMusic(sm);
}
}
输出如下:
来自IpodPlayer的音乐
来自IpodPlayer的歌曲
来自IpodPlayer的音乐
来自Ipod的音乐
来自Ipod的音乐
来自Ipod的音乐
来自IpodPlayer的音乐
来自IpodPlayer的音乐
来自IpodPlayer的音乐
进行打印的类有一个方法,该方法将对象作为音乐类,而不是Song的子类 为了做你想做的事,你必须做以下事情:
void PlayMusic(Music m){
if(m instance of Song){
System.out.println("Song from Ipod");
} else
System.out.println("Music from Ipod");
}
由于您将ipl声明为超级类IPOD并将其实例化为IPodPlayer,因此除非您检查其类型并适当地强制转换,否则它的行为与IPOD相同
IpodPlayer player2 = null;
if(ipl instance of IpodPlayer)
player2 = (IpodPlayer)ipl;
但是这样做是没有意义的,所以只需将它用作您希望它表现为的类
这篇文章比我解释得更好 原因是:
首先,java使用静态绑定从一组重载方法中进行选择。然后在从重写的方法集中进行选择时使用动态绑定。
我认为你理解为什么要打印前三行,所以我不会解释这背后的原因 所以就这样想吧。无论何时“扩展”到一个类,实际上都是在创建该类的新副本并向其中添加内容。 如果您将一个类想象成一个包含房间(方法)和设备(变量)的房子的蓝图,那么一个扩展另一个类的类就是一个基于另一个蓝图的房子的蓝图,其中包含一些可能的修改/添加。当您创建扩展另一个蓝图的蓝图时,您添加的任何房间或设备,如果与原始蓝图中的某个内容具有相同的签名(相同的名称/类型/参数),将覆盖原始蓝图中的该内容 解释为什么每一行都像这样打印: 第4行:您创建了一个IPOD类,它只有一个方法,并打印相同的内容“来自IPOD的音乐” 第5行:您创建了一个IPOD类,它只有一个方法并打印相同的内容,“来自IPOD的音乐”。是的,该方法只接受音乐类型,而歌曲扩展了音乐。回到例子:这意味着音乐之家的房间和设备都在歌曲之家内部。因此,由于该方法不寻找歌曲库,因此它会删除不属于音乐库的所有内容并将其丢弃。然后将音乐之家交给IPOD类内部的方法 第6行:您创建了一个IPOD类,它只有一个方法,并打印相同的内容“来自IPOD的音乐”。SM是一个音乐对象,因此它很容易传递给方法 第8行:因此第8行由以下代码行组成:
IPOD ipl = new IpodPlayer();
Song s = new Song();
ipl.PlayMusic(s);
ipl属于IPOD类,而不是IpodPlayer类。IPOD类中没有对象歌曲的方法。当您写入“IPOD ipl=new IpodPlayer();”时,您并没有创建IpodPlayer对象。您正在创建一个IPOD对象。
在本文中,当您说“new iPodLayer”时,实际上是说使用iPodLayer蓝图构建IPOD对象。IPOD对象是一个具有一个方法“void PlayMusic(Music m)”的类。所以ipl只有一种方法(音乐方法)。
它之所以说“来自Ipod播放器的音乐”,而不是“来自Ipod的音乐”,是因为在使用Ipod播放器蓝图构建Ipod对象时,您使用具有相同符号(void PlayMusic(Music m))的Ipod播放器方法覆盖了Ipod方法。这仅仅是因为IpodPlayer正在扩展IPOD类
第7行和第9行:IPL是一个IPOD类,但是在声明期间,您可以使用IpodPlayer类中相同的命名方法覆盖名为“PlayMusic”的方法。这就是为什么m、s和sm都打印出“来自IpodPlayer的音乐”核心部分:整个概念是关于方法重载和重写,以及它们如何与动态和静态绑定相联系 现在,首先看下面的代码片段,它是对您的案例@run-time的简化,并理解运行时的图片。使用您选择的任何IDE调试您的代码,您将看到完全相同的结果 主要外卖:在运行时,您的引用将解析为实际对象,这称为动态绑定或多态性。运行时表示对象。因此,无论
IpodPlayer iplayer=new IpodPlayer()代码>或<代码>IPOD ipl=新IpodPlayer()
,在运行时您将获得IpodPlayer
的实例,并将调用其方法
动态绑定链接到方法覆盖。因此,在运行时,将调用哪个被重写的方法是通过检查对象类型来决定的。因此,您可以看到,无论引用类型是什么,在运行时都会调用实际对象的方法
这总结了动态绑定和方法重写
静态绑定和方法重载
静态绑定明确了java中重载方法在编译时如何使用类型信息进行绑定
现在,您的案例是IPOD=new IPOD()
非常清楚,因为您只有方法,没有重载方法,所以您的结果4、5和6是自解释的
真正的困惑在于IpodPlayer iplayer=new IpodPlayer()代码>和IPOD ipl=新的IpodPlayer()代码>
编译时根据对象类型决定调用哪个重载方法,无论是PlayMusic(Music m)
还是PlayMusic(Song m)
请注意,我只谈论方法,而不是哪个类或对象。 new IpodPlayer().PlayMusic(new Music()); //Music from IpodPlayer
new IpodPlayer().PlayMusic(new Song()); //Song from IpodPlayer
new IpodPlayer().PlayMusic(new Song()); //Music from IpodPlayer
new IPOD().PlayMusic(new Music()); //Music from Ipod
new IPOD().PlayMusic(new Song()); //Music from Ipod
new IPOD().PlayMusic(new Song()); //Music from Ipod
new IpodPlayer().PlayMusic(new Music()); //Music from IpodPlayer
new IpodPlayer().PlayMusic(new Song()); //Music from IpodPlayer
new IpodPlayer().PlayMusic(new Song()); //Music from IpodPlayer