instanceof,子类和强制转换

时间:2013-10-13 16:31:41

标签: java

如果我有一个班级myClass1和第二班级myClass1Extended是第一堂课的扩展,我有这个源代码:

myClass1 c1 = something();   // line 1
myClass1Extended c1ex = somethingElse();   // line 2
if (c1ex instanceof myClass1) {    // line 3
    (myClass1)c1ex.doSomething();    // line 4
}

我有几个问题:

    第3行中的
  1. ,运算符instanceof会返回true吗?
  2. 在第4行,假设第一个答案是肯定的,如果在myClass1Extended中没有覆盖doSomething()会怎样?
  3. 如果doSomething()被覆盖了会发生什么呢?
  4. 第4行中的
  5. 是(myClass1)必需吗?
  6. 非常感谢

2 个答案:

答案 0 :(得分:3)

为什么不试试代码?

  1. 它会调用父类
  2. 中的那个
  3. 它将调用子类中的那个
  4. 没有
  5. 假设:

    class Parent
    {
        public void foo() 
        {
            System.out.ptintln("parent::foo");
            bar();
        }
    
        public void bar()
        {
            System.out.println("parent::bar");
        }
    }
    
    class Child
        extends Parent
    {
        public void foo() 
        {
            super.foo();
            System.out.ptintln("child::foo");
        }
    }
    

    您可以在使用Parent类的任何地方使用Child类,因为所有Child都是Parent类型。

    当编译器查看此代码时:

    Parent p = new Child();
    

    它验证Child是否扩展或实现了Parent。

    当编译器查看此代码时:

    p.foo();
    

    它验证p被声明为Parent的类型是foo方法。

    在执行p.foo()行的运行时,虚拟机会查看p实际指向的类型Child,然后在那里查找foo方法。假设在foo中找到了Child方法,它会运行它,否则会查看Parent类。

    foo方法调用bar时,在Parent类中,编译器再次查看以确保Parent类具有bar方法。在运行时,VM再次查看Child类的bar类,因为它不会调用Parent中的那个。

    如果Parent中不存在这些方法,那么它们必须存在于Parent的父类中,一直存在java.lang.Object

答案 1 :(得分:1)

要回答您的问题,请在此处举例:

package test;

public class Parent
{
    public void printFoo()
    {
        System.out.println("foo");
    }

    public void printBar()
    {
        System.out.println("bar");
    }
}

package test;

public class Child extends Parent
{
    @Override
    public void printFoo()
    {
        System.out.println("myFoo");
    }
}

package test;

public class Main
{
    public static void main(String ... args)
    {
        Parent test = new Child();
        Parent test2 = new Parent();

        print(test);
        print(test2);
    }

    public static void print(Parent parent)
    {
        if (parent instanceof Parent)
        {
            System.out.println(parent.getClass().getName()+" is Parent");
            parent.printFoo();
            parent.printBar();
        }
    }
}

如您所见,Child从Parent继承并覆盖printFoo()方法。在打印这些父对象时,您将获得以下输出:

test.Child is Parent
myFoo
bar
test.Parent is Parent
foo
bar

所以回答你的问题:
1)是的 2)它将调用父类的方法
3)它将调用overriden方法 - 如果此方法包含超级调用,则父级方法也将执行
4)否 - 如果你指定f.e. Parent o = new Child()并在Child中实现一个方法,该方法在Parent中不存在,并且您想要调用子对象的方法,您必须将其强制转换回Child ((Child)o).invokeYourMethod()