Java 链式继承情况下的输出

Java 链式继承情况下的输出,java,inheritance,casting,Java,Inheritance,Casting,有人能解释输出背后的逻辑吗?您没有将字节传递给您的吸血鬼实例;您正在通过循环传递一个int。因为Monster接受int,所以它被称为 class Monster { boolean frighten(int x) { System.out.println("Monster"); return true; } } class Vampire extends Monster { boolean frighten(byte x) {

有人能解释输出背后的逻辑吗?

您没有将
字节
传递给您的
吸血鬼
实例;您正在通过循环传递一个
int
。因为
Monster
接受
int
,所以它被称为

class Monster {
    boolean frighten(int x) {
        System.out.println("Monster");
        return true;
    }
}

class Vampire extends Monster {
    boolean frighten(byte x) {
        System.out.println("Vampire");
        return true;
    }
}

class Dragon extends Monster {
    boolean frighten(int x) {
        System.out.println("Dragon");
        return true;
    }
}


class Sample {
    public static void main(String s[]) {
        Monster[] inst = new Monster[3];
        inst[0] = new Monster();
        inst[1] = new Vampire();
        inst[2] = new Dragon();

        for (int i = 0; i < 3; i++) {
            inst[i].frighten(i);
        }
    }
}
实际上,您正在重载您的方法,而不是重写它-您有一个具有相同名称和两个相同签名的方法

class Monster {
    boolean frighten(int x) {
        System.out.println("Monster");
        return true;
    }
}

class Vampire extends Monster {
    boolean frighten(byte x) {
        System.out.println("Vampire");
        return true;
    }
}

class Dragon extends Monster {
    boolean frighten(int x) {
        System.out.println("Dragon");
        return true;
    }
}


class Sample {
    public static void main(String s[]) {
        Monster[] inst = new Monster[3];
        inst[0] = new Monster();
        inst[1] = new Vampire();
        inst[2] = new Dragon();

        for (int i = 0; i < 3; i++) {
            inst[i].frighten(i);
        }
    }
}
重写方法时确实应该使用同构类型,这样就不会遇到类似的问题。有效:在
吸血鬼
中更改
恐吓
的签名,以接受
int
而不是
字节

class Monster {
    boolean frighten(int x) {
        System.out.println("Monster");
        return true;
    }
}

class Vampire extends Monster {
    boolean frighten(byte x) {
        System.out.println("Vampire");
        return true;
    }
}

class Dragon extends Monster {
    boolean frighten(int x) {
        System.out.println("Dragon");
        return true;
    }
}


class Sample {
    public static void main(String s[]) {
        Monster[] inst = new Monster[3];
        inst[0] = new Monster();
        inst[1] = new Vampire();
        inst[2] = new Dragon();

        for (int i = 0; i < 3; i++) {
            inst[i].frighten(i);
        }
    }
}
@Override
注释您的方法将让编译器帮助选择类似的内容

class Monster {
    boolean frighten(int x) {
        System.out.println("Monster");
        return true;
    }
}

class Vampire extends Monster {
    boolean frighten(byte x) {
        System.out.println("Vampire");
        return true;
    }
}

class Dragon extends Monster {
    boolean frighten(int x) {
        System.out.println("Dragon");
        return true;
    }
}


class Sample {
    public static void main(String s[]) {
        Monster[] inst = new Monster[3];
        inst[0] = new Monster();
        inst[1] = new Vampire();
        inst[2] = new Dragon();

        for (int i = 0; i < 3; i++) {
            inst[i].frighten(i);
        }
    }
}
Monster                           
Monster                                 
Monster                                   

如果您的目的是覆盖,那么可以使用注释。然后编译器将帮助您发现此类错误。例如,编译器会发现这里有一个错误

class Monster {
    boolean frighten(int x) {
        System.out.println("Monster");
        return true;
    }
}

class Vampire extends Monster {
    boolean frighten(byte x) {
        System.out.println("Vampire");
        return true;
    }
}

class Dragon extends Monster {
    boolean frighten(int x) {
        System.out.println("Dragon");
        return true;
    }
}


class Sample {
    public static void main(String s[]) {
        Monster[] inst = new Monster[3];
        inst[0] = new Monster();
        inst[1] = new Vampire();
        inst[2] = new Dragon();

        for (int i = 0; i < 3; i++) {
            inst[i].frighten(i);
        }
    }
}
// Would cause a compilation error since the method isn't overridden
@Override
public boolean frighten(byte x) {
    return true;
}
当你写作时

class Monster {
    boolean frighten(int x) {
        System.out.println("Monster");
        return true;
    }
}

class Vampire extends Monster {
    boolean frighten(byte x) {
        System.out.println("Vampire");
        return true;
    }
}

class Dragon extends Monster {
    boolean frighten(int x) {
        System.out.println("Dragon");
        return true;
    }
}


class Sample {
    public static void main(String s[]) {
        Monster[] inst = new Monster[3];
        inst[0] = new Monster();
        inst[1] = new Vampire();
        inst[2] = new Dragon();

        for (int i = 0; i < 3; i++) {
            inst[i].frighten(i);
        }
    }
}
 class Vampire extends Monster
    {
      @Override 
      boolean frighten(byte x)
      {
       System.out.println("Vampire");
       return true;
      }
     }
由于
inst[i]
属于
Monster
类型,编译器必须在
Monster
类上找到一个与参数匹配的
bride
方法-在这里的实际代码中,它是
bride(int)

class Monster {
    boolean frighten(int x) {
        System.out.println("Monster");
        return true;
    }
}

class Vampire extends Monster {
    boolean frighten(byte x) {
        System.out.println("Vampire");
        return true;
    }
}

class Dragon extends Monster {
    boolean frighten(int x) {
        System.out.println("Dragon");
        return true;
    }
}


class Sample {
    public static void main(String s[]) {
        Monster[] inst = new Monster[3];
        inst[0] = new Monster();
        inst[1] = new Vampire();
        inst[2] = new Dragon();

        for (int i = 0; i < 3; i++) {
            inst[i].frighten(i);
        }
    }
}
它在您传递给它的
Monster
的所有实例上调用此方法-无论运行时类是什么,方法都是在编译时选择的

class Monster {
    boolean frighten(int x) {
        System.out.println("Monster");
        return true;
    }
}

class Vampire extends Monster {
    boolean frighten(byte x) {
        System.out.println("Vampire");
        return true;
    }
}

class Dragon extends Monster {
    boolean frighten(int x) {
        System.out.println("Dragon");
        return true;
    }
}


class Sample {
    public static void main(String s[]) {
        Monster[] inst = new Monster[3];
        inst[0] = new Monster();
        inst[1] = new Vampire();
        inst[2] = new Dragon();

        for (int i = 0; i < 3; i++) {
            inst[i].frighten(i);
        }
    }
}
这意味着永远不会调用
Vampire.bride(byte)
方法-它是一个重载,而不是一个覆盖,因为签名
bride(int)
bride(byte)
不匹配

class Monster {
    boolean frighten(int x) {
        System.out.println("Monster");
        return true;
    }
}

class Vampire extends Monster {
    boolean frighten(byte x) {
        System.out.println("Vampire");
        return true;
    }
}

class Dragon extends Monster {
    boolean frighten(int x) {
        System.out.println("Dragon");
        return true;
    }
}


class Sample {
    public static void main(String s[]) {
        Monster[] inst = new Monster[3];
        inst[0] = new Monster();
        inst[1] = new Vampire();
        inst[2] = new Dragon();

        for (int i = 0; i < 3; i++) {
            inst[i].frighten(i);
        }
    }
}
如果在
Monster
上将
bride
方法的参数更改为
long
,编译器只能从
Monster
上定义的方法中进行选择,因此它知道它可以在所有实例上安全调用的唯一方法是
bride(long)
:这两个子类都不会重写此方法-因此行为是基类的行为

class Monster {
    boolean frighten(int x) {
        System.out.println("Monster");
        return true;
    }
}

class Vampire extends Monster {
    boolean frighten(byte x) {
        System.out.println("Vampire");
        return true;
    }
}

class Dragon extends Monster {
    boolean frighten(int x) {
        System.out.println("Dragon");
        return true;
    }
}


class Sample {
    public static void main(String s[]) {
        Monster[] inst = new Monster[3];
        inst[0] = new Monster();
        inst[1] = new Vampire();
        inst[2] = new Dragon();

        for (int i = 0; i < 3; i++) {
            inst[i].frighten(i);
        }
    }
}
如果将
Dragon
上的
bride
方法的参数更改为
long
,它将不再覆盖基类中的方法-因此行为是基类的行为

class Monster {
    boolean frighten(int x) {
        System.out.println("Monster");
        return true;
    }
}

class Vampire extends Monster {
    boolean frighten(byte x) {
        System.out.println("Vampire");
        return true;
    }
}

class Dragon extends Monster {
    boolean frighten(int x) {
        System.out.println("Dragon");
        return true;
    }
}


class Sample {
    public static void main(String s[]) {
        Monster[] inst = new Monster[3];
        inst[0] = new Monster();
        inst[1] = new Vampire();
        inst[2] = new Dragon();

        for (int i = 0; i < 3; i++) {
            inst[i].frighten(i);
        }
    }
}

阻止这种“意外”行为的方法是始终将@Override添加到您认为可以覆盖基类中方法的方法中。如果带有该注释的方法实际上没有重写基类上的方法,编译器将对此进行投诉。

vamper
没有重写
brand(int)
,它定义了一个重载。如果在
Monster
类中将其更改为
long
Dragon
也不会覆盖该方法。这就是为什么如果希望重写方法,就应该对方法
@Override
进行注释。我甚至不会调用此继承。您未正确使用
扩展
关键字。要详细说明,
怪物
应该是不同类型怪物的模型或蓝图。这并没有实现。问题不在于吸血鬼类。如果Monster或drangon类中的x的类型为int,那么它可以完美地工作并打印以下内容:Monster MonsterDragon@Nain:我不会称之为“工作正常”,因为代码的意图是调用某个类的
怪物
。这是我能看到的最明显的问题,因为你没有看到“吸血鬼”,因为你重载了你的方法,而不是覆盖了它。把注释移到更低的一层。你不能在课堂上使用它。
class Monster {
    boolean frighten(int x) {
        System.out.println("Monster");
        return true;
    }
}

class Vampire extends Monster {
    boolean frighten(byte x) {
        System.out.println("Vampire");
        return true;
    }
}

class Dragon extends Monster {
    boolean frighten(int x) {
        System.out.println("Dragon");
        return true;
    }
}


class Sample {
    public static void main(String s[]) {
        Monster[] inst = new Monster[3];
        inst[0] = new Monster();
        inst[1] = new Vampire();
        inst[2] = new Dragon();

        for (int i = 0; i < 3; i++) {
            inst[i].frighten(i);
        }
    }
}