类Student实现接口Singer;
类Teacher实现接口Singer,Painer;
Singer s1=new Teacher;
Painer p1=(Painer )s1;();//就是这句不明白 我个人认为,强制转换的条件是:父类转子类。可这个例子中s1实现的是p1的接口,应该不用强制转换才对。我不解,望帮助,谢谢

解决方案 »

  1.   

    我个人觉得应该是Painer p1 = (Teacher)s1;这样才好,因为强制转换是向下转的。你这里的只是两边类型匹配而尔。
      

  2.   

    就算你那个Teacher没有实现Painer接口Painer p1=(Painer )s1;这句一样编译成功的
      

  3.   

    Painer p1=(Painer )s1  我都不懂这句有什么用
      

  4.   

    类Student实现接口Singer; 
    类Teacher实现接口Singer,Painer; 
    1.先讲点知识
    s1和p1都是上转型对象,上转型的对象只是隐藏了属性和方法而已,需要强制转换才可以调用里面的方法
    2.Singer s1=new Teacher;//s1中有Singer,Painer中的方法和属性,只是不能直接调用。
    3.Painer p1=(Painer )s1;();//p1强制转换之后,就可以获得Painer里面的属性和方法
    就是这个原因才需要强制转换的。也就是说:其实s1的属性和方法多于p1,所以需要强制转换。
      

  5.   

    关于父类-子类之间相互造型的问题:是java(以及其他OO)多态的重要方式之一(另一种是override和overloading)这也是在工厂模式出来之前,比较流行的“面向接口编程”的“设计模式”父类变量可以无条件指向任意子类的对象而无需显式造型(显式造型不报错)
    Object o = new String();子类变量可以而且必须经过强制造型到父类,但可能抛出ClassCastException
    Object o = new String();
    String s = (String)o; //okObject o1 = new Integer();
    String s2 = (String)o1;//ClassCastException
    关于“面向接口编程”的例子,在java.sql包比比皆是,比如Driver,Connection等等。
    之所以可以用Class.forName("....");
    DriverManager.getConnection()...
    这样获取数据库连接,就是因为数据库厂商提供的驱动实现了上述两个接口
      

  6.   

    Singer s1=new Teacher;
    s1编译时的类型是Singer,s1运行时的类型是Teacher
    Painer p1=(Painer )s1;
    p1编译时的类型是Painer,p1和s1在编译的时候不认识。要强转一下
      

  7.   

    s1的类型是Singer Teacher只是隐形的类型(具有Teacher的所有功能 也就有Painer里的功能)
    但是类型Singer和Painer不同  也就是p1不能直接引用s1
      

  8.   

    Singer s1=new Teacher(); 
    执行完这条语句后,s1这个句柄,编译器只会认为它是 Singer类型的对象,尽管它实际上是 Teacher 对象
    所有s1 不对当 Painer 使用,要让它可用,只能把 s1再次转为 Teacher,或 painer
    即 Teacher t=(Teacher)s1;或 Painer p=(Painer)s1;
    这样编译器才能使用对这个对象使用 Painer接口中的方法;
    当我,即使s1这个对象不是 Teacher对象,而是Student对象
    这样转换,编译的时候也不会报错,只是在运行时报错;