Search code examples
javaoopinstance-variables

When is it appropriate to assign values to an instance variable in Java?


This is a question on best practice. When taking an object oriented approach, I've come up with three different ways that I might do the same thing. To my untrained eye, none of them seem "wrong", but I know every language and style has its best practices, and I want to know if any of these three ways violate some "best practice" that I haven't learned yet.

Way 1: (declare, then assign in constructor)

public class CCipher {

    private String alphabet;
    private String shiftedAlphabet;
    private int mainKey;

    public CCipher(int key){

        mainKey = key;
        alphabet = "abcdefghijklmnopqrstuvwxyz";
        shiftedAlphabet = alphabet.substring(mainKey) 
                        + alphabet.substring(0, mainKey);
    }

Way 2: (declare and assign at the same time)

public class CCipher {

    private String alphabet = "abcdefghijklmnopqrstuvwxyz";
    private String shiftedAlphabet;
    private int mainKey;

    public CCipher(int key){

        mainKey = key;
        shiftedAlphabet = alphabet.substring(mainKey) 
                        + alphabet.substring(0, mainKey);
    }

Way 3: (Some things get initialized in a non get/set method)

public class CCipher {

    private String alphabet;
    private String shiftedAlphabet;
    private int mainKey;

    public CCipher(int key){

        mainKey = key;
        alphabet = "abcdefghijklmnopqrstuvwxyz";

    }

    public String encrypt(String input){
        shiftedAlphabet = alphabet.substring(mainKey) 
                        + alphabet.substring(0, mainKey);
        // ... code to encrypt input ...
    }

    public String decrypt(String input){
        shiftedAlphabet = alphabet.substring(26 - mainKey) 
                + alphabet.substring(0, 26 - mainKey);
        // ... code to decrypt input
    }
}

Personally, for this specific homework assignment, I really like the third way best, because it flows with the logic of the problem I'm trying to solve. But it it's wrong, well it's wrong...


Solution

  • The second version seems okay. But with the constant indeed as static final String.

    public class CCipher {
    
        private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
        private final String shiftedAlphabet;
        private final int mainKey;
    
        public CCipher(int key) {
            mainKey = key;
            shiftedAlphabet = ALPHABET.substring(mainKey) 
                            + ALPHABET.substring(0, mainKey);
        }
    

    Christopher Schneider pointed out that in for encrypting and decrypting different shiftedAlphabets are used. As a CCipher object in reality probably either encrypts or decrypts, make it a local variable.

    One would need two different non-final lazily initialized fields which is cumbersome.

    public class CCipher {
    
        private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
        //private final String shiftedEncryptAlphabet;
        //private final String shiftedDecryptAlphabet;
        private final int mainKey;
    
        public CCipher(int key) {
            mainKey = key;
            shiftedAlphabet = ALPHABET.substring(mainKey) 
                            + ALPHABET.substring(0, mainKey);
        }
    
        public String encrypt(String input){
            String shiftedAlphabet = alphabet.substring(mainKey) 
                        + alphabet.substring(0, mainKey);
            // ... code to encrypt input ...
        }
    
        public String decrypt(String input){
            String shiftedAlphabet = alphabet.substring(26 - mainKey) 
                + alphabet.substring(0, 26 - mainKey);
            // ... code to decrypt input
        }