使用instanceof时为什么子类和超类都是真的?

时间:2017-12-09 13:05:57

标签: java interface

很抱歉我在发帖时遇到了错误。在这种情况下,实现I的类应该是B而不是A.在这里,我发现令人困惑的地方。 此外,如果C类实现I而不是A或B,结果仍然相同。

got 'send from sock2' from ('127.0.0.1', 44596)
got 'send from sock1' from ('127.0.0.1', 9999)

为什么在使用interface I{} public class A{ A() { System.out.print("A: " + (this instanceof I) + " "); } public static void main(String[] args) { new C(); } } class B extends A implements I { B() { System.out.print("B: " + (this instanceof I) + " "); } } class C extends B { C() { System.out.print("C: " + (this instanceof I) + " "); } } 子类超类都是true

此代码的结果是:

instanceof

2 个答案:

答案 0 :(得分:4)

instanceof运算符检查给定对象是否为给定类的 sublcass (不一定是 true subclass )。这通常意味着您可以对象强制转换为该类(将视图缩小到该类)。

例如,如果我们有ArrayList,我们可以将其投放到List,如果我们检查instanceof trueArrayList也会返回List {1}}。所以在你的例子当然可以做到

new C() instanceof B // true
new B() instanceof A // true

但是,这些类还会从父母那里继承这样的属性。因此,类C当然是也是 A的子类,因为它是B的子类,BA的子类},所以我们得到

new C() instanceof A // true

同样适用于接口,我们得到

new A() instanceof I // true

继承

new B() instanceof I // true
new C() instanceof I // true

实际例子

看一下以下示例

public interface CanBark { }

public class Dog implements CanBark { }

public class Pug extends Dog { }

当然PugDog,而DogCanBarkPug也是CanBark,我们得到< / p>

new Pug() instanceof Dog     // true
new Dog() instanceof CanBark // true
new Pug() instanceof CanBark // true

instanceof

的详情

Java语言规范§15.20.2)将instanceof运算符的行为定义为

  

在运行时,如果 RelationalExpression 的值 instanceof,则true运算符的结果为null并且引用可以cast§15.16)到 ReferenceType ,而不会引发ClassCastException。否则结果为false

cast§15.16)的行为与

相似
  

[...]或在运行时检查参考值是指 兼容的对象指定引用类型

因此,投射指的是(§5.5)中指定的投射规则。您的具体案例在(§5.5.1)中定义为

  

如果T(目标)是界面,请输入:

  如果S(来源)不是最终类(§8.1.1),那么,如果存在X的超级T,则超级类型YSXY 可证明不同的参数化类型,以及X删除Y 相同,发生编译时错误

  其他,演员在编译时始终合法(因为即使S未实现T,也是S的子类威力)。

答案 1 :(得分:1)

这是面向对象编程的基础。让我举一个例子,它可以帮助你理解为什么子类获得父类实现的接口的行为。如果这有帮助,请告诉我。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

interface Flyable {
    /* Guys, Don't worry about what kind of flyable object you are talking to. 
     * just call me if you want to request someone to fly. */
    public void fly();

}

/*
 * Bird is abstract since there is nothing called 'Bird' existing in the world.
 * It should be either a Crow, Pegion, Sparrow and so on.
 */

abstract class Bird implements Flyable {

    public void fly() {
    /*  All birds follow same sequence of actions to fly.
     This method contains set of instructions to fly. */
    }

    // call this method to know where the bird was born
    public abstract String getCountry();
}


class Sparrow extends Bird {

    private String country;

    // I am responsible to give birth to a new sparrow.
    Sparrow(String beakColor, int weight, String bodyColor, String countryToLive) {
        this.country = countryToLive;

        // code to give birth to a new sparrow.
    }

    // Call me to know where i'm born
    public String getCountry() {
        return this.country;
    }


}

class Helicopter implements Flyable {

    private Date manufacturDate;
    private int engineCapacity;

    Helicopter() {
        /* sequence of instruction on how to assemble a new helicopter with default specifications */
    }

    @Override
    public void fly() {
        /* sequence of instruction on how helicopter should fly
         * Of course it will be different from how birds fly
         *  */

    }

    public Date getManufacturDate() {
        return this.manufacturDate;
    }

    public int getEngineCapacity() {
        return this.engineCapacity;
    }

}


class RandomSkyObjectsHandler {

    public static List<Flyable> getFewFlyableObjectsOfAnyType() {
        List<Flyable> randomList = new ArrayList<Flyable>();
        Sparrow sp1 = new Sparrow("black", 50, "brown", "India");
        Helicopter h1 = new Helicopter();
        Helicopter h2 = new Helicopter();
        Sparrow sp2 =  new Sparrow("Brown", 60, "white", "Kenya");
        Helicopter h3 = new Helicopter();
        Sparrow sp3 = new Sparrow("white", 70, "black", "USA");

        Flyable[] f = {sp1, sp2, h1, sp3, h2, h3};
        randomList = Arrays.asList(f);
        return randomList;


    }
}


public class TestProgramExecutor {
    public static void main(String... commandLineArguments) {

        List<Flyable> mixOfFlyingStuff = RandomSkyObjectsHandler.getFewFlyableObjectsOfAnyType();

        /* here is the beauty of OOPS. I don't need the knowledge of whether i'm telling a helicopter to fly or a sparrow to fly.
         * I'm just pretty sure that I'm talking to a flyable object and it understand if i say fly();
         * */

        for(Flyable f: mixOfFlyingStuff) {

            f.fly();
        }
    }
}