Java 接口和类之间的强制转换

Java 接口和类之间的强制转换,java,interface,Java,Interface,昨天我刚开始学习接口,并做了一些简单的例子,我注意到我在理解类和接口之间的转换时遇到了很多困难,所以我阅读了 然而,当我的书在底部给出一个小的评论问题时,我注意到我仍然没有完全理解,我买的书也没有解决办法。以下是问题(我给出的尝试和推理对某些人来说可能是错误的,所以任何帮助都是好的!) 假设类Sandwich实现了可食接口,那么 给出了变量声明 以下哪项转让声明是合法的 e=sub 因为夹心类实现了接口,,所以这没有问题。我们可以说e=sub没有问题有效 sub=e 由于我们试图将Sandwit

昨天我刚开始学习接口,并做了一些简单的例子,我注意到我在理解类和接口之间的转换时遇到了很多困难,所以我阅读了

然而,当我的书在底部给出一个小的评论问题时,我注意到我仍然没有完全理解,我买的书也没有解决办法。以下是问题(我给出的尝试和推理对某些人来说可能是错误的,所以任何帮助都是好的!)

假设类Sandwich实现了可食接口,那么 给出了变量声明

以下哪项转让声明是合法的

  • e=sub

    因为夹心类实现了接口
    ,所以这没有问题。我们可以说
    e=sub
    没有问题有效

  • sub=e

    由于我们试图将
    Sandwitch
    类中的对象
    sub
    更改为
    接口
    类型,因此不强制转换就无法执行此操作它不起作用

  • sub=(三明治)e

    有效!这解决了我们的老问题

  • sub=(三明治)谷物盒

    我不知道。。但是它应该工作吗?
    cerealBox
    是一个
    矩形
    ,因此使用
    (三明治)
    我们将其转换为
    ,它是
    三明治的一部分

  • e=cerealBox

    别这么想<代码>矩形
    未在
    可食
    界面中实现,因此它不应工作

  • e=(可食用)谷物盒

    现在应该开始工作了。(可食用)就像它实现了接口一样

  • e=(矩形)小脑盒

    不确定。我认为这行不通,我的意思是,
    cerealBox
    是矩形的,为什么我们又把它变成了一个
    Rectangle

  • e=(矩形)空

    一点也不确定

  • #4、6、7和8是你需要帮助的。他们都是关于铸造的。只有当源类型和目标类型通过继承可能存在关系时,强制转换才合法。仅当右侧具有与左侧相同的类型或子类型时,变量赋值才合法

    #4
    sub=(三明治)谷物盒
    铸造后两侧均为
    Sandwich
    型,但
    (Sandwich)cerealBox
    为非法铸造这将不起作用。这是非法强制转换的原因是强制转换不能在不同继承分支上的类之间发生。在任何情况下,
    矩形
    都不能是
    三明治
    ,因此这是编译器错误

    #6
    e=(食用)谷物盒
    这与#4不同,因为它是一个接口。它是合法的,但可能引发运行时错误。请参阅以获得一个好的解释。在编译时,无法知道
    cerealBox
    是否实际上可能是
    Rectangle
    的一个子类型,即
    可食用的
    这将起作用。如果
    矩形
    最终的
    ,这将不起作用

    #7
    e=(矩形)小脑盒
    将变量强制转换为相同类型是合法的。将
    矩形
    分配给
    类型的变量是不合法的<代码>矩形
    不实现
    可食用
    这不起作用。

    #8
    e=(矩形)空
    
    null
    强制转换为任何类型都是合法的这将不起作用,因为
    矩形
    没有实现
    可食用

    您需要了解的是每个对象都有一个具体的类。它“是”该类的一个实例,它“是”该类继承的每个类的一个实例,所有这些都同时发生。不仅如此,它“是”每个接口的一个实例,这些类中的任何一个都同时继承

    因此,假设:

     class Animal
     class Mammal extends Animal implements Suckler
     class Dog extends Mammal implements Woofer
    
    。。。如果我创建了一个
    新狗()
    ,那么这个对象“就是一个
    对象
    (因为所有对象都继承了
    对象
    ),
    动物
    哺乳动物
    吸奶者
    低音扬声器
    所有这些都是同时发生的

    但是,变量与对象不是一回事。变量指向对象,并且变量具有类型。类型必须与指定的对象兼容,但仅此而已

    因此:

    工作正常,但从那一刻起,编译器通过
    s
    变量了解对象的所有信息都是它是一个
    吸吮器。它不知道它是一只狗;它不知道它是哺乳动物。因此,我们不能这样做:

    Dog d = s;
    
    。。。因为编译器不能保证
    s
    指向的变量是

    变量的类型永远无法更改
    s
    在其整个生命周期内都具有类型
    吸盘
    ,无论发生什么情况。我们可以将
    绵羊
    分配给
    s
    ,但除了属于
    哺乳者
    定义的操作之外,我们无法对这些对象执行任何操作


    我将假设各种类和接口的定义如下:

     public interface Edible {
         ...
     }
    
     public class Sandwich implements Edible {
         ...
     }
    
     public class Rectangle {  // note, does not implement or extend anything
                               // (except Object)
         ...
     }
    
    public class Flapjack extends Rectangle implements Edible { ... }
    
    因此:

    这很好
    sub
    是一种
    三明治
    ,而
    三明治
    是一种
    可食用的


    这不会编译
    e
    是一个
    可食用的
    ,但是可以有任意数量的类实现
    可食用的
    ,以及
    三明治
    sub
    必须是一个
    Sandwich
    ,因为编译器不能确定
    e
    是一个
     public interface Edible {
         ...
     }
    
     public class Sandwich implements Edible {
         ...
     }
    
     public class Rectangle {  // note, does not implement or extend anything
                               // (except Object)
         ...
     }
    
    Sandwich sub = new Sandwich();
    Edible e = null;
    e = sub;
    
    Sandwich sub = new Sandwich();
    Edible e = null;
    sub = e;
    
    Sandwich sub = new Sandwich();
    Edible e = null;
    sub = (Sandwich) e;
    
    Sandwich sub = new Sandwich();
    Rectangle cerealBox = new Rectangle(5, 10, 20, 30); 
    sub = (Sandwich) cerealBox;
    
    Rectangle cerealBox = new Rectangle(5, 10, 20, 30); 
    Edible e = null;
    e = cerealBox;
    
    Rectangle cerealBox = new Rectangle(5, 10, 20, 30); 
    Edible e = null;
    e = (Edible) cerealBox;
    
    public class Flapjack extends Rectangle implements Edible { ... }
    
    Rectangle cerealBox = new Rectangle(5, 10, 20, 30); 
    Edible e = null;
    e = (Rectangle) cerealBox;
    
    Edible e = null;
    e = (Rectangle) null;