2013-10-05 3 views
3

В C# существует тип члена, который называется свойством. Это позволяет вам легко и просто определять частное поле и предоставлять простые или сложные геттеры и сеттеры, экономя пространство, не имея необходимости определять целые методы. В Java нет ничего подобного, и из того, что я вижу, общий консенсус заключался в том, чтобы сосать его и определить полные методы getter и setter для частных переменных.Плюсы и минусы реализации свойств в Java

В настоящее время я играл с следующим классом:

public class Property<T> { 

    private T value = null; 

    public Property(){} 
    public Property(T initialValue){ 
     value = initialValue; 
    } 

    public T get(){ 
     return value; 
    } 

    public void set(T newValue){ 
     value = newValue; 
    } 

} 

С этой реализацией, вы можете определить простые свойства, которые требуют только добытчиков и сеттеров: final Property<String> name = new Property<>("Dog");

Или более продвинутых варианты like the one that MSDN provides for C#:

... 
public double seconds; 

public final Property<Double> Hours = new Property<Double>(){ 
    @Override 
    public Double get() { 
     return seconds/3600; 
    } 

    @Override            
    public void set(Double newValue) { 
     seconds = newValue * 3600; 
    } 
}; 
... 

Какими будут плюсы и минусы этого решения?

ответ

1

Так что полный синтаксис, скажем, имя, теперь будет:

theObject.name.set("new name"); 

Дело в том, как вы доступ к этому объекту имя? Является ли он общедоступным/защищенным. Тогда он может быть отменен. Это личное? Тогда вы не можете изменить его вне класса.

Решение, которое вы предложили, работает только в том случае, если у вас уже есть доступ к объекту, после чего вам не нужно решение.

+0

В соответствии с его примером это будет 'object.Hours.set (3600.0)', и это найти, но я пока не вижу преимущества. – omainegra

2

Плюсы в значительной степени очевидны. Я укажу некоторые из них, которые сделают его лучше, чем свойства C#:

  1. Поле обратной связи спрятано, чтобы вы случайно не использовали его вместо свойства. (но недостатком является то, что вы не можете легко выбрать поле поддержки, если хотите)
  2. В отличие от автоматических свойств C#, вы можете переопределить методили set, не оба, например.

    public Property<List<String>> MyList = new Property<List<String>>(){ 
        @Override 
        public List<String> get() { 
         if (value == null) 
          value = new ArrayList<String>(); 
         return value; 
        } 
        // set still works 
    }; 
    

Есть минусы, однако:

  1. Он не является частью языка Java, или каких-либо общих библиотек, поэтому он может быть запутанным для людей, которые читают ваш код (включая себя в будущем).
  2. Вы не можете изменить видимость методов get и set: если вы можете получить доступ к Property<T>, вы можете получить и установить значение.
  3. Если вы не внесете Property поле final, любой, у кого есть доступ к нему, может изменить его на свою собственную реализацию Property. Это может быть полезно, но в большинстве случаев это будет боль.
  4. (это совместное использование с свойствами C#). Вы не можете изменить аргументы, которые передаются методам get и set. Например. у вас не может быть Property<MyType> с set(MyType) и set(CompatibleType) (если вы не продлеваете Property).
  5. Использование генерических средств повсеместно означает, что во время выполнения (спасибо type erasure) вы используете Object повсеместно. Этот бокс/распаковка может привести к небольшому снижению производительности (что не заметно в большинстве приложений), если вы используете примитивы (например, используя double против Property<Double>).

Кстати, Scala это язык, который работает на JVM, которая включает в себя свойства, как родной функции, и взаимодействует с версией Явы свойств (геттеров/сеттеры). Возможно, вы захотите изучить это, поскольку в основном кто-то уже взломал язык Java для вас. =)

В целом, я бы сказал, что вы не должны пытаться заставить Java обладать свойствами. Когда в Риме делайте, как делают римляне. Если вам не нравится, как это делают римляне, двигайтесь по улице (Скала) или по всей стране (C#).

+1

Хорошее объяснение, я бы дал вам еще одно упоминание * Scala *, если бы я мог – omainegra

+0

@omainegra - я просто дал ему еще один (+1) для упоминания Scala. – Brian

0

Профи этого решения (ваш анонимный внутренний класс) состоит в том, что если вам не нужно реализовывать это где-либо еще, это избавит вас от написания всего лишнего класса только для этой ситуации.

Зэком этого решения является то, что позже вы можете реализовать его в другом месте, а затем вы хотите, чтобы реорганизовать свой код для извлечения реализации имущества <Double> в свой класс, чтобы избежать повторений себя.

Я бы сказал,, если вы уверены, что вам не понадобится эта реализация в другом месте (я предполагаю, что вы этого не сделаете), просто перейдите к более позднему решению анонимного внутреннего класс. Это хорошо.

Смежные вопросы