简体   繁体   English

如何在资源类中重写equals()方法?

[英]How to override equals() method in a resource class?

I'm in an AP Computer Science (high school level) and I'm still trying to grasp some things we're learning in class. 我正在读AP计算机科学(高​​中阶段),但仍在尝试掌握我们在课堂上学习的一些知识。 We recently got an assignment to modify a 'Pizza' resource class. 我们最近得到了一个修改“ Pizza”资源类的任务。 His directions from the worksheet were: 他在工作表中的指示是:

Part 1: Modify the old Pizza class written earlier. 第1部分:修改先前编写的旧Pizza类。 Add an equals() method which overrides the one in the Object class. 添加一个equals()方法,该方法将覆盖Object类中的一个方法。 Two Pizza objects are equal if the toppings, sizes and costs are the same. 如果浇头,大小和成本相同,则两个比萨饼对象相等。 Use the PizzaMatch class to test the new method. 使用PizzaMatch类测试新方法。

Part 2: Add a compareTo() method to implement the interface Comparable. 第2部分:添加compareTo()方法以实现接口Comparable。 This compareTo() should help you find the cheapest pizza in pizza.txt.** 这个compareTo()应该可以帮助您在pizza.txt中找到最便宜的比萨。**

And the output he wanted is 他想要的输出是

**Part 1 Output
Input a Pizza topping, size, and cost: 
sloppyJoe 15 15.30
That pizza is # 20 in the file.
ÏÏÏ
Input a Pizza topping, size, and cost: 
cheese 12 12.99
That pizza is not in the file.
Part 2 Output
The cheapest pizza: The 9 inch olive pizza will cost   $7.99** 

Here is Pizza (the resource class) 这是披萨(资源类)

 import java.util.*; 
 import java.io.*;
 class Pizza 
{ 
  private int size; 
  private double cost; 
  private String topping; 
  public Pizza(int pizzaSize, double pizzaCost,String pizzaTopping) 
  { 
     size = pizzaSize; 
     cost = pizzaCost; 
     topping = pizzaTopping; 
  } 
  public void setSize(int input) 
  { 
     size = input; 
  } 
  public void setCost(double input) 
  { 
     cost = input; 
  } 
  public void setTopping(String input) 
  { 
     topping = input; 
  } 
  public int getSize() 
  { 
     return size; 
  } 
  public double getCost() 
  { 
     return cost; 
  } 
  public String getTopping() 
  { 
     return topping; 
  } 

  public String toString() 
  { 
     return (size + " inch " + topping + " pizza will cost $" + cost); 
  } 
}

And here is PizzaMatch 这是PizzaMatch

  import java.util.*;
  import java.io.*;

public class PizzaMatch   {
   public static void main (String [] args)throws Exception
   {

     Scanner keyboard = new Scanner(System.in);
     System.out.println("Input a Pizza topping, size, and cost: "); 
     String top = keyboard.next();  
     int size = keyboard.nextInt();
     double cost = keyboard.nextDouble();
     Pizza input = new Pizza(size, cost, top);
     int counter =1;
     boolean found = false;
     while(inFile.hasNext())
     {
        String t = inFile.next();  
        int s = inFile.nextInt();
        double c = inFile.nextDouble();
        Pizza temp = new Pizza(s,c,t);
       //System.out.println("Pizza #"+counter+"\t" + temp);
        if(temp.equals(input))
        {
           System.out.println ( "That pizza is # " + counter 
              + " in the file.");
           found = true;
        }
        counter++;         
     }
     if(!found)
        System.out.println("That pizza was not in the file.");

  }
}

Basically, I'm not sure where to start. 基本上,我不确定从哪里开始。 I'm still a bit unsure of interfaces, as well. 我仍然不确定接口。 I realize that we have to make a .equals() method, but how? 我意识到我们必须制作一个.equals()方法,但是怎么做呢? I started out writing 我开始写

public Boolean equals(Pizza p)
{
 if(p==/*this is where I don't know what to write*/)
return true;
}

Any help would be greatly appreciated, for both Part 1 and Part 2 of the assignment! 对于作业的第1部分和第2部分,任何帮助将不胜感激! Thanks so much :) 非常感谢 :)

If you want to override a method of a base class, in general the subclass method should have the same signature of the base. 如果要覆盖基类的方法,通常,子类方法应具有与基类相同的签名。

If you look at the documentation for Object.equals() , you can see that it actually returns a boolean , not a Boolean . 如果查看Object.equals()的文档,则可以看到它实际上返回的是boolean ,而不是Boolean Also, it takes an Object parameter, not a Pizza parameter. 而且,它采用一个Object参数,而不是Pizza参数。 So in your case, in Pizza , you'd need: 因此,对于您的情况,在Pizza ,您需要:

public boolean equals (Object o) {
    if (!(o instanceof Pizza))
        return false; // its null, or its not Pizza
    Pizza p = (Pizza)o;
    // compare relevant fields of 'this' with 'p' and return result.
    return ...;
}

Note, by the way, that Java has an @Override annotation that you should use to mark methods that are intended to override base methods: 请注意,顺便说一下,Java具有@Override批注,您应使用该批注来标记旨在覆盖基本方法的方法:

