Chociaż niektórzy ludzie nie znoszą „metod opcjonalnych”, w wielu przypadkach mogą oferować lepszą semantykę niż wysoce rozdzielone interfejsy. Pozwalają między innymi na to, że obiekt może zyskać zdolności lub cechy w trakcie swojego życia, lub że obiekt (zwłaszcza obiekt otoki) może nie wiedzieć, kiedy jest skonstruowany, jakie dokładnie umiejętności powinien zgłosić.
Chociaż raczej nie będę nazywał klas języka Java wzorami dobrego projektowania, sugerowałbym, że dobry framework kolekcji powinien u podstaw zawierać dużą liczbę opcjonalnych metod wraz ze sposobami zapytania kolekcji o jej cechy i możliwości . Taki projekt pozwoli na użycie pojedynczej klasy opakowania z dużą różnorodnością kolekcji bez przypadkowego zaciemnienia umiejętności, jakie może mieć kolekcja podstawowa. Jeśli metody nie były opcjonalne, konieczne byłoby posiadanie innej klasy opakowania dla każdej kombinacji funkcji obsługiwanych przez kolekcje, w przeciwnym razie niektóre opakowania nie nadawałyby się do użytku w niektórych sytuacjach.
Na przykład, jeśli kolekcja obsługuje pisanie elementu według indeksu lub dodawanie elementów na końcu, ale nie obsługuje wstawiania elementów na środku, to kod chcący obudować go w opakowaniu, który rejestrowałby wszystkie wykonane na nim akcje, potrzebowałby wersji opakowania, które zapewniało dokładną kombinację obsługiwanych zdolności, lub jeśli żadna nie była dostępna, musiałaby użyć opakowania, które obsługuje dopisywanie lub zapisywanie według indeksu, ale nie oba. Jeśli jednak ujednolicony interfejs kolekcji zapewnia wszystkie trzy metody jako „opcjonalne”, ale następnie obejmuje metody wskazujące, która z opcjonalnych metod będzie użyteczna, wówczas pojedyncza klasa opakowania może obsługiwać kolekcje, które implementują dowolną kombinację funkcji. Na pytanie, jakie funkcje obsługuje, opakowanie może po prostu zgłosić wszystko, co obsługuje kolekcja enkapsulowana.
Zauważ, że istnienie „opcjonalnych zdolności” może w niektórych przypadkach pozwolić zbiorczym kolekcjom na wdrożenie niektórych funkcji w sposób, który byłby znacznie bardziej wydajny niż byłoby to możliwe, gdyby umiejętności były zdefiniowane przez istnienie implementacji. Załóżmy na przykład, że concatenate
użyto metody do utworzenia zbioru złożonego z dwóch innych, z których pierwszym był ArrayList z 1 000 000 elementów, a ostatnim z nich była kolekcja dwudziestoelementowa, którą można było iterować tylko od początku. Jeśli poproszono by o zbiór złożony o 1 000 013 element (indeks 1 000 012), mógłby zapytać ArrayList, ile elementów zawiera (tj. 1 000 000), odjąć to od żądanego indeksu (dając 12), odczytać i pominąć dwanaście elementów od drugiego kolekcja, a następnie zwróć następny element.
W takiej sytuacji, mimo że kolekcja złożona nie miałaby natychmiastowego sposobu na zwrócenie pozycji według indeksu, zapytanie kolekcji zbiorczej o 1 000 013 pozycji byłoby nadal znacznie szybsze niż odczytanie z niej 1 000 013 pozycji z osobna i zignorowanie wszystkich oprócz ostatniej jeden.