TIL-4주차 코드

 

1. 객체지향 시작 : 22.12.19

  • 우리는 일단 용어보다는 필요성에 꽂혀야 한다.


1) [함수의 필요성]

  • 집중화, 코드를 잘라서 사용, 코드의 재사용, 구현 코드 숨김 가능


2) [구조체]

  • 구조체 :데이터들을 구조화 해서 만드는 것

  • 데이터를 구조화하지 않았을 때 생기는 이유
    • 변수명의 충돌상황을 모면할 수 있다,
    • 우리는 공통분모의 내용 주석을 달아야 하는데 의미를 공통화하여 부여할 수 있다.
  • 그래서, 우리는 데이터는 구조화를 만들어 왔다.


3) [객체지향이 나온 이유]

  • 기존의 함수를 나누는 기준이 명확하지 않다.

  • 함수의 고립화를 무너트린다.(??) : 외부에서 문제가 발생한것이 영향을 끼침!!


4) [캡슐화]

  • 함수들을 모아두는 것이 캡슐화의 동기를 만들었다. 그냥 함수들을 모아두는 것은 캡슐화가 아니다.


5) [객체지향 프로그래밍(OOP)]

  • 개발자의 자세 : 기획!!!, 설계, 건축, 유지 관리
  • 객체지향은 우리가 말한대로 만들어지는 프로그램이다.
  • 즉, 행위, 대상, 주체가 있다.(오목 게임 생각)


6) [객체지향 프로그래밍(OOP) - 예시]

  • 우리는 구조를 만들때, 인문학적인 생각이 가장 중요하다. ( ex) 그림보고 객체-행위 생각해보기 )
  • 하지만, 행위를 하지 않으면 객체가 아니다. ( ex) 그림에서 달, 구름, 나무 등등 )
  • 즉, 객체 지향에서 객체는 무조건 행위여야 한다!!!
  • ex) 개체는 메뉴판의 자장면, 객체는 메뉴를 주문 후 실제로 만들어진 자장면이다.


7) [객체의 속성]

  • 자바에서는 객체를 “Class”라고 부른다. 객체의 속성은 중요하다.( ex) 비행기의 위치 상태값과 같다.)


8) [객체지향의 목적]

  • 우리의 머릿속에 있는 것을 그대로 표현할 줄 알아야 한다.

  • 이제는 객체 지향에서 함수처럼 코드를 잘라내는 것이 아니라 접근 방법이고 역할이라서 “메서드”라고한다.

  • 기존의 방식처럼은 실세계에서 만들어지는 방식과 달라서 메서드 방식처럼 우리가 사고하는 그 방식 그대로 사용한다.


printExam(exam);	// 기존 방식(함수)

exam1.input();    // 새로운 방식(메서드)

  • 객체지향은 기존의 방식에서 표현식이 바뀐다.
package ex5.capsule;

public class Exam {
	int kor;
	int eng;
	int math;
	
	public void input() {
		
	}
	public void print() {
		int kor = this.kor;
		int eng = this.eng;
		int math = this.math;
		
		System.out.printf("kor: %d\n", kor);
		System.out.printf("eng: %d\n", eng);
		System.out.printf("math: %d\n", math);
		System.out.printf("-----------------------\n\n");
	}	
}

}
package ex5.capsule;

public class CapsuleTest {

	public static void main(String[] args) {
		
		//성적 객체를 준비한다.
		//실제 뉴렉 = new 성적();
		Exam exam1 = new Exam();
		
		// 성적을 입력받는다.
		// =>뉴렉 성적.입력();
		inputExam(exam1);
		exam1.input();
		
		
		// 성적을 출력한다.
		// =>뉴렉 성적.출력;
		printExam(exam1);						// 이전 방식!!
		
		exam1.print();							// 새로운 방식!! : 객체나 실체나 인스턴스에다가 이 객체(exam1)가 print()를 넘겨 받는다.
											// 정리: 우리는 인스턴스에 print() 메서드를 붙여주므로 인스턴스 메서드라고 부른다.
	}

	private static void inputExam(Exam exam1) {	// static을 써주는 이유는 인스턴스 메서드와 구별해주기 위해서 static을 써준다.
		
	}

	private static void printExam(Exam exam1) {	
		int kor = 30;
		int eng = 20 ;
		int math = 10;
		
		System.out.printf("kor: %d\n", kor);
		System.out.printf("eng: %d\n", eng);
		System.out.printf("math: %d\n", math);
		System.out.printf("-----------------------\n\n");
	}

}

	}

}


9) [인스턴스 메서드]

package ex5.capsule;

public class Exam {
	int kor;
	int eng;
	int math;
	
	public void input() {
		
	}
	public void print() {
		int kor = this.kor;
		int eng = this.eng;
		int math = this.math;
		
		System.out.printf("kor: %d\n", this.kor);
		System.out.printf("eng: %d\n", this.eng);
		System.out.printf("math: %d\n", this.math);
		System.out.printf("-----------------------\n\n");
	}	
}

}
  • 특징
    • 인스턴스 메서드는 넘겨 받는 값이 없다. 또한, this 객체를 사용한다.
    • 먼저, 지역변수를 찾아보고 / 넘겨받고 this의 객체를 찾아서 그안의 속성에 kor이 있는지 확인한다.
    • 우선 순위(중요!!) : 지역 변수 > this 변수
    • this.kor에서 this는 되도록 안 쓰는 것이 좋다. 하지만, 지역변수가 있어서 우선 순위에 밀리는 경우에는 this를 꼭 써주어야 한다.


10) [캡슐의 의미]

  • 내가 만든 함수는 꼭 그 구조안에 들어가야 한다.
  • static 함수는 만들어지는 위치가 정해져 있지 않다.
  • 코드의 캡슐화를 위해서 요소들을 뽑아서 쓰지말아야 한다.
  • 은닉성 : 캡슐화를 위해서 은닉성을 지켜주어야 한다!!! 캡슐 밖에서는 캡슐안의 코드를 사용할 수 없게 해야 한다.(외부에서 영향을 주면, 에러가 발생한다.)
    • 캡슐화를 위해 private으로 작성한다. public은 반대 개념!!
  • 추가적으로, 변수 초기화 함수를 위해 .init() 함수를 만들자!


11) [init() 함수]

public class Exam {
	private int kor;
	private int eng;
	private int math;
	
	public void init() {	// init은 초기화가 아니라 reset에 가깝다..
						// init 함수는 객체가 만들어지자 마자 제일 먼저 실행되어야 한다.
		int kor = 30;
		int eng = 40;
		int math = 50;
	}
}
}

public class CapsuleTest {

