求高人解答此代码!!!

逸花城 2016-07-31 04:47:34
interface A<T>
{
public String fun(T t);
};
class B implements A<B>
{
private String info;
public B(String info){
this.info = info;
}
public String fun(B b){
return this.info + b.info;
}
};
public class Demo
{
@SuppressWarnings("unchecked")
public static void main(String args[]){
A a1 = new B("Hello ");
A a2 = new B("World!!!");
System.out.println(a1.fun(a2));
}
};

正常执行,无任何问题,求高人解答!
...全文
775 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
HerveyHall 2016-08-03
  • 打赏
  • 举报
回复
引用 34 楼 zengqingmei 的回复:
为什么顶楼的代码中不用将a2强制转型
顶楼的代码里面A接口的fun()方法的形参是T类型的,而
A a2 = new B("World!!!");
这句并没有指定T的类型,所以T的实例默认为<? extends Object>类型,也就是说fun()方法可以传递任意一个Object类型的实参,那么
System.out.println(a1.fun(a2));
这句其实是fun()方法通过泛型将a2自动转换成了B类型。
百度百科里的一句话
泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,以提高代码的重用率。
逸花城 2016-08-02
  • 打赏
  • 举报
回复
引用 32 楼 hhv_01 的回复:
[quote=引用 31 楼 zengqingmei 的回复:] “a1在调用a1.fun(a2)时把a2自动强转为B类型”?为什么这里必须要加上“(B)”进行强转?
楼主A类里面的方法fun(B b)的形参是B类型,所以传入实参的时候要传入一个B的实例;而a2是A类型的实例,所以需要显式强制转换成B类型的,这个过程也就是下溯造型。 楼主
A a2 = new B();
这句其实是将B的实例上溯造型成了A,所以a2是A类型的。[/quote] 嗯,我知道,这个是作为辅助说明,关键是为什么顶楼的代码中不用将a2强制转型。
yesonghui 2016-08-02
  • 打赏
  • 举报
回复
遇上同样的问题了.
HerveyHall 2016-08-02
  • 打赏
  • 举报
回复
引用 31 楼 zengqingmei 的回复:
“a1在调用a1.fun(a2)时把a2自动强转为B类型”?为什么这里必须要加上“(B)”进行强转?
楼主A类里面的方法fun(B b)的形参是B类型,所以传入实参的时候要传入一个B的实例;而a2是A类型的实例,所以需要显式强制转换成B类型的,这个过程也就是下溯造型。 楼主
A a2 = new B();
这句其实是将B的实例上溯造型成了A,所以a2是A类型的。
NewMoons 2016-08-01
  • 打赏
  • 举报
回复
引用 18 楼 zengqingmei 的回复:
[quote=引用 17 楼 NewMoons 的回复:] 楼主其实还是对多态理解的不深刻,接口其实也是父类,只不过是一个没有实现的父类。 你定义的变量是类型A而不是B,而A允许定义时其参数类T不指定具体类型,所以在定义时没有指定类型的话,其fun是可以接收任何类型的类。 你的关键问题是:a1.fun(a2),在调用a1的fun时,其参数应该是B类型啊,没错,运行期必须是B类型,但其实本来就是B类型。 你把第21行的代码换成这句 System.out.println(a1.fun((B)a2));看看还能不能执行。 如果你还不理解,我只能**&%$#了。 至于泛型,其实就是解决了编译期保证代码健壮的问题,我个人对泛型一直是不太建议使用的,其语法太晦涩,极大的增加了代码可读性难度,当然,仅仅是个人理解,就像goto语句话题一样,慎用不是说不用。
完全没问题![/quote] 我晕,我的意思就是没问题啊,这正是多态的精华所在啊,如果你过不去这个坎,你就没有理解多态。
逸花城 2016-08-01
  • 打赏
  • 举报
回复
引用 5 楼 SQ_Bang 的回复:
这是泛型加接口实现的例子吧,楼主你是不能理解代码怎么执行吗?那我讲讲小弟我的理解:
执行第19行:变量a1是接口A类型,由于B类实现了A接口,所以可以转换为A接口类型(类似于extends子类转换为父类)。
第19行的new B("Hello ");执行了第8行的构造方法,并且把字符串赋值给变量info;也就是a1.info 的值为"Hello"
执行第20行:和19行差不多,a2.info的值为"World!!!" 。
执行第21行:由于B类实现了接口的fun(T t)方法,而且a1和a2都是A接口类型,a1在调用a1.fun(a2)时把a2自动强转为B类型,所以
return语句等同于 return a1.info + a2.info ; 也就是 return “Hello " + "World!!!" ;


