Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关于Java向上/向下转换和继承优先级的问题_Java_Class_Inheritance_Binding_Casting - Fatal编程技术网

关于Java向上/向下转换和继承优先级的问题

关于Java向上/向下转换和继承优先级的问题,java,class,inheritance,binding,casting,Java,Class,Inheritance,Binding,Casting,在这些情况下,很难理解上行/下行以及静态绑定和动态绑定的复杂性。请考虑以下类和接口示例: public class Marsupial { private String name; Marsupial(String name) { this.name = name; } void eats() { System.out.println("Eats #1");

在这些情况下,很难理解上行/下行以及静态绑定和动态绑定的复杂性。请考虑以下类和接口示例:

 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);   }    
        }
现在,当我创建一个driver类来使用所有的类时,我注意到一些奇怪的事情发生了,我不知道为什么

比如说,

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());
               }    
}
事实证明这是错误的。他们不是同一类人。那么这里到底发生了什么。左边是有袋动物,右边是其他动物。那么,当我们调用方法时,正确的是唯一重要的事情吗?当编译器运行并查看方法时,检查equals运算符的右侧,并说ok这是某某类,因此在确定要使用的类时,请使用在右侧定义的类的方法

而且

如果在我写的主方法中:

Marsupial m = new Koala("jack");
m.eats();
这张打印出来的是2。这是因为无尾熊没有eats方法,只是返回到链的上一级,所以下一级将是Herbivor,因为它有一个eats()方法,这就是被调用的方法,这是想法吗

主方法中的另一个示例:

Herbivore h = new Koala("June");
((Marsupial)h).eats();
这里让我感到不舒服的是,我们可以使用抽象类作为对实际对象的引用,就像这里Herbivor是一个抽象类,因此不能实例化,但可以将它分配给实例化对象的类。 但最让我困惑的是,现在我们在考拉类中,我们调用eats()方法,但随后我们将变量向上转换为有袋动物。因此,这会自动将我们放入有袋动物类,因此无论何时我们调用一个方法,即使它在其他类中,有袋动物类方法也是被调用的方法,因为我们将它键入有袋动物,因此它吃#1

另一个令人困惑的方面是,如果我们主要这样做:

Australian a = new Koala("Khloe");
a.chews(true);
我们看到一个接口被分配给一个子类实例化。这让我很困惑,用a.chews来称呼什么(真的)。既然它被定义为考拉对象,那么我们就在考拉类中,必须使用考拉方法(如果它们存在的话),如果没有的话,我们就上一层去检查它们是否有这个方法等等。但是这里的方法是无效的。那么,只有在澳大利亚有一个原型方法并且考拉定义了它的情况下,它才有效吗?那就行了?这就是将接口设置为其子类对象背后的想法吗?尽管无尾熊有这种方法,因为澳大利亚人没有,但它不会起作用

如果我们主要有代码,比如:

Herbivore h = new Koala("Stacy");
h.chews(true);
这将打印出“Yum-Yum”,只是因为Herbivore有一个未定义的原型方法,而考拉定义了它。但是,如果《食草动物》没有这种原型,这种方法是行不通的

我的最后一个问题是,如果这是在主系统中运行的:

Herbivore h = new Koala("Kali");
h.chews(4);
这是行不通的,因为尽管考拉在那里有这个方法,但它并没有在《食草动物》中定义,所以它是无效的

请帮忙,你能提供的任何更正或信息都会很有帮助


谢谢

所有问题的答案只有一个:尽可能 JVM担心它不会 关心一下这个变量 类型,但仅限于实际类型( 一个与
new
关键字一起使用) . 变量类型用于 编译器仅用于确保类型 安全早在发展中
可能。

我记不清这里有多少问题;但它们都是有价值的,你们为什么不试试看,看看它们的多样性呢。这比编写这个问题花费的时间要少。关于这一点的传统观点是,变量具有声明的类型,对象具有运行时类型。声明的类型告诉您允许对实例调用哪些方法。如果子类型具有该方法,但声明的类型没有,则不能调用它。运行时类型确定实例方法的实际执行版本。如果存在,则运行时类型中的覆盖将获胜。