	public static void main(String[] args) {
		
		//성적 객체를 준비한다.
		//실제 뉴렉 = new 성적();
		Exam exam1 = new Exam();
		exam1.init();
		}
|
  • init은 초기화가 아니라 reset에 가깝다.
  • init 함수는 객체가 만들어지자 마자 제일 먼저 실행되어야 한다.
  • new Exam();에서 new Exam을 “()”로 넘겨주는 것이다. “()”는 이름이 없고 갓 생성된 한번도 쓴적이 없는 함수다.


12) [생성자]

  • 원래는 생성자는 이름이 없다.(생성자 함수라고 쓰면 안된다.)
	public ?() {
		int kor = 30;
		int eng = 40;
		int math = 50;
	}
  • 이름 생성을 다음과 같이 생성해주면, Exam() 형식만 생성자를 호출 할 수 있다.(한정사 느낌)
	public Exam() {
		int kor = 30;
		int eng = 40;
		int math = 50;
	}



22.12.19 실습 코드

package ex5.capsule;


public class CapsuleTest {

	public static void main(String[] args) {
		
		//성적 객체를 준비한다.
		//실제 뉴렉 = new 성적();
		Exam exam1 = new Exam();
		//exam1.init();
		
		
		// 성적을 입력받는다.
		// =>뉴렉 성적.입력();
		Exam.inputExam(exam1);
		exam1.input();
		
		
		// 성적을 출력한다.
		// =>뉴렉 성적.출력;
		Exam.printExam(exam1);		// 이전 방식!!
		
		exam1.print();				// 새로운 방식!! : 객체나 실체나 인스턴스의 개념인 객체(exam1)가 메서드(print())를 넘겨 받는다.
								// 정리: 우리는 인스턴스에 print() 메서드를 붙여주므로 인스턴스 메서드라고 부른다.
		
	}									

}
package ex5.capsule;

import java.util.Scanner;

public class Exam {
	private int kor;
	private int eng;
	private int math;
	
	public Exam() {
		kor = 0;
		eng = 0;
		math = 0;
	}
	
//	public void init() {	// init은 초기화가 아니라 reset에 가깝다..
//						// init 함수는 객체가 만들어지자 마자 제일 먼저 실행되어야 한다.
//		int kor = 0;
//		int eng = 0;
//		int math = 0;
//	}
	
	public void input() {
		
		Scanner scan = new Scanner(System.in);
		
		System.out.println("┌──────────────┐");
		System.out.println("│	성적 입력	      		   │");
		System.out.println("└──────────────┘");

		do {
			System.out.print("kor : ");
			kor = scan.nextInt();
			
			if(kor < 0 || kor > 100) 
				System.out.println("kor은 0~100 의 값을 입력해주세요.");
			
		} while (kor < 0 || kor > 100); 

		do {
			System.out.print("eng : ");
			eng = scan.nextInt();
			
			if(eng < 0 || eng > 100) 
				System.out.println("eng은 0~100 의 값을 입력해주세요.");
			
		} while (eng < 0 || eng > 100); 
		
		do {
			System.out.print("math : ");
			math = scan.nextInt();
			
			if(math < 0 || math > 100) 
				System.out.println("math은 0~100 의 값을 입력해주세요.");
			
		} while (math < 0 || math > 100); 
		
	}
	
	public void print() {

		System.out.printf("kor: %d\n", this.kor);		// 우선순위 생각!!(앞의 지역변수 때문에 this를 써야한다.)
		System.out.printf("eng: %d\n", this.eng);
		System.out.printf("math: %d\n", this.math);
		System.out.printf("-----------------------\n\n");
	}	
	
	static void inputExam(Exam exam1) {	   // static을 써주는 이유는 인스턴스 메서드와 구별해주기 위해서 static을 써준다.(static 함수)
		exam1.kor = 30;
		exam1.eng = 20 ;
		exam1.math = 10;
	}

	static void printExam(Exam exam1) {	
		
		System.out.printf("kor1: %d\n", exam1.kor);
		System.out.printf("eng1: %d\n", exam1.eng);
		System.out.printf("math1: %d\n", exam1.math);
		System.out.printf("-----------------------\n\n");
	}
}



Daily Test : 22.12.20


-프로그램 제작 시, - 개발 일지 제작 하기 : 개발 목적, 키워드, 어려웠던 부분, 다른 방법?, 개선 부분!! 적기

package day.test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;

public class test_221220_1_1 { // 코드는 단계별로 주석처리로 진행했다.

	public static void main(String[] args) throws IOException {

//		문제 10 : 다음 각 절차를 따라 작성하시오.	        키워드 힌트가 필요하다면 열어보기!

		// 1. canvas라는 이름으로 문자 20x20개를 저장할 수 있는 배열 객체를 생성한다.

		// 2. canvas 배열을 다음처럼 ‘┼’ 문자로 채우는 코드를 작성하시오.
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼

		// 3. ‘○’ 문자를 이용해서 canvas에 선을 그리는 함수를 작성하시오.
		// 함수의 호출 예

		// 위의 결과는 다음과 같다.

//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼○┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼○┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼○┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼○┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼○┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼○┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼○┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼○┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼○┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼○┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼○┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼
//		┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼

		char[][] canvas = new char[20][20];

		{
			// 코드를 작성하는 공간

			for (int j = 0; j < 20; j++) {
				for (int i = 0; i < 20; i++) {
					canvas[j][i] = '┼';
					System.out.printf("%c", canvas[j][i]);
				}
				System.out.println();
			}

			System.out.println("board 초기화 완료\n");
		}

		{
			// 2번 문제 코드

			// 3번 문제풀이로 작성된 함수를 호출하는 코드
			int x1 = 10;
			int y1 = 5;
			int x2 = 13;
			int y2 = 13;
			drawLineOnCanvas(canvas, x1, y1, x2, y2);
		}

	}

	static void drawLineOnCanvas(char[][] canvas, int x1, int y1, int x2, int y2) {

		for (int j = 0; j < 20; j++) {
			for (int i = 0; i < 20; i++) {
				canvas[j][i] = '┼';

				if (x2 > x1 && y2 > y1)
					if ((j - y1) == ((y2 - y1) / (x2 - x1)) * (i - x1) && i <= x2 - 1 && i >= x1 - 1 && j <= y2 - 1
							&& i >= y1 - 1)
						canvas[j][i] = '○';

					else if (x2 < x1 && y2 > y1)
						if ((j - y1) == ((y2 - y1) / (x2 - x1)) * (i - x1) && (i >= x2 - 1 && i <= x1 - 1) && (j <= y2 - 1
								&& i >= y1 - 1))
							canvas[j][i] = '○';

				System.out.printf("%c", canvas[j][i]);
			}
			System.out.println();
		}
	}
}




객체 지향 프로그래밍 2일차 : 22.12.20


