2010-04-02 12 views
10

Wiem, że prywatne zmienne instancji są dostępne za pośrednictwem ich publicznych metod pobierających i ustawiających.Java - Czy należy uzyskać dostęp do prywatnych instancji zmiennych w konstruktorach za pomocą metody pobierających i ustawiających?

Ale kiedy generuję konstruktory za pomocą IDE, inicjuje on bezpośrednio zmienne instancji zamiast inicjować je za pomocą metod ustawiających.

Q1. Więc powinienem zmienić kod wygenerowany przez IDE dla konstruktorów, aby zainicjować te zmienne instancji za pomocą ich metod ustawiających.

Q2. Jeśli tak, to dlaczego IDE nie generuje w ten sposób kodu konstruktorów?

============================= EDYCJA ================ =======================

  • używam Eclipse i NetBeans IDE

  • jest to ogólne pytanie. Ale na pytanie @Lords odpowiedź zależy od tego, czy nasz konstruktor jest publiczny, czy chroniony, czy prywatny czy prywatny?

+0

Czy twoi konstruktorzy są publiczni, prywatni czy cokolwiek innego? – Pops

+0

@ Lord Zmieniłem moje pytanie –

+0

I zredagowałem moją odpowiedź. (Właściwie dwie edycje w krótkim odstępie czasu.) – Pops

Odpowiedz

12

Powinieneś nigdy wywołać metodę nie ostateczną od konstruktora.Konstruktor klasy służy do inicjowania obiektu, a obiekt nie jest w stanie spójnym, dopóki konstruktor nie wróci. Jeśli twój konstruktor wywoła nie ostateczną metodę, która zostanie później nadpisana przez podklasę, możesz uzyskać dziwne, nieoczekiwane wyniki, ponieważ obiekt nie jest w pełni zainicjowany po wywołaniu metody nadpisanej.

Rozważmy contrived przykład:

class A { 
    private int x; 

    public A() { 
     setX(2); 
    } 

    public void setX(int x) { 
     this.x = x; 
    } 

    public int getX() { 
     return x; 
    } 
} 

class B extends A { 
    private int number = 10; 

    @Override   
    public void setX(int x) { 
     // set x to the value of number: 10 
     super.setX(number); 
    } 
} 

public class Test { 
    public static void main(String[] args) { 
     B b = new B(); 
     // b.getX() should be 10, right? 
     System.out.println("B.getX() = " + b.getX()); 
    } 
} 

Wynikiem tego programu jest:

B.getX() = 0 

Powodem jest to, że number członkiem B „s nie jest inicjowany w momencie setX nazywa, tak używana jest domyślna wartość 0.

This article ma bardziej szczegółowe wyjaśnienie, podobnie jak Efektywna Java.

1

To zależy. Jeśli twoje programy ustawiające/pobierające po prostu uzyskują dostęp do członków, należy uzyskać do nich bezpośredni dostęp. Jeśli masz też jakiś kod wraz z nim, użyj setterów.

+0

ok, ale czy nie byłoby lepiej użyć seterów, nawet jeśli settery ustawiają je bezpośrednio tak, aby śledzić enkapsulację i ułatwić dodanie kodu w ustawieniach w przyszłości (jeśli to konieczne)? –

+0

Cóż, to nie byłby już seter. Należy również wziąć pod uwagę, że z punktu widzenia obiektowego setery nie są obiektowo zorientowane (który obiekt w naturze ma "seter"?) – Searles

0

Powinieneś zdecydować, które pola zainicjujesz za pomocą konstruktora, a które zainicjujesz za pomocą settera. (oba są możliwe) Wolę używać konstruktora tylko tyle, ile to możliwe i często nie mam ustawiaczy.

To powinno być konfigurowalne/możliwe do wybrania w IDE. Bez znajomości swojego IDE nie ma sposobu, aby dowiedzieć się, dlaczego działa tak, jak robi.

2

Konstruktory służą do inicjowania. Inicjuj prywatne instancje zmiennych bezpośrednio w konstruktorze. Metody definiują zachowanie obiektu. Zachowanie występuje po utworzeniu/inicjalizacji. Manipuluj stanem swoich instancji zmiennymi za pomocą metod ustawiających. To klasyczne myślenie o OOP i prawdopodobnie dlatego twój IDE generuje kod, który robi.

0

Dobre odpowiedzi. Trzeba tylko dodać, że Eclipse (ten, którego często używam) ma szablony, które można modyfikować w celu wygenerowania kodu w pożądany sposób. Może to pomóc w dostosowaniu kodu do Twoich potrzeb.

PS. Raczej używam seterów i pobierających. Podobnie jak nawyk, utrzymuje spójny kod, czuję, że łatwiej będzie go przeczytać komuś innemu, jeśli zachowam nawyki całego kodu.

0

Przede wszystkim initialization != setters (przynajmniej nie zawsze)

Ale IDE są po prostu grać ładny z JavaBeans czczonych niegdyś wzornictwo Zakładając zmian własności powinno nastąpić poprzez ustawiaczy.

Jest to kwestia projektu. Jeśli twoje klasy reprezentują czyste obiekty wartości, nie szkodzi inicjowaniu przez: = Ale jeśli twoje klasy mogą stać się JavaBean, których zmiana właściwości jest czymś więcej niż tylko inicjowaniem lub przypisaniem, idź z połączeniami set*.

0

Prywatne zmienne instancji klasy powinny być (jak sądzę być) deklarowane poza dowolnym konstruktorem klasy. Gdybym mógł podzielić część twojego pytania na dwie części:

Q1) Jeśli zmienne instancji zostaną zainicjowane po utworzeniu klasy, w przeciwieństwie do zmiennych lokalnych, po co zawracać sobie głowę dodatkową pracą w ramach danego konstruktora klasy (?).

A1) Chociaż nie trzeba inicjować zmiennych instancji (prywatny łańcuch someString, domyślnie ma wartość null i jest legalny), jednym z powodów jest to, że domyślna wartość przypisana przez kompilator może nie być pożądaną wartością, lub gorsze, niepoprawne (które kompilator powinien złapać).

Q2) Zakładając powyższą część, jakie jest znaczenie get; zestaw; nieruchomości?

A2) Oprócz faktu, że są łatwe i bardziej eleganckie, że równoważnik metody, właściwości mogą być używane w dowolnym czasie w klasie (oczywiście), mogą być używane jako proste zadania lub zawierać dodatkowy kod (ktoś już to stwierdził do sprawdzania poprawności informacji), a ostatecznie dane są samodzielne w klasie, a zatem łatwiejsze do debugowania.

Wszystko to jest powiedziane, możesz mieć doskonały powód do robienia rzeczy inaczej niż to, co mówi książka lub ktoś inny. Zawsze są akceptacje "reguły (reguł)" i powinieneś odpowiednio kodować.

Powiązane problemy