Summary :

  • 캡슐화란 ? 속성에 접근지시자적용, 해당 속성을 사용하는 함수를 같은 클래스내에서 만듦
  • 데이터의 변화가 외부파일에서 오류를 발생 -> 데이터사용하는 함수를 데이터와 같은 클래스에 둔다
  • 캡슐화를 했지만 데이터를 외부에서 쓴다면 ? 캡슐이 깨진다. ->막으려면 ? -> 접근지시자 사용
  • 접근제어자 : 외부에서 데이터를 볼수 없게하는것 
  • print함수를 분리한 이유: Lotto{}에 포함할 경우 콘솔용이 되어버린다.
  • 함수: static / 객체지향에서 사용하는 함수 : 메소드

 

함수는 원래 외부변화에 영향을 받지 않아야한다.

하지만 다른 클래스에서 데이터계층lotto.nums[i]을 사용할때 문제가 발생한다. 

속성을 정의하는 쪽(Ellipse{ })과 사용하는 사람(main메소드())이 다른경우 :

1. 속성을 간접적으로 쓰기위해 속성과 연관된 함수를 호출. 

2. main에서 속성을 따로만들어도 Ellipse{}클래스안에서 만들어달라고 부탁하는것 

 

도형을 담당하는 데이터가 있다고 가정해보자. 다양한 정수를 Ellipse{ }라고 묶어서 데이터를 개념화시킨다. 데이터를 파악하는게 용이하다.

 

Ellipse{ }안의 속성을 마음대로 쓰는것에 주의해야한다.

직접 사용한다면 각 x,y,w,h를 누가, 어느코드에서 ,몇개를 사용하는지 파악하기가 힘들어진다. → 어느코드에서 오류가 발생하는지 파악하기 힘들다.

 

Ellipse{ }안의 속성(int x,y,w,h)을 쓰는것이 모두 Ellipse{ }안에 있다면 속성명이 변경되는 경우 오류의 범위가 Ellipse{ }안으로 한정된다. 외부에서 속성을 직접사용하는것이 없어진다.

 

Ellipse{ } : 데이터구조를 정의하고있는것, 함수를 모아둘 수 있는 울타리역할→클래스

 

캡슐 : 데이터구조와 함수를 하나로 모아둔것

캡슐화 : 캡슐을 만드는 과정 (함수가 외부영향에 받지않도록 최소화) ↔캡슐이 깨지다.(캡슐밖에서 사용되는경우)

데이터 속성과 데이터를 직접쓰는 함수를 묶는것.

 

캡슐을 깨지못하게 하는 도구 : 접근 제어 지시자

외부에서 아예 접근못하도록 막을 수있다.

protected 자식에게만 접근허락.

private int[] nums ; 

캡슐화 실습

  • main()함수에있을때는 lotto.nums에 에러가 발생한다. int[] nums가 private처리되어 다른클래스에서 접근이 불가능하기 때문이다. 
  • main()함수에 있던 gen()와 sort()함수를 Lotto{}클래스 안에 넣었다. lotto.nums[] 오류가 사라진다.
  • 속성에 접근지시자적용, 해당 속성을 사용하는 함수를 같은 클래스내에서 만듦

 

 

 

print()함수를 Lotto{}에 포함하지않은 이유 ? 

사용자에게 보여줄 수 있는 옵션들 : 콘솔출력 / 윈도우 출력 / 웹 출력/ VR

print()함수를 Lotto에 포함하면 콘솔용 프로그램이 된다. 특정UI로 종속되어버린다.

 

Lotto{}클래스에는 입력버퍼가없다. ->데이터입력이 없다.

배열[]인 메모리할당을 한다. 

사용자에게 입력을 받거나 파일에서 읽어들이는 버퍼가 없다.

 

private int[] nums ; 외부접근막았으니 

getNum(Lotto lotto, int i): Lotto클래스의 정수를 하나씩 꺼내줄 수 있는 함수를 만든다.

외부에서는 Lotto.getNum() 함수를 통해 int[] nums에 담긴 값을 불러온다. (클래스명.함수명으로 호출)


Getter함수(값을 얻어오는 함수 Getter, 값을 적용하는 함수Setter)

외부에있는 print()함수에서 int[] nums에있는 숫자를 가져오기위한 함수getNum()를 Lotto클래스에 만든다.

외부클래스에서는 Lotto.getNum()을 통해 숫자를 가져온다.

 

Program 클래스

getNum[]함수는 lotto가 가지고있는 데이터중에서 i번째 숫자를 반환해주는 역할

함수가 해야할 일을 Lotto{}클래스에서 만들어준다.

 

lotto라는 객체,실체,인스턴스를 공유한다

Lotto{}클래스의 nums명을 바꿔도 Lotto클래스안에서만 오류가 발생한다.

int[] nums변수명 변겨시 Lotto클래스에서만 에러발생

초기화함수 static void init()

main()에서 Lotto.init();호출하고 

nums배열 초기화(lotto.nums = new int[6];를)하는 init()메소드를 Lotto클래스에서 만든다.

Pritn()함수가 밖에 있기때문에 size에 직접 접근할 수없고 getSize()함수를 통해 가져온다.

Lotto.getSize()

Program클래스

package ex6.캡슐화.로또;

import java.util.Random;

public class Program {
	
	// 로또를 출력하자
	private static void print(Lotto lotto) {
		//밖에있으니까 캡슐깨지않고 함수를통해얻어야함
		for (int i = 0; i < Lotto.getSize(lotto); i++) {
			System.out.printf("%d", Lotto.getNum(lotto, i));
			if (i < 5)
				System.out.printf(",");
		}
		System.out.println();
	}

	public static void main(String[] args) {// 어플리케이션역할
		//lotto객체를 생성.기존gen()함수에서 분리함 : gen()함수는 숫자만생성하도록
		Lotto lotto = new Lotto();

		//lotto.nums = new int[6];
		Lotto.init(lotto);			
		
		//int[] lotto;

		lotto = Lotto.gen(lotto);//Lotto의 인스턴스(객체,실체)를 만드는 함수

		print(lotto);
		
		Lotto.sort(lotto);

		print(lotto);
		
	}// main메소드 끝

}
package ex6.캡슐화.로또;

import java.util.Random;

//재사용
public class Lotto {
	private int[] nums; // Lotto의 청사진,단순 정의,
	private int size;

	public static int getNum(Lotto lotto, int i) {
		int num = lotto.nums[i];
		return num;
	}
	public static void init(Lotto lotto) {
		lotto.size = 6;
		lotto.nums = new int[lotto.size];
	}

	public static int getSize(Lotto lotto) {
		return lotto.size;
	}

	public int getSize() {
		return size;
	}


	static Lotto gen(Lotto lotto) {
//		Lotto lotto = new Lotto(); // 4바이트
//		lotto.nums = new int[6]; // 배열의 공간생성
		Random rand = new Random();
		for (int i = 0; i < 6; i++) {
			lotto.nums[i] = rand.nextInt(45) + 1;
		}
		// 자판기
		return lotto;
	}// gen()끝

	public static void sort(Lotto lotto) {

		for (int j = 0; j < lotto.size - 1; j++) {
			for (int i = 0; i < lotto.size - 1 - j; i++) {
				int compare;
				if (lotto.nums[i] > lotto.nums[i + 1]) {
					compare = lotto.nums[i];
					lotto.nums[i] = lotto.nums[i + 1];
					lotto.nums[i + 1] = compare;
				}
			}
		}
	}// sort()끝

}

+ Recent posts