1) [수업 전 내용]

  • Data 분석에 관심이 있으면, 확률과 통계 공부하기(선형 대수 등등)

  • 캡슐화의 의미 : 구조화된 데이터, 그것을 사용하는 함수들을 묶어놓는 것.
    • 즉, 의미가 있고 목적을 가지고 있는 것
  • 자바에서는 카멜 표기로 변수명 사용해야 한다, 변수명은 의미가 명확해야 한다.

  • 일반적인 책의 내용에서 왜, 어떻게 사용해야하는지를 모두 믿지 말고 참고만 하기.



2) [캡슐화의 이해]

  • 우리는 프로그램에서 캡슐이 깨지면 안 된다.

  • 캡슐이 깨지는 것을 막기 위해서 도구(접근 제어자)가 필요하다.(private, public, protected, default, internal)
    • ex) 윈도우의 창을 이동하거나 닫거나 열거나 하는 행위는 모두 객체로 설정되어 있다.
  • 생성자는 함수가 아니며 이름으로 호출되는 것이 아니라 Exam 형식이여야만 ()로 호출된다.

  • private int kor은 형식이다.(메뉴판 느낌), 전역 변수도 아니다.
package ex5.capsule;

import java.util.Scanner;

public class Exam {
	private int kor;
	private int eng;
	private int math;



3) [오버로드 함수 개념], [오버로드 생성자 개념], [생성자 설정법]

  • 자바에서 예전은 같은 이름의 함수은 에러가 발생했다. 인자를 추가로 받기 때문에 적재된 것이 많아서 “오버로드 함수”라고 부른다.
package ex5.capsule;

import java.util.Scanner;

public class Exam {
	private int kor;
	private int eng;
	private int math;
	
	public Exam() {		//  이클립스에서는 생성자를 안 만들어주어도  
						//	기본적으로 0으로 세팅되는 생성자를 만들어준다.
//		kor = 0;
//		eng = 0;
//		math = 0;
		
		//Exam(0,0,0);		// 중요!! 생성자는 이름이 없기 때문에 호출될 방법이 없구나. 그래서 this(0,0,0)로 호출한다.

		this(0,0,0); 		// this(0,0,0); 는 객체가 단 한번도 실행되기 전에 실행되어야 한다. 
	}					// kor = 0;를 먼저 생성했으면 에러가 발생해버린다. 
	
	
	public Exam(int kor, int eng, int math) {		// 오버로드 생성자 이다. 오버로드 생성자는 기본적으로
		this.kor = kor;						// 이클립스가 생성자에 의해서 0.0.0이 입력된다..
		this.eng = eng;						// 밑의 print() 오버로드 함수와 같은 역할이다.(기본값 setting)
		this.math = math;						// main함수에서 사용자가 임의의 값(Exam exam1 = new Exam(1,2,3))으로 설정해줄 수도 있다.
	}	
	
	
//	public void init() {	// init은 초기화가 아니라 reset에 가깝다..
//						// init 함수는 객체가 만들어지자 마자 제일 먼저 실행되어야 한다.
//		int kor = 30;
//		int eng = 40;
//		int math = 50;
//	}
	
	public void input() {
		
		Scanner scan = new Scanner(System.in);
		
		System.out.println("┌──────────────┐");
		System.out.println("│	성적 입력	      		   │");
		System.out.println("└──────────────┘");

		do {
			System.out.print("kor : ");
			kor = scan.nextInt();
			
			if(kor < 0 || kor > 100) 
				System.out.println("kor은 0~100 의 값을 입력해주세요.");
			
		} while (kor < 0 || kor > 100); 

		do {
			System.out.print("eng : ");
			eng = scan.nextInt();
			
			if(eng < 0 || eng > 100) 
				System.out.println("eng은 0~100 의 값을 입력해주세요.");
			
		} while (eng < 0 || eng > 100); 
		
		do {
			System.out.print("math : ");
			math = scan.nextInt();
			
			if(math < 0 || math > 100) 
				System.out.println("math은 0~100 의 값을 입력해주세요.");
			
		} while (math < 0 || math > 100); 
		
	}
	

	
	public void print() {			// 오버로드 메서드는 구현된 메서드에게 넘겨준다.
		
		print('-',30);
	}	
	
	public void print(char c) {
		print(c,30);
	}

	public void print(char c, int length) {
		System.out.printf("kor: %d\n", this.kor);		// 우선순위 생각!!(앞의 지역변수 때문에 this를 써야한다.)
		System.out.printf("eng: %d\n", this.eng);
		System.out.printf("math: %d\n", this.math);
	
		for(int i = 0; i<length; i++)
			System.out.printf("%c", c);
	}
	
	static void inputExam(Exam exam1) {	   // static을 써주는 이유는 인스턴스 메서드와 구별해주기 위해서 static을 써준다.(static 함수)
		exam1.kor = 30;
		exam1.eng = 20 ;
		exam1.math = 10;
	}

	static void printExam(Exam exam1) {	
		
		System.out.printf("kor1: %d\n", exam1.kor);
		System.out.printf("eng1: %d\n", exam1.eng);
		System.out.printf("math1: %d\n", exam1.math);
		System.out.printf("-----------------------\n\n");
	}
}

  • this는 객체이며 인스턴스라서 객체를 대신 해주는 역할을 해준다.



4) [상속]

  • 상속 : 캡슐 덩어리를 엮어내고 단계를 만들어 내는 것, 조립하는 것

  • 캡슐이 하나 나오면서 main함수가 점점 가벼워진다.

  • 의존(Dependency) 객체 : 부품처럼 객체를 사용한다. 부품을 이용해서 Program이 만들어진다.

  • 그래서 우리는 데이터를 분리하고 입/출력을 따로 분리한다.

package ex6.has_a;


public class CapsuleTest {

	public static void main(String[] args) {
		
		//성적 객체를 준비한다.
		//실제 뉴렉 = new 성적();
		
		//Exam newlec = new Exam(1,2,3);
		ExamConsole console = new ExamConsole();
		
		console.input();
		
		console.print();		// 새로운 방식!! : 객체나 실체나 인스턴스의 개념인 객체(exam1)가 메서드(print())를 넘겨 받는다.
							// 정리: 우리는 인스턴스에 print() 메서드를 붙여주므로 인스턴스 메서드라고 부른다.
		
		
	}									



}

package ex6.has_a;

import java.util.Scanner;

public class ExamConsole {
	
	private Exam exam;		// 이 구문을 통해 결합이 되는 것이다.
									
						// 여기서 exam은 단순히 참조명이 아니라 이 console의 부품명이 된다.
						// 분리가 되면 한쪽은 부품이 되고 다른쪽은 제품이 된다.
						// Exam에서는 그냥 사용하고 
						// ExamConsole에서는 Exam 객체의 exam을 구성하는 관계가 존재한다.(Composition Has A  관계로 사용하고 있다. = 부품이나 멤버(this)를 가지고 있다.).
						// main 함수에서는 member가 아니라 그냥 쓴다. 구성하는 관계가 아니다.(Has A  관계)
	
