有关java 继承和多态的问题

xingxing_aibiancheng 2009-03-19 09:03:45
请看如下代码:

public class Base { // 父类Base
int i=1;
public void amethod(){
System.out.println("Base.amethod()");
}
public Base(){
this.amethod();
}
}
public class Descend extends Base { // 子类Descend
int i=-1;
public static void main(String[] arg){
Base b=new Descend();
System.out.println(b.i);
b.amethod();
}
public void amethod(){
System.out.println("Descend.amethod()");
}
}
为什么运行结果是
Descend.amethod()
1
Descend.amethod()

而不是
Base.amethod()
-1
Descend.amethod()
请各位大虾帮忙分析分析
...全文
1180 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
dxpws 2009-03-20
  • 打赏
  • 举报
回复
up
teddybek 2009-03-19
  • 打赏
  • 举报
回复
// 获取所有逻辑盘并列出硬盘所有目录
// </summary>
private void ListDrives()
{
TreeNode tn;

// 获取系统中的所有逻辑盘
string[] drives = Directory.GetLogicalDrives();

// 向树视图中添加节点
tvDir.BeginUpdate();
for(int i=0;i<drives.Length;i++)
{
// 根据驱动器的不同类型来确定所进行的操作
switch( GetDriveType( drives[i] ))
{
case 2: // 软驱
// 如果是软驱,则仅向树视图中添加节点
// 而不列举它的目录,并且它的图像索引以及
// 处于选择状态下的图像索引分别为0和0
tn = new TreeNode( drives[i] ,0,0);
break;
case 3: // 硬盘
// 如果是硬盘,则除了向树视图中添加节点外,
// 还要列举出它的目录
tn = new TreeNode( drives[i],1,1);
ListDirs(tn,drives[i]); // 列举硬盘中的目录
break;
case 5: // 光驱
// 如果是光驱,则仅向树视图中添加节点
tn = new TreeNode( drives[i],2,2);
break;
default: // 在默认情况下,按软驱的情况进行处理
tn = new TreeNode( drives[i] ,0,0);
break;
}
tvDir.Nodes.Add( tn ); // 把创建的节点添加到树视图中
}
tvDir.EndUpdate();

// 把C盘设为当前选择节点
tvDir.SelectedNode = tvDir.Nodes[1];
}


public MainForm()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();


nDirLevel = 0; // 把列举深度初始化为0
ListDrives(); // 获取逻辑驱动器并列出硬盘中的目录
}


// <summary>
// 递归列出指定目录的所有子目录
// </summary>
private void ListDirs(TreeNode tn,string strDir)
{
if( nDirLevel>4 ) // 调整该行语句,可以改变列举目录的深度
{
nDirLevel = 0;
return;
}
nDirLevel++;
string[] arrDirs;
TreeNode tmpNode;

try
{
// 获取指定目录下的所有子目录
arrDirs = Directory.GetDirectories( strDir);
if( arrDirs.Length == 0 ) return;
// 把每一个子目录添加到参数传递进来的树视图节点中
for( int i=0;i<arrDirs.Length;i++)
{
tmpNode = new TreeNode( Path.GetFileName(arrDirs
[i]),3,4 );
// 对于每一个子目录,都进行递归列举
ListDirs( tmpNode,arrDirs[i] );
tn.Nodes.Add( tmpNode );
}
}
catch
{
return;
}
}

// <summary>
// 列出指定目录下的所有子目录和文件
// </summary>
private void ListDirsAndFiles(string strDir)
{
ListViewItem lvi;
int nImgIndex;
string[] items = new String[4];
string[] dirs;
string[] files;
try
{
// 获取指定目录下的所有子目录
dirs = Directory.GetDirectories( strDir );
// 获取指定目录下的所有文件
files = Directory.GetFiles( strDir );
}
catch
{
return;
}
hunray 2009-03-19
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 successgl 的回复:]

Base b=new Descend(); 是先生成一个Descend对象,然后把其赋值给Base对象b(实际b是持有新生成对象的引用),

System.out.println(b.i); 此时取出的b.i是Base对象的中属性,因为 虽然这个对象实际是Descend的,可以认为已经强制转成Base类型的,此时编译器并不知道是Descend类型的,所以取出的是1

b.amethod(); 虽然b是Base类型的,但是方法是支持多态的,就是子类Descend已经重写了amethod()方法,所以
调用的是实…
[/Quote]
学习了。
fzdxwhl2007 2009-03-19
  • 打赏
  • 举报
回复
上面看错了
//构造子类时,先调父类的构造直到Object类为止,这里执行父类amethod(); 这边由于多态执行的是子类的amethod();

失误失误
  • 打赏
  • 举报
回复
是啊,那我一定要看看,刚才问了问3楼的朋友,他告诉我关于i的问题:对于变量编译的时候已经确定即 Base b=new Decsend();时i就已经指定是父类的了,其余的问题就是多态的范畴了,感谢大家,第一次发帖就有这莫多人响应,以后我会经常来玩儿的。
fzdxwhl2007 2009-03-19
  • 打赏
  • 举报
