2013-05-20 2 views
0

Эффективен в Java Пункт 16:Как понять состав и методы пересылки?

К счастью, есть способ, чтобы избежать всех проблем раньше. Вместо расширения существующего класса дайте вашему новому классу частное поле, которое ссылается на существующий класс.

Тогда я получил код, чтобы объяснить в деталях:

public class InstrumentedSet<E> extends FowardingSet<E> { 
    private int addCount = 0; 

    public InstrumentedSet(Set<E> s) { 
     super(s); 
    } 

    public boolean add(E e) { 
     addCount++; 
     super.add(e); 
    } 

    ... 

    public int getCount() { 
     return addCount; 
    } 
} 

public class ForwardingSet<E> implements Set<E> { 
    private final Set<E> s; 
    public ForwardingSet(Set<E> s) { 
     this.s = s; 
    } 

    public boolean add(E e) { 
     return s.add(e); 
    } 

    ... 
} 

Я чувствую спутать: где частная ссылка? и я видел, что расширяет ключевые слова, очевидно, так где же состав в коде?

+5

Возможно, это определение 'ForwardingSet'. –

+0

Какое издание Effective Java это? Во втором издании пункт 18 является «Предпочтение интерфейсов абстрактным классам». Вы говорите о пункте 16? –

+0

@vivin, вы правы. Это ошибка типографии. Я также обновил текст. –

ответ

0
public class ForwardingSet<E> implements Set<E> { 
    private final Set<E> s; 
         ^-- here is the private reference 

ForwardingSet реализует интерфейс Set путем перенаправления или делегирования всех его методов другому набору. Это образец декоратора в действии.

1

Ссылка находится по адресу:

private final Set<E> s; 

s устанавливается через конструктор

ForwardingSet(Set<E> s) 

и конструктор дочернего

InstrumentedSet(Set<E> s) 

, что вызывает супер (ов);

InstrumentedSet - это обертка для подкласса FowardingSet и переадресовывает туда звонки.