						// Composition Has A 관계 : 객체를 a로 관계를 갖고 있다. 객체를 갖고는 있는데 각자 꽂아야하고 부품들을 무조건 생성해야한다. 
						//	부품들을 생성만하고 끝날 수도 있다. "일체형 관계"이다. 즉, "완성품"이다.
						// 부품이 그 안에 있는지도 모르는 관계
																		
						// Association Has A 관계 : 우리 코드를 따로 결합해주어야 한다. 핸드폰과 부품을 결합해주는 관계. 분리형 관계

						// Aggregation Has A 관계 : 
		

						// *** 데이터 구조를 유연하게 하기위해서 데이터 속성의 값을 노출해도 되지만 데이터 구조를 노출하면 안된다.

	public ExamConsole() {	
		exam = new Exam(); // 콘솔에서는 부품을 자기가 직접 만들어서 자급자족한다.	이것이 Composition Has A 관계이다.
						// 즉, 데이터를 통으로 넘겨주는 격이다.
	}					// 오전의 문제 푼 것에서 배열에서 생성자의 메모리 할당 생성자와 같다.
						// Composition Has A은 부품을 바꿔낄 수 없고 Association Has A는 부품을 바꿔낄 수 있다.
						// 따라서, Association Has A는 유연한 코드이다.
	
	

	public void input() {
		
		Scanner scan = new Scanner(System.in);
		
		System.out.println("┌──────────────┐");
		System.out.println("│	성적 입력	      		   │");
		System.out.println("└──────────────┘");
		
		int kor, eng, math;
		
		do {
			System.out.print("kor : ");
			kor = scan.nextInt();
			
			if(kor < 0 || kor > 100) 
				System.out.println("kor은 0~100 의 값을 입력해주세요.");
			
		} while (kor < 0 || kor > 100); 
		
					    // 이것이 Association Has A 관계
		exam.setKor(kor); // this.exam.setKor는 국어 성적을 setting 해주는 역할이며 이것을 간단히 exam.setKor(kor)라고 사용하며 setter 메서드라고 부른다. 
		
		do {
			System.out.print("eng : ");
			eng = scan.nextInt();
			
			if(eng < 0 || eng > 100) 
				System.out.println("eng은 0~100 의 값을 입력해주세요.");
			
		} while (eng < 0 || eng > 100); 
		
		exam.setEng(eng); // this.exam.setEng는 영어 성적을 setting 해주는 역할이며 이것을 exam.setEng(eng)라고 사용하며 setter 메서드라고 부른다. 

		do {
			System.out.print("math : ");
			math = scan.nextInt();
			
			if(math < 0 || math > 100) 
				System.out.println("math은 0~100 의 값을 입력해주세요.");
			
		} while (math < 0 || math > 100); 
		
		exam.setMath(math); // this.exam.setMath는 수학 성적을 setting 해주는 역할이며 이것을 exam.setMath(math)라고 사용하며 setter 메서드라고 부른다. 

	}
	

	
	
	public void print() {					// 오버로드 메서드는 구현된 메서드에게 넘겨준다.
		
		print('-',30);
	}	
	
	
	public void print(char c) {
		print(c,30);
	}

	public void print(char c, int length) {
		int total = exam.total();			// total과 avg를  출력 이외에도 사용하기 위해서 메서드로 만들기
		double avg = exam.avg();
		
//		System.out.printf("kor: %d\n", exam.getKor());			
//		System.out.printf("eng: %d\n", exam.getEng());
//		System.out.printf("math: %d\n", exam.getMath());
		
		System.out.printf("kor: %d\n", exam.getKor());			
		System.out.printf("eng: %d\n", exam.getEng());
		System.out.printf("math: %d\n", exam.getMath());
	
		for(int i = 0; i<length; i++)
			System.out.printf("%c", c);
	}
}

package ex6.has_a;

public class Exam {
	
	//private Subject subject; 	// Subject를 추가해줘도 구조는 바뀌지만 구성은 바뀌지 않는다.(중요!! exam : subject.exam.kor)
							// 데이터 구조를 숨겨주는 역할을 해주는 것이 getter와 setter이다.(구성은 같다.)
	
	private int kor;		// 외부 파일의 접근을 위해서 private는 사용할 수 없다.
	private int eng;
	private int math;
	
	public Exam() {		//  이클립스에서는 생성자를 안 만들어주어도  
						//	기본적으로 0으로 세팅되는 생성자를 만들어준다.
//		kor = 0;
//		eng = 0;
//		math = 0;
		
		//Exam(0,0,0);		// 중요!! 생성자는 이름이 없기 때문에 호출될 방법이 없구나. 그래서 this(0,0,0)로 호출한다.

		this(0,0,0); 		// this(0,0,0); 는 객체가 단 한번도 실행되기 전에 실행되어야 한다. 
	}					// kor = 0;를 먼저 생성했으면 에러가 발생해버린다. 
	
	
	public Exam(int kor, int eng, int math) {	// 오버로드 생성자 이다. 오버로드 생성자는 기본적으로
		this.kor = kor;					// 이클립스가 생성자에 의해서 0.0.0이 입력된다..
		this.eng = eng;					// 밑의 print() 오버로드 함수와 같은 역할이다.(기본값 setting)
		this.math = math;					// main함수에서 사용자가 임의의 값(Exam exam1 = new Exam(1,2,3))으로 설정해줄 수도 있다.
	}	
	
	public double avg() {
		return total() / 3.0;
	}


	public int total() {
		return kor + eng + math;
	}


	public void setKor(int kor) {			// 데이터 구조를 숨겨주는 역할을 해주는 것이 getter와 setter이다.(구성은 같다.)
		this.kor = kor;					// this는 객체를 대신 써주는 것
	}


	public void setEng(int eng) {			// getter와 setter는 자동적으로 만들수 있다.
		this.eng = eng;
	}


	public void setMath(int math) {
		this.math = math;
	}


	public int getKor() {	
		return kor;
	}


	public int getEng() {
		return eng;
	}


	public int getMath() {
		return math;
	}

}


3. 상속(객체 지향 3) : 22.12.21

0) 들어가기전, 객체 배열 정리

  • 항상, 새로 만들어진 객체에 배열을 사용하기 위해서 2단계의 과정을 무조건 진행해야한다.

    • 1단계 : 배열 참조

        Student[] students = new Student[10];	// 중요!! 배열 참조(나는 생성자에서 만드려고 했다.)
      
    • 2단계 : 배열 할당

        students[j] = new Student();			// 중요!! 배열 할당!!(내가 이해하지 못한 부분)
                                        // 그 만들어진 공간에 이름 붙여주는 역할
      
