// Lecture19 -- encapsulation

/*
+ why everything public so far?
  - information hiding for good style
    (move information far away from user)
  - Why?
    - security
    - reliability of code
    - ease of reuse
    - use $public$ (and default visibility) and $private$
    
+ $private$
  - prevents another class from using a the "." operator to call
    a var or method
  - provides protection
 

    +--------+
    |  bank  | --->  A transacts
    |  ($$)  | <---
    +--------+
        ^|    , \
        ||     \ \
        |V      \ \,
                 \  get
       B        set
   transacts


  - prevent A and B from drawing $$ simultaneously by
    managing band account (instance variable) with setters and getters
    (public methods)

+ terminology for the stuff above:
  - encapsulation
  - information hiding

+ how to modify classes? (style)
  - make hidden things $private$:
    - instance variables
    - UTILITY METHODS: methods used only in class
  - make public things $public$ (or default visibility)
    - static variables (also called CLASS VARIABLES)
    - setters and getters: methods that set and get info from instance
      variables and utility methods

+ How to access?
  - from WITHIN the same object, all members (inst vars and meths) can "see" 
    eachother
  - from another object of the same class, you may use dot operator to access
    any member even if it's private
  - from another class (or object from another class):
    - anything labeled as $private$ cannot be accessed with the dot operator
    - use setter and getter methods to communicate with the object
    - also, use constructors to set initial information
      (constructors are typically public)

*/

class Person {
    private String name;       // name of current Person
    private Person friend;     // friend of current Person is also a Person

    // constructor
    // use constructors to set IVs usually, but can do even more!
    public Person(String n) {
	name=n;
    } 

    // method for setting value of $friend$:
    public void set_friend(Person p) {
	friend = p;
    }

    // using $toString$ to print description of current object:
    public String toString() {
	return "Name of person: "+name+"; Name of friend: "+friend.name;
    }
}

public class lecture19_encaps {
    public static void main(String[] args) {
	
	// create 4 new people:
	   Person a = new Person("Dave");
	   Person b = new Person("Jeff");
	   Person c = new Person("Nate");
	   Person d = new Person("Tony");

	// Ira's friend is Jeff
	   a.set_friend(b);

        // Description of Ira:
	   System.out.println("Part 1:");
	   System.out.println(a);

        // Creating objects as inputs and return values:
	   System.out.println("Part 2:");
	   b.set_friend(new Person("Alan"));
	   System.out.println(b);

        // Aliases
        // if you assign a reference to an object to another reference
        // an object gets obliterated...which one?

	   c = d; 
	   System.out.println("Part 3:");
	   c.set_friend(b);
           System.out.println(a);
           System.out.println(b);
	   System.out.println(c);
           System.out.println(d);
    }
    
}

/* output:
Part 1:
Name of person: Dave; Name of friend: Jeff
Part 2:
Name of person: Jeff; Name of friend: Alan
Part 3:
Name of person: Dave; Name of friend: Jeff
Name of person: Jeff; Name of friend: Alan
Name of person: Tony; Name of friend: Jeff
Name of person: Tony; Name of friend: Jeff
*/



