KB IT’s Your Life 4기 - Java 3일차


클래스의 4가지 스타일(종류)

  1. VO(Value Object), DTO(Data Transfer Object) : 데이터 저장용
부서: 영업부, 이름:김길동, 직급: 대리 > 하나의 클래스
부서: 개발부, 이름:박길동, 직급: 대리 > 하나의 클래스
  1. Manager, Dao : VO에 대한 관리 기능(CRUD; Create Read Update Delete)
  2. UI : 입출력 인터페이스(GUI, CUI, WebUI)
  3. IO : 데이터 입출력 담당, DB; Get, Post

이 역할로 클래스를 나눌 것!!!!!!!!!!!!!!!!!!

객체 생성 과정

Person p1 = new Person();

  1. Person 클래스 로딩
  2. 힙에 메모리 할당 (객체생성)
  3. 필드에 기본 초기값 할당
  4. 명시적 초기값 할당
  5. 생성자 실행

접근 지정자

image

싱글톤 패턴에서는 객체를 1개만 만들기 때문에 생성자에 private 생성자를 이용한다.

자바 공부 심화 (도서)

  1. 이펙티브 자바
  2. 리팩토링
  3. 디자인패턴
  4. 엔터프라이즈 디자인패턴

생성자 오버로딩 규칙

  1. 이름 동일
  2. 매개변수 다름 (타입 또는 순서, 개수)
    • 매개변수 이름은 무관 : 이름만 바꾸면 오류 발생. 타입과 개수, 순서가 다른것!!!!!!!!!!!!!

클래스와 오브젝트

  • Class는 Object의 Template이고,
  • Object는 Class의 Instance이다.

  • Instance를 통틀어서 Object라고 일컫음. (거의 동의어임)

Person 클래스

package day_03;

public class Person {
	// String은 null로 초기화
	String name = "냥냥"; // 필드 (객체 생성시 자동 초기화 및 객체 영역에 생성)
	int age;

	// 생성자가 아무것도 존재하지 않는 경우, 기본 생성자를 컴파일러가 자동으로 추가함
	// 이름이 같고 파라미터가 다른 생성자들 여러개 : 오버로딩
	public Person() {
	}

	// 기본 생성자 ctrl + space
	public Person(String name, int age) { // public을 쓰지 않아도 OK
		this.name = name; // 파라미터를 String n으로 넣고 name = n 과 같이 사용해도 되지만, 동일한 이름을 사용하는 것이 가독성에 좋음.
		this.age = age; // this는 내장 필드로 객체마다 가지고 있는 것이다. this는 stack영역에서 heap을 가리키고 있는 시작 주소값을 의미한다.
	}

	public Person(int age, String name) { // public을 쓰지 않아도 OK
		this(name, age); // 이 this는 public Person(String name, int age) 를 의미한다.
        // this(age,name); 이 this는 현재 함수인 public Person(int age, String name) 를 호출하고, 재귀호출로 무한 반복하기 때문에 오류가 발생한다.
		System.out.println(123); //생성자 호출에서 this는 무조건 첫번째 문장이어야한다. 그러므로 println을 위로 올리면 오류 발생.
	}

	
	/** 내부 변수값을 출력 */
	public void printInfo() {
		System.out.println("name: "+name +", age: "+ age); // 로컬 변수 -> 멤버 변수 순으로 검색
		//System.out.println("name: "+this.name +", age: "+ this.age); // 붙여도 돼.
	}
}

package day_03;

public class PersonExam {
	public static void main(String[] args) {
		Person p1 = new Person("김길동", 40); //변수선언 (지역변수, stack영역-메서드 코드 실행시, 메서드 종료시 삭제)
		//값 바꾸기	
		p1.name = "홍길동";
		p1.age = 30;
		
		p1.printInfo(); // 매서드 호출
		System.out.println(p1.name);
		System.out.println(p1.age);

		//객체 생성시 바로 초기화하기 위해 생성자 메소드 등장
		Person p2 = new Person("강길동", 40);
		System.out.println(p2.name);
		System.out.println(p2.age);
		
		Person p3 = new Person();
		System.out.print(p3.name);
	}
}

Person2 클래스

package day_03;

public class Person2 {

	 String name;
	 int age;

	//3. 여기서 빨간줄에서 create all 클릭.
	public Person2(String name, int age) {
		this.name = name;
		this.age = age;
	}

}

package day_03;

/**
 * 개발자 툴 잘 이용하기
 * */
public class PersonExam2 {
	public static void main(String[] args) {
		// 만들고, 빨간줄에서 자동으로 만들기 누름.
		// 1. 보통 이 main함수를 먼저 작성하고 class명 빨간줄에 create class 'Person' > Finish
		// 2. 파라미터 빨간줄에 create construct 선택
		Person2 p1 = new Person2("김길동", 40); // 변수선언 (지역변수, stack영역-메서드 코드 실행시, 메서드 종료시 삭제)
		// 값 바꾸기
		p1.name = "홍길동";
		p1.age = 30;

		System.out.println(p1.name);
		System.out.println(p1.age);

	}
}

static 메서드

static 메서드는 static 변수만 직접 접근가능하다.

