public class monstertestdrive {

public static void main(String[] args) {
    monster[] ma=new monster[3];
    ma[0]=new vampier();
    ma[1]=new monster();
    ma[2]=new dragon();
    for(int x=0;x<3;x++){
        ma[x].frighten(x);
      }
    }

}

class monster{
boolean frighten(int d){
    System.out.println("arrah");
    return false;
  }
}

class vampier extends monster{
boolean frighten(int x){
    System.out.println("a bite?");
    return true;
 }
}

class dragon extends monster{
boolean frighten(int degree){
    System.out.println("breath fire");
    return true;
 }
}


frighten方法中提到的返回类型有任何用途吗?
我问这个是因为我交换了返回类型,但是输出是相同的。但是当我更改数组对象的位置即0,1和2时,我得到了不同的输出。

最佳答案

布尔返回值和整数参数对您的输出没有影响,因为这些方法没有使用它们。您从不使用任何方法的返回值来设置任何变量或确定输出。您也永远不会使用任何传入的值来更改方法内的任何内容或方法的输出。您可能想先阅读有关返回类型,方法和参数的更多信息;基本知识是,除非您打算使用参数或返回值,否则没有理由使用它们。一旦您了解了这一点,我们就可以继续研究为什么数组的每个元素都输出不同版本的frighten。

您可能需要首先阅读有关具体和抽象类,多态性和继承的信息。

您正在查看的是动态(或较晚)方法绑定的实例。

您的父级CONCRETE类(怪物)具有frighten()的特定实现:

boolean frighten(int d){
   System.out.println("arrah");
   return false;
}


frighten的此实现已使用布尔返回类型和整数参数编写。扩展此类时,子类将继承此方法。假设我创建了另一个子类别的狼人:

 class werewolf extends monster{}


乍一看,该类没有与之关联的方法或属性;但实际上,由于类继承,它隐式具有在其父类中声明的frighten方法。这是编译器看到的:

 class werewolf extends monster{
      boolean frighten(int d){ // Method **from** the parent class
      //This is implicitly built into the subclass due to inheritance
           System.out.println("arrah");
           return false;
      }
 }


但是,这些方法并非一成不变。在子类中,可以覆盖父类方法。这是您在吸血鬼和龙类中所做的。这是一个替代,因为您的方法具有相同的返回类型,相同的方法名称和相同的参数。如果要更改其中的任何一项,它将完全是另一种方法,并且不会替代父方法。您应该养成使用@Override指令的习惯,该指令告诉编译器进行检查并确保您实际上遵循正确的格式进行覆盖。

 class dragon extends monster{
      @Override // This tells the compiler to check the parent for this method you are going to override and if you've followed the right format
      boolean frighten(int degree){
           System.out.println("breath fire");
           return true;
      }
 }


动态/后期方法绑定是程序在运行时解析对各自类实现的引用的能力。

您的所有子类都是它们扩展的超类的实例,因此,当您创建对超类类型的引用的数组时,可以用子类填充它们(此处有点自我推广:Why can an array of references to an interface house classes that implement that interface?)。

这是因为子类与其父类具有ISA关系。但是,当您执行main方法时:

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


您尚未明确告诉编译器,如何选择要使用的frighten()版本?嗯,这就是多态性的优点-您不必这样做。当代码执行时,它足够聪明,可以查看引用所指向的实际类,如果方法被正确覆盖(例如,嘿),则此方法有另一种本地实现,让我们执行其中一个而不是其中一个这是父类。但是,如果您以任何方式更改子类中的返回值或frighten()方法的参数,它都不会被覆盖,并且执行的方法将默认为引用的类型(在这种情况下为Monster类)因为您的参考数组是怪兽之一)。

因此,这不是布尔值如何工作的问题,而是如何正确使用覆盖的方法的问题。希望这对您有所帮助!

关于java - boolean 表达式如何在Java中工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21938863/

10-12 06:00