package day.test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

public class Room {				

		Student[] students = new Student[10];			// 중요!! 배열 참조(나는 생성자에서 만드려고 했다.)
												// 이건 공간만 만들어줌.	
													
		public void load(String path) throws FileNotFoundException {
		
		FileInputStream fis = new FileInputStream(path);
		Scanner scan = new Scanner(fis);
		
		while(scan.hasNext()) {						// 데이터의 크기를 세는 방법 : 파일을 두번 읽어서 첫번째는 데이터 크기 세고 나머지는 그 크기는 배열 생성
												// 두번째 방법은 : 가변배열 방법 이용
			for(int j=0; j<10; j++) {
				
//				line.replaceAll(",|\n", " ");		// 이 방법으로도 나중에 해보기
				
				String line = scan.nextLine();			
				
				String[] tokens = line.split(",");	// 이부분은 위의 line과 같은 방식으로 String[]으로 생성한 부분이다.	
												// 참조 변수명이 여러개 값을 받으면 복수로 변수명 만들기
				
				students[j] = new Student();			// 중요!! 배열 할당!!(내가 이해하지 못한 부분)
												// 그 만들어진 공간에 이름 붙여주는 역할
				
				int num = Integer.parseInt(tokens[0]);
				students[j].setId(num);
				students[j].setName(tokens[1]);

			}
		
		}
	}
	

1) [관계 구분]

  • Has A 관계 : 결합관계를 의미한다.(부품과 제품 사이의 관계)

  • Is A 상속 : “상속”이라고 부른다.

  • Aggregation 관계 : 필요할 때마다 객체를 만든다.(집합 관계, 1:N 관계), 처음에는 메서드가 없다.

  • Composition 관계 : 이미 객체를 만들어 놓고 사용한다. (1:1 관계), 메서드를 한번에 다 갖고 있다.

  • Associaion 관계 : 객체를 각각 만들어주고 서로 연결해주는 과정이 있다.

  • 정리** :

    • Composition 관계는 생성자에 이미 데이터에 값을 다 설정 해놓고 사용한다.
    • Aggregation은 필요할 때마다 set과 get을 통해서 값을 저장하여 사용한다.
    • Associaion은 객체를 각각 만들어주고 서로 연결해주는 과정이 있다.



2) [Injection의 의미]

  • Setter Injection : Association에서 사용, set을 이용하는 경우

  • Construction Injection : 생성자를 통해서 결합하는 경우

  • DI(Dependency Injection = 의존성 주입) : “부품을 결합한다.”는 의미이다.

  • Is A 상속 : 틀을 만들어 놓고 가져다가 사용. 이러한 틀을 “framework” 라고 부른다.



3) [재사용의 의미]

  • 재사용의 의미 : 배포되어서 바이너리 파일을 가지고 소스코드를 얻는것이다.

  • 재사용은 기존의 코드를 건드리면 안된다.



4) [상속의 개념]


  • 상속을 관계해주는 방법, 첫번째 방법 : extends 이용
package ex7.is_a;

public class NewlecExam extends Exam { 	// 이부분
	
	private int com;

}
  • Exam은 부모클래스, NewlecExam은 자식클래스



  • 상속을 관계해주는 방법, 두번째 방법 : Exam exam 이용
  • 2가지 방식을 같이 쓰진 못한다.
package ex7.is_a;

public class NewlecExam {
	
	private Exam exam; // 이부분
	private int com;

}



5) [super의 개념]

  • super() : 부모의 틀을 가져온다.(부모의 생성자를 가져온다.), super도 집중화 가능(재사용이랑 의미는 다르다.)



6) [Override의 개념]

package ex7.is_a;

public class NewlecExam extends Exam {
	
	private int com;
	
	public NewlecExam() {
			
		//setKor = 1;
		super();
		this.com = 0;
				 
	}
	
	public NewlecExam(int kor, int eng, int math, int com) {
		
		//setKor = 1;
		
		super(kor, eng, math);	// 부모의 생성자를 받아오는 경우
		this.com  = com;
	}

	@Override					// 부모가 갖고 있는 메서드를 Override 방식으로 수정했다.(덮어 씌움)
	public int total() {
		return super.total() + com;
	}
	
	@Override
	public double avg() {		// 틀을 만드는 것은 생성자를 쓰거나 Override를 통해 고쳐쓴다.
		
		//return super.avg()*3/total();
		return total()/4.0;
	}
}



7) [객체와 참조 형식의 개수의 개념]

Exam exam = new Exam();				// 가능.
NewlecExam exam = new NewlecExam();	// 가능.
NewlecExam exam = new Exam();		// 불가능.
Exam exam = new NewlecExam();		// 가능. NewlecExam은 자식이라서 부모 범위로 포함해서 더 큰 범위로 생성된다. 더 큰 범위(NewlecExam)에서는 작은 범위인 Exam을 사용할 수 있다.	
								// new로 객체가 만들어지기 때문이다. 



8) [객체와 참조 형식의 개수의 개념]

  • 부모에 메서드가 없다면 오버라이드 메서드를 호출할 수 없다.



8) [객체와 참조 형식의 개수의 개념]

  • 자식 메서드인 Override가 우선시 된다.

  • Framework도 만들어지는 과정이 이것과 같다. 내가 만든 프로그래밍 순서를 거쳐서 원래 프로그래밍 순서로 되돌아간다. 하지만, 되돌아가는 것은 순회하는 느낌으로 돌아가는 것이며 되돌아가는 것도 내가 선언을 따로 해줘야 한다.

package ex7.is_a;


public class InheritanceTest {

	public static void main(String[] args) {
		
		NewlecExam exam1 = new NewlecExam(1,1,1,1);
		System.out.println(exam1.total());
		System.out.println(exam1.avg());
		
		Exam exam2 = new NewlecExam(1,1,1,1);
		System.out.println(exam2.total());
		
//		Exam exam3 = new Exam(1,1,1);
//		System.out.println(exam3.total());	
	}									
}

package ex7.is_a;

public class NewlecExam extends Exam {
	
	private int com;
	
	public NewlecExam() {
			
		//setKor = 1;
		super();				// 초기화 부분이라서 이런식으로 아무 값 없이 가져온다.
		this.com = 0;
				 
	}
	
	public NewlecExam(int kor, int eng, int math, int com) {
		
		//setKor = 1;
		
		super(kor, eng, math);	// 부모의 생성자를 받아오는 경우, 기존의 입력값을 가져오는 것이므로 변수명으로 받아온다.
		this.com  = com;
	}

	@Override					// 부모가 갖고 있는 메서드를 Override 방식으로 수정했다.(덮어 씌움)
	public int total() {
		return super.total() + com;
	}
	
