재정의한 메서드는 동적으로 선택되고, 다중정의한 메서드는 정적으로 선택된다

재정의한 메서드 (오버라이딩)

class Wine {
    String name() { return "Wine"; }
}

class SparklingWine extends Wine {
    @Override String name() { return "SparklingWine"; }
}

class Champagne extends SparklingWine {
    @Override String name() { return "Champagne"; }
}

public class Main {
    public static void main(String[] args) {
        List<Wine> wines = Arrays.asList(new Wine(), new SparklingWine(), new Champagne());

        for (Wine wine : wines) {
            System.out.print(wine.name() + " ");
        }
    }
}
// Wine SparklingWine Champagne

다중정의한 메서드 (오버로딩)

public class Main {
    public static String classify(Set<?> set) {
        return "집합";
    }

    public static String classify(List<?> list) {
        return "리스트";
    }

    public static String classify(Collection<?> list) {
        return "그 외";
    }

    public static void main(String[] args) {
        Collection<?>[] collections = {
                new HashSet<>(),
                new ArrayList<>(),
                new HashMap<String, String>().values()
        };

        for (Collection<?> c : collections) {
            System.out.print(classify(c) + " ");
        }
    }
}

다중정의가 혼동을 일으키는 상황을 피하자

주의사항1 : 오토박싱

public class SetList {
    public static void main(String[] args) {
        Set<Integer> set = new TreeSet<>();
        List<Integer> list = new ArrayList<>();

        for (int i = -3; i < 3; i++) {
            set.add(i);
            list.add(i);
        }
        for (int i = 0; i < 3; i++) {
            set.remove(i);
            list.remove(i);
        }
        System.out.println(set + " " + list);
    }
}

//실행 결과 : [-3, -2, -1] [-2, 0, 2]