11
\$\begingroup\$

I coded a simple program that asks the user to add/delete/modify/print/etc. their contact list names. Now, I had learned a little about encapsulation. However, I still could not figure out which methods to set to private and which ones to public. Plus, in this part of the MobilePhone class,

public static void menu() {
    boolean quit = false;
    int choice = 0;
    while (!quit) {
        System.out.println("Enter your choice:");
        choice = scanner.nextInt();
        scanner.nextLine();
        //switch case...

The program did not work without the scanner.nextLine(); part. What is the point of it? Is it because I left scanner as an Integer input before that by typing choice = scanner.nextInt();?

And also, if there are any other things you would like to mention about the program or the mistakes, I am open to criticism.

import java.util.Scanner;


public class MobilePhone {
private static Scanner scanner = new Scanner(System.in);
private static Contacts contactsList = new Contacts();

public static void main(String[] args) {
    instructions();
    menu();

}

public static void menu() {
    boolean quit = false;
    int choice = 0;
    while (!quit) {
        System.out.println("Enter your choice:");
        choice = scanner.nextInt();
        scanner.nextLine();
        switch (choice) {
            case 0:
                instructions();
            case 1:
                quit = true;
                break;
            case 2:
                contactsList.printContacts();
                break;
            case 3:
                addContact();
                break;
            case 4:
                updateContact();
                break;
            case 5:
                removeContact();
                break;
            case 6:
                searchContact();
                break;
            default:
                break;
        }
    }

}

public static void addContact() {
    System.out.println("Enter the name of the new contact");
    String newContact = scanner.nextLine();
    contactsList.addNewContact(newContact);
}

public static void updateContact() {
    System.out.println("Enter the name of the contact that you want to replace");
    String replacedName = scanner.nextLine();
    System.out.println("Enter the updated name");
    String newName = scanner.nextLine();
    contactsList.updateContact(replacedName, newName);
}

public static void removeContact() {
    System.out.println("Which contact do you wish to remove?");
    String removedContact = scanner.nextLine();
    contactsList.removeContact(removedContact);
}

public static void searchContact() {
    System.out.println("Which contact are you looking for?");
    String contactName = scanner.nextLine();
    int index = contactsList.findContact(contactName);
    if (index >= 0) {
        System.out.println(contactsList.findContact(contactName) + 1 + ") " + contactName);
    } else {
        System.out.println("No such contact found.");
    }
}

public static void instructions() {
    System.out.println("1)Quit\n2)List of contacts\n3)Add new contact\n4}Update existing contact\n5}Remove contact\n6)Search/Find contact");

}
}

And the Contacts Class:

import java.util.ArrayList;


public class Contacts {
private ArrayList<String> contactsList = new ArrayList<>();

public void printContacts() {
    System.out.println("You have " + contactsList.size() + " contacts.");
    for (int i = 0; i < contactsList.size(); i++) {
        System.out.println((i + 1) + ". " + contactsList.get(i));
    }
}

public void addNewContact(String contact) {
    contactsList.add(contact);
}

public void removeContact(String contact) {
    int index = findContact(contact);
    if (index >= 0) {
        deleteContact(index);
    } else {
        System.out.println("No such contact found");
    }
}

public void updateContact(String replacedContact, String newContact) {
    int index = findContact(replacedContact);
    if (index >= 0) {
        contactsList.set(findContact(replacedContact), newContact);
    } else {
        System.out.println("No such contact found to update");
    }
}

public int findContact(String contact) {
    return contactsList.indexOf(contact);
}

private void deleteContact(int index) {
    contactsList.remove(index);
}


public ArrayList<String> getContactsList() {
    return contactsList;
}
}
\$\endgroup\$
11
\$\begingroup\$

Encapsulation is :

A language mechanism for restricting direct access to some of the object's components. A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.

From wikipedia.

In other words, you don't need to put any method to private to have encapsulaiton and, in fact, you don't even need objects. You can do encapsulation in C just fine as long as you hide struct data manipulation inside functions.

For example, the following code :

class Person {
     // some fields...
     private final LocalDate birthday;

     public int getAge() {
         // return the diff between now and birthday
     }

have proper encapsulation because how the age is stored and how the birthday is manipulated are hidden from the user of the object.


public ArrayList<String> getContactsList() {
    return contactsList;
}

You shouldn't return your contactsList as an ArrayList directly because it breaks encapsulation. Generally speaking, user of Contacts objects shouldn't :

  • care of in what types you are storing your contact list so you can return the list as one of the supertype (List or even Collection depending on the contracts, IMO Collection is fine)

  • be able to modify your fields directly since you are already giving them other methods to work with your contact list, so you should either remove this method completely or return an unmodifiable object

In the end, this method would be removed or be replaced by this :

public Collection<String> getContacts() {
    return Collections.unmodifiableCollection(contactsList);
}

Otherwise, your Contacts class is fine but you should avoid printing to System.out directly as Contacts is purely a "Model" object. For example, your printContacts could be modified as returning a String and another object would be responsible for the printing.

\$\endgroup\$
  • \$\begingroup\$ Very insightful. Much appreciated \$\endgroup\$ – Huzo Jun 6 '17 at 9:42
7
\$\begingroup\$

scanner.nextInt() only scans for the next integer in your input buffer. For example if you type in 123abc[enter] it only receives the 123 part and leave the rest(abc[enter]) in the buffer. Therefore you must add scanner.nextLine() to clear out the input buffer.

\$\endgroup\$
2
\$\begingroup\$

It's a small point but it can make a difference when coming back in future and looking at the code but try to be more consistent with your indentation and general code cleanliness. The contents of your classes aren't indented at the moment and you have a couple of unnecessary new-lines at the bottom of the main, menu and instructions methods. Aside from that you've been consistent with the casing of method names and using your braces on the same line (I want to recommend new line braces but that's mostly just personal preference).

Something debatable is whether you need the deleteContact method. It's only called once and that's inside the removeContact method. While only the removeContact method is public so from a public interface perspective it's OK, if I were reading the implementation I might be confused as to why there are two similarly named functions and what the semantic difference between remove and delete is. In this case I don't think the deleteContact method adds much because I wouldn't be confused to find the line contacts.remove(index) in a removeContacts function. There's more discussion on single usage private methods here.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.