“a1在调用a1.fun(a2)时把a2自动强转为B类型”?为什么这里必须要加上“(B)”进行强转?
逸花城 2016-08-01
  • 打赏
  • 举报
回复
引用 5 楼 SQ_Bang 的回复:
这是泛型加接口实现的例子吧,楼主你是不能理解代码怎么执行吗?那我讲讲小弟我的理解: 执行第19行:变量a1是接口A类型,由于B类实现了A接口,所以可以转换为A接口类型(类似于extends子类转换为父类)。 第19行的new B("Hello ");执行了第8行的构造方法,并且把字符串赋值给变量info;也就是a1.info 的值为"Hello" 执行第20行:和19行差不多,a2.info的值为"World!!!" 。 执行第21行:由于B类实现了接口的fun(T t)方法,而且a1和a2都是A接口类型,a1在调用a1.fun(a2)时把a2自动强转为B类型,所以 return语句等同于 return a1.info + a2.info ; 也就是 return “Hello " + "World!!!" ;
看了这么多回复只剩下一个疑问了:“a1在调用a1.fun(a2)时把a2自动强转为B类型”? 为什么会”把a2自动强转为B类型“?
逗泥丸的平方 2016-08-01
  • 打赏
  • 举报
回复
为什么要有问题.. A<T>只定义了fun的规范... 你也只是在用fun ,fun也没有违法这个规范,这不是很正常的吗.
JPF1024 2016-08-01
  • 打赏
  • 举报
回复



interface A<T>
{
    public String fun(T t);
};
class B implements A<B>
{
    private String info;
    public B(String info){
        this.info = info;
    }
    public String fun(B b){
        return this.info + b.info;
    }
};
public class HelloWorld
{
    @SuppressWarnings("unchecked")
    public static void main(String args[]){
        A a1 = new B("Hello ");
        A a2 = new B("World!!!");
        System.out.println(a1.fun(a2));
		System.out.println(a1 instanceof A);
		System.out.println(a1 instanceof B);
		System.out.println(a2 instanceof A);
		System.out.println(a2 instanceof B);
		System.out.println(a2==a1);
    }
};
输出: Hello World!!! true true true true false 为什么要转型? 就跟: Object str1 = new String(); Object str2 = new String(); 一样,为啥要转型? 可能没增加泛型,那就换个: List list1 = new ArrayList(); List list2 = new ArrayList(); 道理一样。
逸花城 2016-08-01
  • 打赏
  • 举报
回复
引用 27 楼 dcxy0 的回复:
如果你要比较,可以用==比较一下对象是否相等。。(虽然结果一定是false)... 另外,如果你想研究类似的例子,可以去看一下:List(Interface),ArrayList(Class),HashList(Class)之间的关系。
我觉得这个例子中应该是System.out.println(a1.fun((B)a2)),但为什么可以把(B)省略,向下转型是不会自动进行的啊。
JPF1024 2016-08-01
  • 打赏
  • 举报
回复
如果你要比较,可以用==比较一下对象是否相等。。(虽然结果一定是false)... 另外,如果你想研究类似的例子,可以去看一下:List(Interface),ArrayList(Class),HashList(Class)之间的关系。
NewMoons 2016-08-01
  • 打赏
  • 举报
回复
我已经无法用人类的语言和你沟通了,楼下继续。。。
逸花城 2016-08-01
  • 打赏
  • 举报
回复
引用 23 楼 NewMoons 的回复:
去掉泛型可以,但你向上转型就需要强制转换了:System.out.println(a1.fun((B)a2)); 这正是多态的特性加泛型解决的问题啊(我前面说了泛型的主要作用之一就是避免运行期的强制转换,把错误尽量控制在编译期,使程序更加健壮。) 楼主真正不理解的不仅仅是泛型,更主要的是多态不理解。 多态:向下是自动转换,向上则要强制转换。这个很好理解啊,子类的特性肯定比父类多,所以可自动转换。但反之。。。我实在懒得再解释了。
你说反了,向上是自动转型,向下则要强制转型,问题的关键不在于如何进行向上和向下转型,而是为什么加了泛型就可以不用“强制”进行向下转型?
NewMoons 2016-08-01
  • 打赏
  • 举报
回复
为了让代码看起来更通用,在没有泛型的时候,代码都是这么写:
package test2;

interface A
{
    public String fun(Object t);
};