	@Override
	public double avg() {		// 틀을 만드는 것은 생성자를 쓰거나 Override를 통해 고쳐쓴다. 
		
		//return super.avg()*3/total();
		return total()/4.0;
	}
}


package ex7.is_a;

public class Exam {
	
	//private Subject subject; // Subject를 추가해줘도 구조는 바뀌지만 구성은 바뀌지 않는다.(중요!! exam : subject.exam.kor)
						    // 데이터 구조를 숨겨주는 역할을 해주는 것이 getter와 setter이다.(구성은 같다.)
	
	private int kor;		// 외부 파일의 접근을 위해서 private는 사용할 수 없다.
	private int eng;
	private int math;
	
	public Exam() {		// 이클립스에서는 생성자를 안 만들어주어도  
						// 기본적으로 0으로 세팅되는 생성자를 만들어준다.
//		kor = 0;
//		eng = 0;
//		math = 0;
		
		//Exam(0,0,0);		// 중요!! 생성자는 이름이 없기 때문에 호출될 방법이 없구나. 그래서 this(0,0,0)로 호출한다.

		this(0,0,0); 		// this(0,0,0); 는 객체가 단 한번도 실행되기 전에 실행되어야 한다. 
	}					// kor = 0;를 먼저 생성했으면 에러가 발생해버린다. 
	
	public Exam(int kor, int eng, int math) {	// 오버로드 생성자 이다. 오버로드 생성자는 기본적으로
		this.kor = kor;					// 이클립스가 생성자에 의해서 0.0.0이 입력된다..
		this.eng = eng;					// 밑의 print() 오버로드 함수와 같은 역할이다.(기본값 setting)
		this.math = math;					// main함수에서 사용자가 임의의 값(Exam exam1 = new Exam(1,2,3))으로 설정해줄 수도 있다.
	}	
	
	public double avg() {
		return total() / 3.0;
	}

	public int total() {
		return kor + eng + math;
	}

	public void setKor(int kor) {		// 데이터 구조를 숨겨주는 역할을 해주는 것이 getter와 setter이다.(구성은 같다.)
		this.kor = kor;				// this는 객체를 대신 써주는 것
	}

	public void setEng(int eng) {		// getter와 setter는 자동적으로 만들수 있다.
		this.eng = eng;
	}

	public void setMath(int math) {
		this.math = math;
	}

	public int getKor() {	
		return kor;
	}

	public int getEng() {
		return eng;
	}

	public int getMath() {
		return math;
	}
}
package ex7.is_a;

import java.util.Scanner;

public class ExamConsole {
	
	private Exam exam;		// 이 구문을 통해 결합이 되는 것이다.
									
						// 여기서 exam은 단순히 참조명이 아니라 이 console의 부품명이 된다.
						// 분리가 되면 한쪽은 부품이 되고 다른쪽은 제품이 된다.
						// Exam에서는 그냥 사용하고 
						// ExamConsole에서는 Exam 객체의 exam을 구성하는 관계가 존재한다.(Composition Has A  관계로 사용하고 있다. = 부품이나 멤버(this)를 가지고 있다.).
						// main 함수에서는 member가 아니라 그냥 쓴다. 구성하는 관계가 아니다.(Has A  관계)
	
						// Composition Has A 관계 : 객체를 a로 관계를 갖고 있다. 객체를 갖고는 있는데 각자 꽂아야하고 부품들을 무조건 생성해야한다. 
						// 부품들을 생성만하고 끝날 수도 있다. "일체형 관계"이다. 즉, "완성품"이다.
						// 부품이 그 안에 있는지도 모르는 관계
																		
						// Association Has A 관계 : 우리 코드를 따로 결합해주어야 한다. 핸드폰과 부품을 결합해주는 관계. 분리형 관계

						// Aggregation Has A 관계 : 
		
						// *** 데이터 구조를 유연하게 하기위해서 데이터 속성의 값을 노출해도 되지만 데이터 구조를 노출하면 안된다.

	public ExamConsole() {	
		exam = new Exam(); 		// 콘솔에서는 부품을 자기가 직접 만들어서 자급자족한다. 이것이 Composition Has A 관계이다.
								// 즉, 데이터를 통으로 넘겨주는 격이다.
	}							// 오전의 문제 푼 것에서 배열에서 생성자의 메모리 할당 생성자와 같다.
								// Composition Has A은 부품을 바꿔낄 수 없고 Association Has A는 부품을 바꿔낄 수 있다.
								// 따라서, Association Has A는 유연한 코드이다.

	public void input() {
		
		Scanner scan = new Scanner(System.in);
		
		System.out.println("┌──────────────┐");
		System.out.println("│	성적 입력	      		   │");
		System.out.println("└──────────────┘");
		
		int kor, eng, math;
		
		do {
			System.out.print("kor : ");
			kor = scan.nextInt();
			
			if(kor < 0 || kor > 100) 
				System.out.println("kor은 0~100 의 값을 입력해주세요.");
			
		} while (kor < 0 || kor > 100); 
		
						   // 이것이 Association Has A 관계
		exam.setKor(kor); 	   // this.exam.setKor는 국어 성적을 setting 해주는 역할이며 이것을 간단히 exam.setKor(kor)라고 사용하며 setter 메서드라고 부른다. 
		
		do {
			System.out.print("eng : ");
			eng = scan.nextInt();
			
			if(eng < 0 || eng > 100) 
				System.out.println("eng은 0~100 의 값을 입력해주세요.");
			
		} while (eng < 0 || eng > 100); 
		
		exam.setEng(eng); 	   // this.exam.setEng는 영어 성적을 setting 해주는 역할이며 이것을 exam.setEng(eng)라고 사용하며 setter 메서드라고 부른다. 

		do {
			System.out.print("math : ");
			math = scan.nextInt();
			
			if(math < 0 || math > 100) 
				System.out.println("math은 0~100 의 값을 입력해주세요.");
			
		} while (math < 0 || math > 100); 
		
		exam.setMath(math);   // this.exam.setMath는 수학 성적을 setting 해주는 역할이며 이것을 exam.setMath(math)라고 사용하며 setter 메서드라고 부른다. 

	}
	

	public void print() {	   // 오버로드 메서드는 구현된 메서드에게 넘겨준다.
		
		print('-',30);
	}	
	
	
	public void print(char c) {
		print(c,30);
	}

	public void print(char c, int length) {
		int total = exam.total();			// total과 avg를  출력 이외에도 사용하기 위해서 메서드로 만들기
		double avg = exam.avg();
		
//		System.out.printf("kor: %d\n", exam.getKor());			
//		System.out.printf("eng: %d\n", exam.getEng());
//		System.out.printf("math: %d\n", exam.getMath());
		
		System.out.printf("kor: %d\n", exam.getKor());			
		System.out.printf("eng: %d\n", exam.getEng());
		System.out.printf("math: %d\n", exam.getMath());
	
		for(int i = 0; i<length; i++)
			System.out.printf("%c", c);
	}
}



