В методе Java, который принимает аргумент Object, как вы можете получить доступ к полям, которые существуют только для экземпляров определенных классов? - PullRequest
1 голос
/ 28 марта 2012

- Да, это вопрос, требующий помощи в отношении того, что было назначено в качестве домашней работы. Нет, это не я прошу тебя сделать мою домашнюю работу для меня. Срок был полчаса назад; Я буквально не могу изменить свое представление. Тебе просто нужно поверить мне на слово. Идем дальше ...

Я знаю, что тестирование типа объектов не требуется. Когда я искал подробности об instanceof, я обнаружил полдюжины тем, в которых люди отвечали только для того, чтобы сообщить оригинальному постеру, что они ошиблись, если им пришлось проверить, чтобы выяснить, с каким объектом они имели дело до обработки Это. Да, я знаю, я хотел бы следовать соглашениям. К сожалению, мой профессор попросил нас переопределить метод equals класса, который мы определили, и специально потребовал параметр типа Object. Если вы увидите мой код, вы, вероятно, поймете лучше:

public boolean equals(Course other){
    if(!(other instanceof Course)){
        return false;
    } else if(other.name==this.name && other.days==this.days && 
        other.start==this.start && other.end==this.end){
        return true;
    }
    return false;
}

Вы, наверное, можете понять, куда я иду с этим. Параметр 'other' должен иметь тип Object, но программа подходит, если я оставлю его как Object и использую поля name / days / start / end. Если я изменю это на Конечно, конечно, это работает (не каламбур), но это был бы совершенно другой метод. Желаемое поведение - для всех объектов, кроме экземпляров Course, заставить метод возвращать false, и, кроме того, для несоответствующих данных между экземплярами Course, чтобы они возвращали false.

Прошу прощения за всех, кто достаточно хорошо знает Java, чтобы расстроиться, увидев такие вопросы.

Ответы [ 4 ]

6 голосов
/ 28 марта 2012

Если вы хотите переопределить метод «равно», вы должны использовать Object в качестве параметра, и, таким образом, вам нужно проверить для типа объекта. Обычно ваша собственная реализация будет выглядеть так:

@Override
public boolean equals(Object obj) {
    if (obj == this)
        return true;  // object's references are identical
    else if (!(obj instanceof Course))
        return false;

    Course that = (Course) obj;
    return (this.name.equals(that.name)) && (this.days == that.days)
        && (this.start.equals(that.start)) && (this.end.equals(that.end));
}

Конечно, вы должны также переопределить hashCode, используя те же важные поля.


Вместо этого вы перегружаете метод собственным параметром типа Course. Поэтому, если вы вызываете myobject.equals(anotherObject) и anotherObject - это , а не типа Course, ваш метод "равно" никогда не будет вызван, вместо этого будет вызван метод Object#equals, который выполняет только следующее: return this == obj.


Причиной того, что перегрузки метода «равно» недостаточно, является необходимость перегрузить также «hashCode», который не принимает параметров и, следовательно, не может быть перегружен.

  • Если вы напишите свою собственную реализацию boolean equals(Object), вы должны также реализовать int hashCode()
  • Оба метода должны использовать одинаковые значимые поля для "hashCode" и "equals".
  • Если a.equals(b) == true, то следующее должно также быть верным: a.hashCode() == b.hashCode()
  • Также если a.hashCode() != b.hashCode(), то a.equals(b) == false

Последний пункт - главная причина, почему вы не должны просто перегружать «равно» своим собственным типом:

Course c1 = new Course("myname");
Course c2 = new Course("myname");
c1.equals(c2);                   // true
c1.hashCode() == c2.hashCode();  // false
0 голосов
/ 28 марта 2012

Вы пытаетесь разыграть это:

Cource c = (Course)other;
0 голосов
/ 28 марта 2012

Ваш код:

 public boolean equals(Course other){
     if(!(other instanceof Course)){  <-- other can only be Course here
          return false;
     } else if(other.name==this.name && other.days==this.days && 
         other.start==this.start && other.end==this.end){
         return true;
      }
     return false;
  }

Правильный код:

  public boolean equals(Object other){
     if(!(other instanceof Course)){
         return false;
     } else{ 
       Course c = (Course) other;
       if(c.name==this.name && c.days==this.days && 
          c.start==this.start && c.end==this.end){
         return true;
      }
     }
   } 
     return false;
  }
0 голосов
/ 28 марта 2012

Вы можете разыграть Объект как Курс:

Course course = (Course)object;

Затем выполните все сравнения объекта курса. Очевидно, что перед проверкой все еще выполняйте проверку instanceof, чтобы избежать исключения ClassCastException.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...