关于Java upcasting / downcasting和继承pripority的问题

时间:2017-02-27 03:51:25

标签: java class inheritance binding casting

在这些情况下无法理解上传/下传,静态绑定和动态出价的复杂性。请考虑以下类和接口示例:

 public class Marsupial {   private String name;
         Marsupial(String name) {    
         this.name = name;    
         }
         void eats() {   
         System.out.println("Eats #1");   
         }
         String getName(){    return name;    
         }
         }


    abstract class Herbivore extends Marsupial {
         Herbivore(String name) {
         super(name);    
         }
         void eats() {
         System.out.println("Eats #2");    
         }
         abstract void chews(boolean b); 
         }


    interface Australian {   
    public void greets(Koala k); 
    }


    public class Koala extends Herbivore implements Australian {
         Koala(String name) {
         super(name);   
         }
         public void greets(Koala k) {
         System.out.println("G'day mate!");
         System.out.println(getName() + " " + k.getName() );   
         }
         void chews(boolean b) {

        System.out.println("Yum yum!");   
         }
         void chews(int i) {    System.out.println("Delicious!");    
         }
         void likes(Koala k) {
        greets(k);
        k.greets(this);   }    
        }

现在,当我创建一个驱动程序类来使用所有类时,我注意到发生了一些奇怪的事情,我不知道为什么。

例如,

public class Driver {   
    public static void main(String[] args) {
    Marsupial m = new Marsupial("Kate");
    Marsupial m2 = new Koala("Kim");
    System.out.println(m.getClass() == m2.getClass());
               }    
}

事实证明这是错误的。他们不是同一个班级。那么这里到底发生了什么。我们左边是Marsupial,右边是其他东西。那么,当我们调用方法时,唯一重要的事情就是这样吗?当编译器运行并查看方法时,检查equals运算符的右侧并说确定这是这样的类,因此在确定要使用的类时,请使用右侧定义的类的方法。 p>

此外,

如果在我写的主要方法内:

Marsupial m = new Koala("jack");
m.eats();

打印出Eats#2。现在是因为考拉因为没有吃法只是回到链的一个级别,所以下一级将是草食动物,因为它有一个被调用的eats()方法,那就是那个想法?

主要方法中的另一个例子:

Herbivore h = new Koala("June");
((Marsupial)h).eats();

这里抛出的东西是我们可以使用抽象类作为对实际对象的引用,就像这里Herbivore是一个抽象类因此不能实例化,但它可以被分配给一个实例化对象的类。 但最让我困惑的是,现在我们在Koala类中,我们调用eats()方法,然后我们将变量UPCAST​​到Marsupial。那么这会自动将我们放入Marsupial类中,因此我们调用方法时,即使它在其他类中,Marsupial类方法也是被调用的方法,因为我们将其类型化为Marsupial,因此它的Eats#1。

另一个令人困惑的地方是,如果我们在main中这样做:

Australian a = new Koala("Khloe");
a.chews(true);

看到将接口分配给子类实例化是错误的。它让我感到困惑的是用a.chews调用什么(true)。因此,因为它被定义为Koala对象,所以我们在Koala类中,如果它们存在则必须使用Koala方法,如果不存在,我们会去一级检查它们是否有这种方法等等等等第四。但这里的方法无效。那么只有当澳大利亚人在那里有原型方法并且考拉定义它时它才有效吗?那会有用吗?这是将接口设置为其子类对象的想法吗?虽然考拉有这种方法,因为澳大利亚没有这种方法,但它不起作用。

如果我们在main中有代码:

Herbivore h = new Koala("Stacy");
h.chews(true);

这将打印出来" Yum yum"只因为Herbivore有原型未定义的方法而Koala定义了它。但是,如果草食动物没有那个原型方法是不可行的。

我的最后一个问题是,如果这是在main中运行的话:

Herbivore h = new Koala("Kali");
h.chews(4);

这不会起作用,因为尽管考拉在那里有这种方法,但它没有在草食动物中定义,所以它无效。

请提供帮助,您提供的任何更正或信息都会非常有用。

谢谢

1 个答案:

答案 0 :(得分:0)

所有人的答案都是:至于 JVM担心它不会 关心变量 类型,但只有实际类型( 一个与new关键字一起使用的) 。变量类型适用于 编译器仅用于确保类型 安全在发展初期 可能的。