4. 객체 지향 4 : 22.12.22


1) 이전 강의의 객체지향

  • 구조화 : 수납공간을 어떻게 만들건지 고민하는 것(객체지향)

  • 행위도 넣어주고 행위의 주체도 넣어 주어야 한다.

  • 남이 만든 프레임워크를 가져다가 사용한다.

  • 일반적으로 초급 개발자는 UI를 만드는 일을 많이 한다. 객체 설계를 하지 않는다. 데이터 설계를 위한 이해가 필요하다. 전체 시스템에 대한 이해가 필요하다.

  • 배운 기술(스프링 부트)을 사용할 수 있어야 하고 사수의 유무가 아니라 책임의 유무이다. 사수는 가르쳐 주지 않는다.

  • 연봉보다 신입을 빨리 없애고 회사에서는 어울릴 수 있는 사람인가가 중요하다. 실력은 중요하지 않다. 인성이 중요하다. 오만함을 없애라.

  • 궁하지 않을 때, 면접을 많이 봐라. 자신감이 아직 있을 때, 편하게 면접 볼 수 있다. 주눅 들지않고


2) Is_A 상속 설명 : 기존의 프레임워크를 이용하는 방법

  • 기존의 프레임워크를 통해 extends로 상속받을 때, 커스터마이징을 할 수 있도록 해야 한다.

  • ex) 그림 그리는 로직을 내가 Override를 통해 로직을 바꿀 수 있다.(paint 메서드)

  • 점차 브라우저에서 모든 것을 해결하려고 한다. 브라우저에서 인스톨하려고 한다.

  • 앞으로는 서블릿 클래스, html 이용


3) 다형성

  • 다형성 : 캡슐을 분리해서 만들고 결합력을 느슨하게 만든다. 인터페이스와 관련 있는 내용

  • 아직 다형성은 개념 이해가 안 가서 간단히 게임 개발하고나서 나중에 다시 공부하자. 앞으로는 서블릿 공부, 백엔드, 프론트 엔드 개발 공부할 것임.




5. 자바 웹 개발 시작 (Servlet, Tomcat) : 22.12.22

  • 입/출력 도구가 이제부터 달라진다. 기존의 콘솔, 파일에서 웹이 추가된다.

  • 서블릿 – JSP – JSP MVC – Spring MVC 순서로 진행되었다.

  • 이전에는 서블릿이 중요했지만 앞으로는 중요한 기술들이 바뀌어서 이러한 내용들은 빠르게 훑고 Spring까지 배워야 한다.


1) [강의 진행 방향]

  • 미니프로젝트 : Servlet, Json, JS 맛보기

  • 1차 프로젝트 스프링부트, Thymeleaf(JSP 안 쓰고) 이용

  • 2차 프로젝트 : 프론트 엔드(vue js 이용)



2) [Servlet] 시작


3) [인터넷 vs 웹]

  • 인터넷 : ex) “도로”와 같은 통로를 의미한다.
  • 웹 : www 형식으로 문서를 서비스하기 위한 시스템이다. (ex) 배달을 해주는 시스템)


4) [인터넷 등장 배경]

  • LAN : local area network (전세계적으로 공유할 수 있는 공간이 생김.)
  • 이러한 network끼리 물리적인 장치를 연결시켜주는 것이 “inter network”라고 부름
  • 게이트웨이 : network가 서로 나갈 때, 갈아타기 위한 장소.
  • 이렇게 internet이 만들어짐.(지나다니는 통로) 이제는 배달시켜주는 것이 필요하다.


5) [서버 vs 클라이언트]

  • 한쪽은 서버가 되고 다른 한쪽은 클라이언트가 된다.
    • 서버 : 핫 스왑의 개념,

    • 클라이언트 : 파일을 전송하기 위해서 일련의 약속이 필요하다.
      • 이러한 약속을 프로토콜(FTP)이라고 부른다.
      • HTTP(하이퍼텍스트로 파일을 보내줌), SMTP(메일링으로 파일을 보내줌)
    • 이제는 웹으로 도로가 되는 역할이 된다. 하지만, 웹은 문서를 전달하는 시스템에 불과하다.


6) [웹 프로그래밍 VS 자바 프로그래밍]

  • IP : inter network에서 다른 network로 전송할 때, 식별되는 번호이다.
    • 192.168.0.1
  • MAC address : 웹에서는 LAN Port Address(랜카드)에 의해 식변된다.(Media Access Control Address를 구별해주기 위해서 MAC address를 붙여준다.)
    • MAC주소를 보고 통신해야 할 포트를 지정해 내보낼 수 있다.
    • MAC Address를 이용하여 구별해줘서 우리는 송신할 수 있다.
    • 192.168.0.1에서 1은 host 번호이고 1에 의해서 MAC Address가 정해진다.
  • Broad casting : 그래서, MAC address가 너무 많아서 그에 맞는 Media Access를 찾기 위해서 방송 같은 것을 한다. Network 환경 설정에서 32번으로 설정되어 있으면 이것이 Host 번호이다.

  • Port : 아직은 밖에 있는 데이터가 컴퓨터까지만 와서 추가적으로 데이터가 있는데 이것이 port라고 부르며 이것은 사서함과 같다.
    • http에서 8080이라는 포트번호를 사용에서 포트번호는 각 역할을 부여해준다.
  • 정리** : 데이터가 올 때는, 웹에서 IP로 오지만 Port 번호가 있어서 사서함에 데이터를 전해준다. IP는 문턱까지, MAC address는 디테일까지, Port는 각 역할까지(MAC주소를 보고 통신해야 할 포트를 지정해 내보낼 수 있다. )

  • 네트워크 소켓 : 네트워크 데이터를 연결해주는 IP Address, Port의 정보를 갖고 데이터를 주고 받는다.

  • API : 사서함의 데이터를 꺼내 쓰고 네트워크로 수거해가는 것이다.(send, receive)

  • RPC(Remote Procedure Call) : 아래 한글 처럼 업데이트할 때, 항상 지웠다가 다시 설치해야 한다. 별도의 원격 제어를 위한 코딩 없이 다른 주소 공간에서 리모트의 함수나 프로시저를 실행 할 수 있게 해주는 프로세스간 통신입니다. 즉, 위치에 상관없이 RPC를 통해 개발자는 위치에 상관없이 원하는 함수를 사용


6) [웹이란?]

  • 이제는 웹을 브라우저를 통해 동적으로 만들어 준다.
  • 백엔드 개발 : 서버에서 코드를 이용해서 문서를 만들고(문서화) 이러한 문서는 클라이언트에서 요청이 있을 때마다 문서를 전달해준다.(동적 개발)
  • 프론트 개발 : 클라이언트 프로그램을 만들지 않지만 요즘에는 프론트 개발쪽에서 데이터를 직접 사용하므로 살아났다.


