// CS100J Spring 2001
// Lecture 12, 3/1
// encapsultation

/*

+ 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)

*/

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 name) {
	this.name=name;
    } 
    
    // hold on! What's $this$? A reference (and sometimes method) to allow
    // you to distinguish between the local var and the instance var
    // $this.name$ means the instance var
    // $name$ means the local var
    
    // 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 lecture12_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");
	
	// Dave's friend is Jeff
	a.set_friend(b);
	
	// Description of Dave:
	System.out.println("Part 1:");
	System.out.println(a.toString()); // should ditch this!
	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.toString());
	
        // Aliases
	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
*/