class A{ static int i = 0 ; int b = 0;

static void a(){ i++; b++; //구문 오류 발생 } } static 메서드는 non-static변수는 직접접근 불가하다.

이유: static의 경우, Method 영역 안에 A.i=0이 들어가고 A.a()가 존재한다 non-static인 경우, Method영역 안에 A.a()가 존재한다. i는 A의 객체가 생성한 뒤에야 heap공간에 A.i = 0 이 생성된다.

즉, 완전히 다른 메모리 공간에 만들어짐.


  Method    heap   stack
-------------------------
ㅣ      ㅣ       ㅣ     ㅣ
ㅣstaticㅣ       ㅣ     ㅣ
ㅣ      ㅣ       ㅣ     ㅣ
ㅣ      ㅣ객체변수ㅣ     ㅣ
ㅣ      ㅣ       ㅣ     ㅣ
ㅣ      ㅣ       ㅣ     ㅣ
-------------------------

static 함수에서 non-static 변수를 그래도 사용하고 싶을 때?

int price;

satic public void prn(){
   Product p1 = new Product("11", "11", "11", 11);
   p1.price = 200;
}

static과 non-static은 선언만 같이 되어있지 메모리 공간이 아예 다르다. Method만 독립적으로 선언이 불가능해서 같이 선언되어있는 것이다.

static은 독립적인 역할+기능을 할 때 많이 사용한다.

random, 삼각함수, 로그 등

Product

package day_03;

/** 상품 기본 정보 정의용 클래스 */
public class Product {
//객체 소속으로 heap영역 *******객체 생성 후 사용 가능!!!!!! Product p2 = new Product(); 가 필요. Product p3 = null이면 오류 발생
	String code; // 상품코드
	String name; // 상품이름
	String company; // 제조사
	int price; // 상품가격

//클래스 소속으로 호출할 때, 클래스 이름  Project.count로 사용 가능. Method 영역에 들어감. main실행 전 Method 영역에 자리를 잡고 준비함. 
	//객체를 만든 이후에는 객체를 통해서도 사용이 가능하지만, 비추천.
	//static은 하나만 만듦.
	static int count = 0;

//생성자 만들기 : source >> Generate Constructor using Fields(멤버변수) 
	public Product(String code, String name, String company, int price) {
		super();
		this.code = code;
		this.name = name;
		this.company = company;
		this.price = price;
		count++;
	}

	public void printInfo() {
		System.out.println("code=" + code + " name=" + name + " company=" + company + " price=" + price);

	}
}

package day_03;

public class ProductExam {
	public static void main(String[] args) {
		// 객체 만들기 : new + ctrl + space -> ctrl + 1 + enter
		Product p1 = new Product("a100", "냉장고", "삼성", 100);
		p1.printInfo();
		//static은 객체를 만든 이후에는 객체를 통해서도 사용이 가능하지만, 비추천.
		//\p1.count++;
		System.out.println(Product.count);

		Product p2 = new Product("a100", "냉장고", "삼성", 100);
		System.out.println(Product.count);
	}
}

static

package day_03;

public class staticExam {
	int age = 0;
	public static void main(String[] args) {
		//Math의 모든 멤버가 static임. 즉, 객체를 만들 필요가 없다.
		Math.random();
		
		//static으로 선언되어있지 않은 age에 접근 방법
		new staticExam().age = 199;
		
		//static 함수 안에서 static 사용가능
		test1();
	}
	static void test1() {
		//this(); => static 내부에서는 this 사용 불가. static은 Method 영역이기 때문에 전혀 상관없는 것.
		
	}
}

getter setter (private class 멤버변수)

캡슐화(=정보은닉)

package day_03;

public class MyInfo {
	private int age;
    int age2; //접근제한자 생략시 default라고 칭함.
    
    //getter, setter 한 번에 만드는 방법 > source > generate getters ans setters 클릭
    public int getAge() {
    	//getter
    	return this.age;
    }
    public void setAge(int age) {
    	//setter
    	this.age = age;
    }
    
    
}

package day_03;

public class MyInfoExam {
	public static void main(String[] args) {
		MyInfo mi = new MyInfo();
		// mi.age = 100; private은 클래스가 달라지면 접근 불가이기 때문에, 오류발생
		mi.age2 = 100; //default 같은 패키지 내 다른 클래스 접근 가능.
		
	}
}

객체 배열

package day_03;

/** 회원 정보 정의 클래스 */
public class MyMember {
	//변수 정의
	private String name;
	private int age;
	private String tel;
	
	///생성자 (보통 (1)기본 생성자 (2)모든 변수를 매개변수로 받는 생성자를 만듦.)
	public MyMember() {

	}

	public MyMember(String name, int age, String tel) {
		super();
		this.setName(name);
		this.age = age;
		this.tel = tel;
	}

	//getter, setter 
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getTel() {
		return tel;
	}

	public void setTel(String tel) {
		this.tel = tel;
	}


	//디버깅용; 현재 객체의 변수값을 문자열로 반환하는 메서드 toString
	@Override
	public String toString() {
		return "MyMember [name=" + name + ", age=" + age + ", tel=" + tel + "]";
	}
	
}



package day_03;

public class 회원관리 {
	public static void main(String[] args) {
//		MyMember m1 = new MyMember("홍길동", 33, "111-222");
//		MyMember m2 = new MyMember("김길동", 35, "111-333");

		// new 연산자를 이용해서 객체를 생성한다. heap에 size가 3인 배열 객체 1개 생성.
		MyMember[] mems = new MyMember[3];
		// 배열은 null로 초기화 되어있음.
		System.out.println(mems[0]); // null
		System.out.println(mems[1]); // null
		System.out.println(mems[2]); // null

		mems[0] = new MyMember("홍길동", 33, "111-222");
		System.out.println(mems[0].toString());

	}
}