class B implements A
{
    private String info;
    public B(String info){
        this.info = info;
    }
    public String fun(Object b){
        return this.info + ((B)b).info;
    }
};

public class Demo
{
    @SuppressWarnings("unchecked")
    public static void main(String args[]){
        A a1 = new B("Hello ");
        A a2 = new B("World!!!");
        System.out.println(a1.fun(a2));
    }
};
NewMoons 2016-08-01
  • 打赏
  • 举报
回复
去掉泛型可以,但你向上转型就需要强制转换了:System.out.println(a1.fun((B)a2)); 这正是多态的特性加泛型解决的问题啊(我前面说了泛型的主要作用之一就是避免运行期的强制转换,把错误尽量控制在编译期,使程序更加健壮。) 楼主真正不理解的不仅仅是泛型,更主要的是多态不理解。 多态:向下是自动转换,向上则要强制转换。这个很好理解啊,子类的特性肯定比父类多,所以可自动转换。但反之。。。我实在懒得再解释了。
逸花城 2016-08-01
  • 打赏
  • 举报
回复
引用 17 楼 NewMoons 的回复:
楼主其实还是对多态理解的不深刻,接口其实也是父类,只不过是一个没有实现的父类。
你定义的变量是类型A而不是B,而A允许定义时其参数类T不指定具体类型,所以在定义时没有指定类型的话,其fun是可以接收任何类型的类。
你的关键问题是:a1.fun(a2),在调用a1的fun时,其参数应该是B类型啊,没错,运行期必须是B类型,但其实本来就是B类型。
你把第21行的代码换成这句 System.out.println(a1.fun((B)a2));看看还能不能执行。
如果你还不理解,我只能**&%$#了。

至于泛型,其实就是解决了编译期保证代码健壮的问题,我个人对泛型一直是不太建议使用的,其语法太晦涩,极大的增加了代码可读性难度,当然,仅仅是个人理解,就像goto语句话题一样,慎用不是说不用。


完全没问题!
adfldk 2016-08-01
  • 打赏
  • 举报
回复
在想着要怎么和楼主解释 局限在代码可能楼主理解不了 要用生活中的例子才行
NewMoons 2016-08-01
  • 打赏
  • 举报
回复
楼主其实还是对多态理解的不深刻,接口其实也是父类,只不过是一个没有实现的父类。 你定义的变量是类型A而不是B,而A允许定义时其参数类T不指定具体类型,所以在定义时没有指定类型的话,其fun是可以接收任何类型的类。 你的关键问题是:a1.fun(a2),在调用a1的fun时,其参数应该是B类型啊,没错,运行期必须是B类型,但其实本来就是B类型。 你把第21行的代码换成这句 System.out.println(a1.fun((B)a2));看看还能不能执行。 如果你还不理解,我只能**&%$#了。 至于泛型,其实就是解决了编译期保证代码健壮的问题,我个人对泛型一直是不太建议使用的,其语法太晦涩,极大的增加了代码可读性难度,当然,仅仅是个人理解,就像goto语句话题一样,慎用不是说不用。
逸花城 2016-08-01
  • 打赏
  • 举报
回复
引用 20 楼 NewMoons 的回复:
[quote=引用 18 楼 zengqingmei 的回复:]
[quote=引用 17 楼 NewMoons 的回复:]
楼主其实还是对多态理解的不深刻,接口其实也是父类,只不过是一个没有实现的父类。
你定义的变量是类型A而不是B,而A允许定义时其参数类T不指定具体类型,所以在定义时没有指定类型的话,其fun是可以接收任何类型的类。
你的关键问题是:a1.fun(a2),在调用a1的fun时,其参数应该是B类型啊,没错,运行期必须是B类型,但其实本来就是B类型。
你把第21行的代码换成这句 System.out.println(a1.fun((B)a2));看看还能不能执行。
如果你还不理解,我只能**&%$#了。

至于泛型,其实就是解决了编译期保证代码健壮的问题,我个人对泛型一直是不太建议使用的,其语法太晦涩,极大的增加了代码可读性难度,当然,仅仅是个人理解,就像goto语句话题一样,慎用不是说不用。


完全没问题![/quote]

我晕,我的意思就是没问题啊,这正是多态的精华所在啊,如果你过不去这个坎,你就没有理解多态。[/quote]
为什么a2会自动向下转型?

为什么去掉泛型就不可以?
NewMoons 2016-07-31
  • 打赏
  • 举报
回复
楼主的疑点究竟在哪里?哪一行? 猜你的意思是觉得应该抛异常么?
加载更多回复(15)

62,614

社区成员

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

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