1. 程式人生 > >java基礎複習(抽象類和介面)

java基礎複習(抽象類和介面)

  • 介面中的資料域只能是public static final,方法只能是public abstract
    由於這個原因,這些修飾也可以忽略。

資料域只能是static final的原因:
stackoverflow上:

An interface can’t have behavior or state because it is intended to specify only an interaction contract, no implementation details. No behavior is enforced by not allowing method/constructor bodies or static/instance initializing blocks. No state is enforced by only allowing static final fields.Therefore, the Class can have a state (static state), but the instance state is not inferred by the interface.

  • CompareTo方法和equals方法

強烈建議CompareTo應該與equals保持一致。對於兩個物件o1和o2, 應該確保以下同時成立:
o1.equals(o2)為true
o1.compareTo(o2)==0

The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C. Note that null is not an instance of any class, and e.compareTo(null) should throw a NullPointerException even though e.equals(null) returns false

stackoverflow上有人提了一個問題,與這個有點關係,
Java, Why it is implied that objects are equal if compareTo() returns 0?

問題:

import java.util.Comparator;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;

public class Person implements Comparable<Person
> {
private final String name; private int height; public Person(String name, int height) { this.name = name; this.height = height; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public String getName() { return name; } @Override public int compareTo(Person o) { return Integer.compare(height, o.height); } public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Person other = (Person) obj; if (!Objects.equals(this.name, other.name)) { return false; } return true; } public int hashCode() { int hash = 5; hash = 13 * hash + Objects.hashCode(this.name); return hash; } public String toString() { return "Person{" + name + ", height = " + height + '}'; } public static class PComparator1 implements Comparator<Person> { @Override public int compare(Person o1, Person o2) { return o1.compareTo(o2); } } public static class PComparator2 implements Comparator<Person> { @Override public int compare(Person o1, Person o2) { int r = Integer.compare(o1.height, o2.height); return r == 0 ? o1.name.compareTo(o2.name) : r; } } public static void test(Set<Person> ps) { ps.add(new Person("Ann", 150)); ps.add(new Person("Jane", 150)); ps.add(new Person("John", 180)); System.out.println(ps.getClass().getName()); for (Person p : ps) { System.out.println(" " + p); } } public static void main(String[] args) { test(new HashSet<Person>()); test(new TreeSet<Person>()); test(new TreeSet<>(new PComparator1())); test(new TreeSet<>(new PComparator2())); } }

result:

java.util.HashSet
 Person{Ann, height = 150}
 Person{John, height = 180}
 Person{Jane, height = 150}

java.util.TreeSet
 Person{Ann, height = 150}
 Person{John, height = 180}

java.util.TreeSet
 Person{Ann, height = 150}
 Person{John, height = 180}

java.util.TreeSet
 Person{Ann, height = 150}
 Person{Jane, height = 150}
 Person{John, height = 180}

別人的解答,總結一下有下面幾點
1、首先,HashSet會根據hash code排序,
而TreeSet則是與equals、hash code沒有關係,
它只會按照class本身的compare來決定
2、第一點即解釋了問題的輸出結果
3、由上面的例子更能提醒我們,最好是使
(x.compareTo(y)==0) == (x.equals(y))
否則可能會出現一些意想不到的錯誤。