回复
public class Base { // 父类Base
int i=1;
public void amethod(){
System.out.println("Base.amethod()");
}
public Base(){
this.amethod();
}
}
public class Descend extends Base { // 子类Descend
int i=-1;
public static void main(String[] arg){
Base b=new Descend(); //构造子类时,先调父类的构造直到Object类为止,这里执行父类amethod();
System.out.println(b.i); //这里为父类引用,所以打印1
b.amethod(); //由于子类重写了父类方法,这边调子类方法
}
public void amethod(){
System.out.println("Descend.amethod()");
}
}
为什么运行结果是
Descend.amethod()
1
Descend.amethod()

而不是
Base.amethod()
-1
Descend.amethod()
zhangbo6791644 2009-03-19
  • 打赏
  • 举报
回复
呵呵,兄弟,我弄错了,呵呵,属性是不支持的了,呵呵,失误,失误啊!!
我来解释一下你的情况
Descend.amethod()
1
Descend.amethod()
先从的父类的构造函数进去,那个this就是子类了,而关于属性是不支持的了,用的是父类的属性
呵呵,不好意思,弄错了
successgl 2009-03-19
  • 打赏
  • 举报
回复
你可以看一下《java编程思想》的,这书讲的挺明白的
  • 打赏
  • 举报
回复
半信半疑,不过还是非常感谢!
successgl 2009-03-19
  • 打赏
  • 举报
回复

Base b=new Descend(); 是先生成一个Descend对象,然后把其赋值给Base对象b(实际b是持有新生成对象的引用),

System.out.println(b.i); 此时取出的b.i是Base对象的中属性,因为 虽然这个对象实际是Descend的,可以认为已经强制转成Base类型的,此时编译器并不知道是Descend类型的,所以取出的是1

b.amethod(); 虽然b是Base类型的,但是方法是支持多态的,就是子类Descend已经重写了amethod()方法,所以
调用的是实际的Descend类型的方法,这与System.out.println(b.i)是不一样的,可以认为属性的不支持多态的

水平有限,难免会有错误!
zhangbo6791644 2009-03-19
  • 打赏
  • 举报
回复
把接口的用法用到这上面,思想又是是继承的,当然都糊涂了呵呵
  • 打赏
  • 举报
回复
哥们儿你写的好像跟我说的不一样吧,我用的是多态,你One one=new One();
这莫写,好像跟我的问题没有联系吧
心如刀割 2009-03-19
  • 打赏
  • 举报
回复
父类为子类实例化调用的肯定是子类的方法.
public Base(){
this.amethod();
} 你子类也有amethod()这个方法,调用的就是子类的,至于为什么i的值也是父类的我再想想
Alon知行 2009-03-19
  • 打赏
  • 举报
回复

属性不体现多态,

Base b=new Descend();
public Base(){
this.amethod();
} 执行子类的方法,我在子类的方法中添加了super.amethod方法得到了Base.amethod()

public void amethod(){
super.amethod();
System.out.println("Descend.amethod()");
}
我揣测 在创建对象时 会先从子类的空间中寻找这个方法

我还没找到理论根据 等待高人来解答...
  • 打赏
  • 举报
回复
那public Base(){
this.amethod();
}
输出为什么不是父类的呢?
心如刀割 2009-03-19
  • 打赏
  • 举报
回复
这题是有点迷惑,我再想想。。。。
  • 打赏
  • 举报
回复
照你这莫说
中运行结果中
Descend.amethod()
1
Descend.amethod()
应该改写为

Base.amethod()
1
Base.amethod()
了,这样就是调用父类的了,我是这样理解的
guxiangzhang 2009-03-19
  • 打赏
  • 举报
回复
没那莫简单吧,执行Base b=new Descend(); 时先调用父类的构造函数
public Base(){
this.amethod();
}
但this.amethod()是执行的子类的方法,
还有为什么System.out.println(b.i); 输出的是父类的i?



调用子类构造方法前先执行父类构造方法 。 但b是父类的对象,所以System.out.println(b.i); 输出的是父类的i。
不知道这样解释号理解不?
zhangbo6791644 2009-03-19
  • 打赏
  • 举报
回复
public class Two{
int i=1;
public Two()
{
this.getTwo();
}

public void getTwo()
{
System.out.println("Two.getTwo()");
}


}

public class One extends Two {

int i=10;
public One()
{

}
public void getOne()
{
System.out.println("One.getOne()");
}

public static void main(String[] arg)
{
One one=new One();
one.getOne();
}
}
你改改,你的代码方法的名称都一样
zhangbo6791644 2009-03-19
  • 打赏
  • 举报
回复
你是为父类创建的实例,Descend是Base的子类呀,你那样new,肯定是父类的
加载更多回复(6)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