A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 郑元皓 中级黑马   /  2013-3-15 14:05  /  2392 人查看  /  13 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 郑元皓 于 2013-3-15 14:51 编辑

interface A{}
class B implements A
{
        public String test()
        {
                return "yes";
        }
}
class Demo
{
        static A get()
        {
                return new B();
        }
        public static void main(String[] args)
        {
                A a=get();
                System.out.println(a.test());
        }
}
打印结果是:编译失败,因为A接口中没有定义test方法。

这是毕老师的一个小练习题,谁能和我解释下A a=get();这句话的A是哪里的A?是接口的,还是static A get()我理解不到


评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

13 个回复

倒序浏览
  1. interface A{}
  2. class B implements A
  3. {
  4.         public String test()
  5.         {
  6.                 return "yes";
  7.         }
  8. }
  9. class Demo
  10. {
  11.         static A get()
  12.         {
  13.                 return new B();
  14.         }
  15.         public static void main(String[] args)
  16.         {
  17.                 A a=get();
  18.                 System.out.println(a.test());
  19.         }
  20. }
复制代码
A a=get();这句话执行,就会执行
static A get()
{
return new B();
}
这就相当于A a=new B();
这就是多态。
在编译的时候看等号的左边,因为类A中没有方法test,方法test时类B中特有的,所以编译失败。

在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
在多态中,成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属的类)。
在多态中,静态成员函数的特点:
无论编译和运行,都参考做左边。
这些在毕老师的视频day08中讲的很详细的,希望对你有帮助

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
A a=get();这个A是接口,他是由子类的静态方法static A get()
实现的,这是java一个很重要的特性,多态。由子类实现实例化父类,向上转型。呵呵。。
回复 使用道具 举报
因为你这里的a虽然实际上是b对象  但对外暴露出来的是a类型 由于a类型里面没有test()方法 所以在这里会报错
把A a=get();改成 B b = (B)get();这样就可以了
另外class Demo 的前面要加上pubic
否则会找不到主类
回复 使用道具 举报
HM刘博 发表于 2013-3-15 14:20
A a=get();这句话执行,就会执行
static A get()
{

为什么A a=get();这句话执行,
就会执行
static A get()
{
return new B();
}
我就是对这句话理解不出来。新手,能解释的详细点吗?
回复 使用道具 举报
郑元皓 发表于 2013-3-15 14:33
为什么A a=get();这句话执行,
就会执行
static A get()

这就是调用啊
回复 使用道具 举报
HM刘博 发表于 2013-3-15 14:38
这就是调用啊

嗯嗯。理解出来了。谢谢
回复 使用道具 举报
郑元皓 发表于 2013-3-15 14:46
嗯嗯。理解出来了。谢谢

不客气,共同努力
回复 使用道具 举报
interface A{}
class B implements A
{
        public String test()
        {
                return "yes";
        }
}
class Demo
{
        static A get()
        {
                return new B();
        }
        public static void main(String[] args)
        {
                A a=get(); //多态;实现了父类引用指向子类对象。
                //上面这句话等同:A a =new B();   实现了父类引用指向子类对象。
                //现在把方法get()的反回值 new B() ,B的一个实例看作成一个A的对象来用。
                //例如:将一个猎人当作一个普通人来看了。 其中,A为猎人,B为普通人,
               System.out.println(a.test());//既然将猎人只当一个普通人来看,那么他就不会有猎人才具备的打猎方法了。其中将test()看做猎人的打猎方法。
                                      //因为A中没有test()方法,所以a.test()编译错误。
                                       //如果你将  A a=get(); 改成  B a=(B) get(); ,就可以调用a.test()方法了。
        }
}

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 csatshell 于 2013-3-15 15:13 编辑

首先明确一点,你的编译失败是因为多态的问题。
1,static A get()//这是一个方法,方法被静态修饰,方法的返回值类型是接口类型A
        {
                return new B();
       }
2,public static void main(String[] args)

        {

                A a=get();//这个是多态的体现,你使用接口A类型引用接收A的子类对象
               System.out.println(a.test());//使用父类引用调用test()方法,但是你父接口A中有test方法吗?没有,所以你会编译失败。这种情况就是你父类引用接收子类对象且调用子类特有的方法
//这时候若想要编译通过,必须向下转型,回复子类本来的面貌   就是 B b=(B)a;然后再用b调用test方法就行了
        }
改正后的代码如下,供您参考:

  1. <DIV class=blockcode>
  2. <BLOCKQUOTE>
  3. <BLOCKQUOTE> [code]
  4. interface A{}
  5. class B implements A
  6. {
  7.         public String test()
  8.         {
  9.                 return "yes";
  10.         }
  11. }
  12. class Demo
  13. {
  14.         static A get()
  15.         {
  16.                 return new B();
  17.         }
  18.         public static void main(String[] args)
  19.         {
  20.                 A a=get();
  21.     B b=(B)a;
  22.     System.out.println(b.test());
  23.         }
  24. }
复制代码
[/code]

评分

参与人数 2技术分 +2 收起 理由
冯海霞 + 1
洪建超 + 1

查看全部评分

回复 使用道具 举报
  1. interface A{}//这个里面没定义方法 实现接口也没用。很奇怪
  2. class B implements A
  3. {
  4.          public String test()
  5.          {
  6.                  return  "yes";
  7.          }
  8. }
  9. class Demo
  10. {
  11.          static A get()
  12.          {
  13.                  return new B();
  14.          }
  15.          public static void main(String[] args)
  16.          {
  17.                  B a=(B)get();//把A接口类型强转为实现子类类型。
  18.                  System.out.println(a.test());
  19.          }
  20. }
  21. //下面这个代码你应该好理解点。上面的我都有点不懂。
  22. interface C
  23. {
  24.         public String test();
  25. }
  26. class D implements C
  27. {
  28.          public String test()
  29.          {
  30.                  return  "yes";
  31.          }
  32. }

  33. class Demo1
  34. {
  35.          static C get()
  36.          {
  37.                  return new D();
  38.          }
  39.          public static void main(String[] args)
  40.          {
  41.                 C a=get();//子类实现接口,使用接口引用来使用子类方法。我想应该是这样。毕老师应该是想叫你理解多态。
  42.                  System.out.println(a.test());
  43.          }
  44. }
复制代码
这两个代码比较起来看应该理解的更透彻。
回复 使用道具 举报
csatshell 发表于 2013-3-15 15:07
首先明确一点,你的编译失败是因为多态的问题。
1,static A get()//这是一个方法,方法被静态修饰,方法的 ...

:L加分都遇一起,这小子走运了,哈哈
回复 使用道具 举报
洪建超 发表于 2013-3-15 16:14
加分都遇一起,这小子走运了,哈哈

这个同步锁不好。。。。嘿嘿

1.jpg (16.86 KB, 下载次数: 8)

1.jpg
回复 使用道具 举报
csatshell 发表于 2013-3-15 16:36
这个同步锁不好。。。。嘿嘿

同步锁不好,但是对你来说没什么安全隐患,不是吗?好好加油吧
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马