【问题标题】:How boolean expression works in java?布尔表达式在java中如何工作?
【发布时间】:2014-03-23 05:30:09
【问题描述】:
 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 的调用都将返回一个布尔结果,但您不会在任何地方对该结果执行任何操作,因此更改该布尔结果不会影响任何事情也就不足为奇了。你期待什么?
  • 另外,如果改变数组元素的顺序,然后按顺序进行迭代,输出自然会不一样。
  • @JacobM 实际上这个程序是在一本书(Head First Java)中编写的,根据书本,如果我们将返回类型从 true 更改为 false,那么我们会收到不同的输出。因此,我感到困惑并在此论坛上提出了这个问题。
  • 手边没有 Head First Java 的副本,但我敢打赌,你已经改变了书中的内容。查看ma[x].frighten(x); 行。要使返回值产生任何效果,您必须先执行bool result = ma[x].frighten(x); 之类的操作,然后再执行result 之类的操作。
  • @JacobM 当我将 frighten 方法中的参数类型从 int 更改为 byte 时,为什么 Dragon frighten 方法不打印而 Monster 中的方法打印了两次

标签: java arrays methods boolean return


【解决方案1】:

boolean 返回和 integer 参数对您的输出没有影响,因为这些方法不使用它们。您永远不会使用任何方法的返回值来设置任何变量或确定输出。您也永远不会使用任何传入的值来更改方法中的任何内容或方法的输出。您可能想先阅读更多关于返回类型、方法和参数的信息;这是基本知识,除非您打算使用参数或返回值,否则没有理由使用它们。一旦你理解了我们可以继续讨论为什么数组的每个元素输出不同版本的 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() 方法的返回值或参数,它就会变成 not 覆盖,并且执行的方法将默认为引用的类型(在这种情况下是怪物类,因为您的参考数组是怪物之一)。

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

【讨论】:

    【解决方案2】:

    是的,返回类型很重要。 boolean 返回类型返回 truefalse。您还可以创建一个int 返回类型并返回一个数字。这对很多事情都很方便

    例如:

    int sum(int x, int y)
    {
        return x + y;
    }
    

    您没有注意到差异,因为您没有对返回值做任何事情

    ma[x].frighten(x);
    

    如果你的函数没有返回任何有意义的东西,那么你最好将返回类型设置为void 并且什么都不返回

    void frighten(int degree){
        System.out.println("breath fire");
    }
    

    【讨论】:

    • 当我将 frighten 方法中的参数类型从 int 更改为 byte 时,为什么 Dragon frighten 方法不打印而 Monster 中的方法打印两次
    • @Shantanu 这是因为你的两个类都继承自 Monster 的 frighten(int),当你做出改变时,dragon 不再有 frighten(int) 来覆盖它,所以它使用它从 Monster 继承的那个
    【解决方案3】:

    我敢打赌改变 Monster 的 frighten 方法中的返回类型(即从 boolean 到 int 然后返回值从 false 到 0)来试验不同的多态情况......然后得到不同的输出

    【讨论】:

    • 当我将 frighten 方法中的参数类型从 int 更改为 byte 时,为什么 Dragon frighten 方法不打印而 Monster 中的方法打印两次
    • 您从哪个方法更改参数类型?怕龙?
    • 通过在 Dragon 的 frghten 方法中将参数类型更改为 Byte,您不再覆盖从 Monster 继承的方法,而是使用另一个签名重载。在运行时有两种方法可供选择,但只有一种与参数类型匹配:它是 Monster 的方法。所以你看到了对应的输出
    猜你喜欢
    • 2022-12-15
    • 1970-01-01
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多