@Override
public boolean equals (Object o) {
    if (!(o instanceof Pizza))
        return false; // its null, or its not Pizza
    Pizza p = (Pizza)o;
    // compare relevant fields of 'this' with 'p' and return result.
    return ...;
}

If you had used this annotation in your original example, the compiler would have generated an error stating that your equals() method didn't actually override the base. 如果在原始示例中使用了此批注,则编译器将生成一个错误,指出您的equals()方法实际上并未覆盖基数。

As for the actual implementation, that's up to you. 至于实际的实现,则取决于您。 What does it take to make one Pizza equal another? 要使一个Pizza等于另一个Pizza需要什么? You have the criteria listed in your requirements, so implementing equals will involve comparing those fields of this and p and determining if the two are equal or not. 您已在需求中列出了标准,因此实施equals将涉及比较thisp那些字段并确定两者是否相等。

The strategies for compareTo() are similar. compareTo()的策略相似。 Your Pizza will have to implement, eg, Comparable<Pizza> and then override int compareTo(Pizza) ; 您的Pizza必须实现,例如Comparable<Pizza> ,然后重写int compareTo(Pizza) the implementation should behave as defined in the documentation for Comparable.compareTo() , and the exact logic you use for determining the result depends on the requirements given in your problem description. 实现的行为应符合Comparable.compareTo()文档中的定义,并且用于确定结果的确切逻辑取决于问题描述中给出的要求。

I recommend reading the official tutorial on Overriding Methods for Part 1, and the official tutorial on Object Ordering for Part 2. These are concise, well-written, and will give you the tools you need to solve these types of issues. 我建议阅读有关第1部分的重写方法的官方教程和有关第2部分的对象排序的官方教程。它们简洁明了,编写精巧,将为您提供解决这些类型问题所需的工具。

To override a method, you need to declare it exactly the same as in the original. 要覆盖方法,您需要声明与原始方法完全相同的方法。 It's helpful to use the @Override annotation to enforce this. 使用@Override注释强制执行此操作很有帮助。

In the case of equals() , you'd start with: 对于equals() ,您将从以下内容开始:

@Override
public boolean equals(Object o) {
  :
}

The skeleton is typically: 该框架通常为:

@Override
public boolean equals(Object o) {
  if (o instanceof Pizza) {
    // Do the comparison for Pizza objects.
  } else {
    // A Pizza object can only be equal to other Pizza objects.
    return false;
  }
}

Well first of all you should add an @Override tag above the equals function because you're overriding Object's equals() function. 首先,您应该在equals函数上方添加@Override标记,因为您要覆盖Object的equals()函数。 Your professor told you to verify if the topping, size and cost were the same for both pizza's, this means that you should compare certain variables of both pizza's and not just try to compare one complete pizza with another as you're doing now (p==??). 您的教授告诉您要验证两个比萨饼的浇头,大小和成本是否相同,这意味着您应该比较两个比萨饼的某些变量,而不是像现在一样尝试比较一个完整的比萨饼与另一个完整的比萨饼(p == ??)。

You'll want something like this: 您会想要这样的东西:

@Override
public Boolean equals(Object o)
{
    //Make sure its a pizza
    if (o instanceof Pizza == false)
        return false;

    //Cast to a pizza
    Pizza p = (Pizza)o;

    //Compare the fields
    if(this.size == p.getSize() && this.cost == p.getCost() && this.topping == p.getTopping())
        return true;
    else
        return false;
}

Its pretty simple, you override a method in a super class by defining the method with the same method signature in the derived class. 非常简单,您可以通过在派生类中使用相同的方法签名定义方法来覆盖超类中的方法。 In Object, the .equals method is defined as: 在Object中,.equals方法定义为:

public boolean equals(Object obj)

So you make a method in your class with the same signature and provide your implementation. 因此,您可以在类中创建一个具有相同签名的方法并提供实现。 You didnt ask for the interface part, but ill include it anyway. 您没有要求接口部分,但是无论如何都不能包含它。 An interface is a contract. 接口是合同。 It defines method signatures that an object must have if it implements the interface, but it does not provide an implementation. 它定义了对象实现接口时必须具有的方法签名,但是不提供实现。 This will result in compile time errors if you havent provided the implementation in a method whose signature matches whats defined in the interface. 如果您没有在签名与接口中定义的签名相匹配的方法中提供实现,则会导致编译时错误。 Here you just want to add the keyword implements followed by the interface you wish to implement on the class declaration, then do pretty much exactly what you did with the equals method, only with compareTo. 在这里,您只想添加关键字Implements,然后再添加要在类声明中实现的接口,然后执行与equals方法几乎完全相同的操作,仅使用compareTo。

See .equals here http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html and compareTo here http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html 请参阅http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html此处的.equals,并比较此处http://docs.oracle.com/javase/7/docs/api/ java / lang / Comparable.html

For the equals() you need something like this: 对于equals(),您需要这样的东西:

public boolean equals (Object o){
    boolean res=false;
    if (o instanceof Pizza){
        Pizza p0 = (Pizza) o;
        res=getTopping().equals(p0.getTopping())&&getSize().equals(p0.getSize())&&getCost().equals(p0.getCost());
    }
    return res;

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM