关于向下转型和多态性

时间:2017-03-13 21:29:05

标签: java

为什么我要写这样的

animal a = new cat();
cat b = (cat)a;
b.makesound();
a.makesound();

但不喜欢这个

animal a = new cat();
animal b = new cat();
a.makesound();
b.makesound();

他们提供相同的输出

这是整个代码。

public class DownCasting 
{
    public static void main(String args[])
    {
        animal a = new cat();
        cat b = (cat)a;
        b.makesound();
        a.makesound();
    }
}


class animal
{
    public void makesound()
    {
        System.out.println('w');
    }
}


class cat extends animal
{
    public void makesound()
    {
        System.out.println("meow");
    }
}

如此向下倾斜只是给对象第二个名字?还是有其他用途?

3 个答案:

答案 0 :(得分:0)

在第二个变体中,您创建了两只猫。

首先,您将其他名称b分配给已有的动物a

  

如此向下倾斜只是给对象第二个名字?还是有其他用途?

你可能想要一份动物名单,f.ex。狗:

class dog extends animal
{
    public void makesound()
    {
        System.out.println("woof");
    }
}

可以与猫组合在同一个列表中。

答案 1 :(得分:0)

强制转换是强制使变量表现为另一种变量的过程。如果一个类与另一个类或接口共享一个IS-A或继承关系,那么它们的变量可以转换为彼此的类型。

public class DownCasting 
{
    public static void main(String args[])
    {
        animal a = new cat();
        cat b = (cat)a;
        b.makesound();
        a.makesound();
    }
}


class animal
{
    public void makesound()
    {
        System.out.println('w');
    }
}


class cat extends animal
{
    public void makesound()
    {
        System.out.println("meow");
    }
}

在行animal a = new cat();中,您使用Animal类型的变量来引用Cat类型的对象,a.makesound();将打印“喵”,因为有了继承,实例方法在运行时绑定。

但是,如果您尝试执行cat b = a;(不进行转换),Java编译器将尝试使用类型为Cat的变量来引用类型为Animal的对象,这是不可能(你不能使用子类的变量来引用(执行)来自超类的方法),所以有必要强制转换变量以向java编译器指示它可以确定尽管{{1} }是a类型的变量,实际上是Animal

让我举个例子来说明这一点:

我的两个课程有一些修改:

Cat

这两个类现在都有一个其他类没有的方法。

现在让我们使用它:

class animal
{
    public void makesound()
    {
        System.out.println('w');
    }

    void sleep(){
        System.out.println("ZZZ");
    }
}


class cat extends animal
{
    public void makesound()
    {
        System.out.println("meow");
    }
    void play(){
        System.out.println("I´m playing");
    }
}

如果我public class DownCasting { public static void main(String args[]) { animal a = new cat(); } } 它会给我一个编译错误,因为Java在Animal类中搜索方法a.play();并且找不到它...为什么java会这样做?正如我已经说过的那样:“继承,实例方法在运行时绑定”,所以如果我想调用该方法,我必须转换play()变量...... {{1} }

但如果你试图以相反的方式做到这一点会发生什么?

a

所以,我可以这样投它以便编译:

((Cat)a).play();

但是,在运行时会抛出Cat c = new Animal(); //This line will never compile... 为什么?,因为你不能使用子类的变量来引用(执行)超类中的方法。 / p> 总之,请记住,对象引用变量的类型和引用的对象的类型可能不同。

但是这些规则有不同的规则。

对于这个主题,我将特别推荐你OCA Java SE 7 Programmer I Certification Guide: Prepare for the 1ZO-803 exam第6章。

答案 2 :(得分:-1)

  

为什么我必须像这样写

要回答这个问题,您首先需要知道什么可以发出声音? 猫还是动物?

你这样做:

animal a = new cat();
a.makesound();

当方法makeound在动物中声明时

如果没有那么你需要施放