7) [WAS의 개념]

  • “server app” : 문서화 하기 위해 코드를 모아두는 공간이다.
  • “Web server” : 서버를 실행해주는 실행환경 그자체이다.
  • “WAS” : 그것에 대한 코드를 실행하여 그 결과를 돌려주는 서버라고 한다. WAS는 서버의 타입명이다. 그 중에서 제품명은 “Tomcat”이 있다.
  • apache는 돌아가 해주는 범용도구이다. 예를 들어, tomcat, php 등이 있다.


8) [Tomcat의 개념]

  • Tomcat을 실행하기 위해서 Tomcat은 java를 이용하므로 “JAVA_HOME”이라는 환경 변수를 추가로 설정해야 한다.

  • apcahe.org 홈페이지에서 Tomcat을 설치하면 설치 파일의 bin 폴더의 startup.bat 파일이 있다. 해당 파일을 키면, 브라우저와 클라이언트를 연결할 수 있다. 즉, startup.bat 파일은 서버와 같은 역할을 한다.

  • D:\Setup\apache-tomcat-10.0.27\webapps\ROOT 경로의 폴더에서 만들어지는 파일은 브라우저에서 사용되며 표시된다.

    • 따라서, ROOT 폴더에서 nana.txt를 만들고나서 http://localhost:8080/nana.txt의 url로 브라우저 이동하면, txt 파일의 내용을 브라우저에서 출력하여 서비스할 수 있다.



5. 톰캣, 서블릿 : 22.12.23


0) [들어가기 전]

  • 참조는 사용하기 위한 참조형을 정하는 것이 좋다.

  • 자식은 확장하는 기능도 있고 확장하는 기능이 아니라 부모의 수준에서 사용하고 싶으면,

  • 자식 이름을 쓰게되면 참조하는 영역이 줄어든다.

  • Frame(부모)이 아니라 GameFrame(자식)으로 이름으로 쓰면 사용하는 기능이 줄어들어서 사용하게 된다. 굳이, GameFrame(Override된 형태만)이라고 범위를 한정시킬 필요는 없다.

  • 그래서 Frame를 사용한다.



1) [네트워크 기본 강의] : 추가로 공부하기(성공과 실패를 결정하는 1% 의 네트워크 원리)

  • 웹은 기본적으로 port 번호를 80으로 이용해서 톰캣의 포트번호를 8080으로 설정하기. 따라서, http에서 port 번호 80을 입력하면 생략된다.(server.xml에서 변경 가능)

  • http의 port는 80번으로 default port이므로 묵시적으로 입력된다.

  • Tomcat은 “index.html”, “index.jsp”, “index.htm”의 순서로 다음의 파일이 없으면 404 에러가 발생한다.

  • 네트워크 연결 방법
    • 1) 구리선 이용

    • 2) LAN 이용 : 공유선(전기선)이 가운데 존재하고 가지로 가지를 친다. 네트워크가 더 줄어들게 된다. ex) 버스형, 링형, 스타형(효율적인다, 스위치를 이용하므로) 등등
      • 요즘에는 허브로 공유기를 사용한다. 버스형이라고도 부른다.
    • 3) 공중파 이용 : 와이파이
  • 스니핑 개념 : 보안 관련된 내용

  • 네트워크 네이밍 : 도메인이라고 부른다.
    • 예전에는 C:\Windows\System32\drivers\etc 경로에서 hosts 파일에 ip와 DNS를 적으면 그게 도메인으로 적용되어서 DNS를 조작할 수 있다.(호스트 파일 조작 방식)
    • 하지만, 요즘에는 윈도우 업데이트로 불가
  • 도메인은 보통 요청하면, 원격의 도메인에서 DB에서 찾지 않고 일일이 찾아준다.



2) [Context 사이트의 이해]

  • Context 사이트 추가 : 문맥을 이어주는 역할, 밖에서 보면 하위 디렉토리 처럼 보이게 해준다.
    • server.xml에서 수정(오타 주의) :


        <Host name="localhost"  appBase="webapps"
             unpackWARs="true" autoDeploy="true">
            <Context path="" docBase="" privilleged="true"/>
      


  • 하지만, 요즘에는 Context를 도메인 앞으로 쓰게 바뀌어 가고있다. 그렇지만 우리는 Context로 만든다.



3) [Servlet의 개념]

  • Server + let : 서버 어플리케이션의 조각

  • 앞으로 어플리케이션은 조각(Servlet)들을 모아서 만들게 된다.

  • 서블릿을 이용하기 위한 툴은 톰캣이 만든 프레임워크이다.

  • Tomcat 10 버전부터 패키지명이 자카르타(jakarta)로 달라졌다.(Tomcat 9 이전의 버전은 패키지가 javax로 동일하다.)

  • WEB-INF : WEB ROOT를 의미한다. WEB-INF 폴더의 파일은 사용자가 요청해도 접근할 수 없다.

  • WAS : 코드를 실행하여 그 결과를 돌려주는 서버

  • Web Server : Tomcat이라는 웹 서버 기능, 서버가 맞는지 판단 기능이 필요하다.



4) [Servlet의 실행 방법]


  • “Tomcat”에게 일하라고 요청해주는 역할을 web.xml파일에서 설정해준다.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:web="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd http://xmlns.jcp.org/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="5.0">
  <display-name>webprj</display-name>
  
  <servlet>	<!-- 메모리에 올리고 객체화한다. 객체화하고 이름을 달아줘야하는데 이것이 servlet-name이다. -->
  	<servlet-name>nana</servlet-name>
  	<servlet-class>com.newlecture.Nana</servlet-class>
  </servlet>

  <servlet-mapping>				<!-- url-parrtern이다. 오타 주의!! -->
  	<servlet-name>nana</servlet-name>
  	<url-pattern>/hello.txt</url-pattern>
  </servlet-mapping>


  • HttpServlet로부터 상속받아서 service 메서드를 구성한다.(HttpServletRequest와 HttpServletResponse를 인자로 받기 때문에 서블릿으로 브라우저와 송수신해준다.)
package com.newlecture;

import jakarta.servlet.*;
import jakarta.servlet.http.*;
import java.io.*;

public class Nana extends HttpServlet
{
	public void service(HttpServletRequest request
			, HttpServletResponse response)
			throws IOException, ServletException
	{
		for(int i =0; i<10; i++)
			System.out.println("hello Servlet");
	}

}
  • http://localhost/news/hello.txt 이동하면, 브라우저에서는 흰 화면이 나오지만, server.bat의 콘솔에서 출력된다.