멀티캠퍼스 백엔드 과정 14일차[6월 20일] - JAVA 클래스

GoldenDusk·2023년 6월 23일
0

클래스

1. 객체 지향 프로그래밍

객체

  • 객체(object)란 물리적으로 존재하거나 개념적인 것 중에서 다른 것과 식별 가능한 것
  • 객체 : 속성과 동작으로 구성
    • 속성 : 필드
    • 동작 : 메소드

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

  • 객체 객체들을 먼저 만들고, 이 객체들을 하나씩 조립해서 완성된 프로그램을 만드는 기법

객체의 상호작용

  • 객체 지향 프로그램에서도 객체들은 다른 객체와 서로 상호작용하면서 동작
  • 객체가 다른 기능을 이용 시 이 메소드 호출해 데이터를 주고 받음
    • 매개값(파라미터) : 객체가 전달하고자 하는 데이터이며, 메소드 이름과 함께 괄호()안에 기술 set
    • 리턴값 : 메소드의 실행 결과, 호출한 곳으로 돌려주는 값 get

package day0620;

class SportsCar1{
	// 데이터
	
	// 기능
}
class Tire1{
	// 데이터
	
	//기능
	
}
class Student{
	// 데이터
	String name;
	
	//이름을 전달받아서 저장기능 => 메소드 void : 리턴값은 없고 
	public void setName(String name) { // String name은 저장받을 공간
		this.name = name;
	} 
	// 이름을 출력하는 기능
	public  String getName() {
		return this.name;
	}
}

public class Main{
	public static void main(String[] args) {
		SportsCar1 car = new SportsCar1(); //스포츠카 생성 내부에 있어서 이름 바꿔도 문제 x
		Tire t1 = new Tire(); // 타이어 생성
		//student 클래스 선언하고 학생 1명 객체 생성
		Student stu1 =new Student();
		Student stu2 =new Student();
		
		stu1.setName("김자바");
		String name1 = stu1.getName(); //name에 들어가서 출력 가능한지 봐보자
		System.out.println(name1);
		
		stu2.setName("이자바");
		String name2 = stu2.getName(); //name에 들어가서 출력 가능한지 봐보자
		System.out.println(name2);
	}
}

객체 생성

  • 객체 생성 연산자 : new
  • 클래스 변수 = new 클래스명();
    • 약간 전화번호 부가 이름과 전번 매칭해둔 그런 느낌
    • 클래스 변수를 통해 객체를 찾아가고, 값을 찾아갈 수 있다.
  • 객체 참조
stu1 = new Student(); //stu1 변수가 Student 객체를 참조합니다.

클래스의 두 가지 용도

  • 라이브러리(library) 클래스 : 실행 할 수는 없으며 다른 클래스에서 이용하는 클래스
  • 실행 클래스 : 메소드를 가지고 있는 실행 가능한 클래스
  • 예시 : 사용 관계
    • 라이브러리 클래스 : Student2

      • 이름(name)과 나이(age)를 가지고 있고 이름과 나이를 저장하고 출력하는 메소드를 가지고 있다.

      • Student2(){}
        - 생성자 : 객체 생성시 초기화 역할을 담당하는 특수한 메소드이자 start 메소드

        package day0620;
        
        public class Student2 //라이브러리 클래스
        {
        	String name;
        	int age;
        	
        	Student2(){} // 생성자 : 객체 생성시 초기화 역할을 담당하는 특수한 메소드이자 start 메소드
        	
        	// 메소드 : 객체의 동작으로 호출(이름을 불러줌)시 실행하는 블록
        	// name을 저장하는 setter 메소드 
        	public void setName(String name) {
        		this.name = name;
        	} // 이 블럭이 사라지는 동시에 사라지기에 setter의 값은 사라지기에 name에 옮겨서 저장해줌
        	
        	public void setAge(int age) {
        		// 클래스 내부에서 멤버 변수와 매개변수의 이름이 같을 경우, 매개변수로 전달된 값을 구분하기 위해 this 키워드를 사용
        		// this는 해당 객체 자신을 가리키는 참조로, 객체 내에서 멤버 변수에 접근할 때 사용
        		this.age = age; // 객체의 멤버 변수 age에 전달된 값 age를 할당하는 코드
        	} // 한 번 쓰고 버리는 값 => 저장하기 위해서는 데이터베이스와 연동
        	
        	// name 잘 저장되었는지 확인 getter 메소드
        	public String getName() {
        		return this.name;
        	}
        	
        	public int getAge(){
        		return this.age;
        	}
        	
        	public void printInfo() {
        		System.out.println(this.name + "학생이며 나이는"+this.age);
        	}
        }
    • 실행 클래스 : StudentEx

      package day0620;
      
      public class StudentEx
      {
      
      	public static void main(String[] args) //실행 라이브러리
      	{
      		// 객체 두 개 생성되며 따로 따로 저장 => Student2 클래스에서
      		 Student2 stu1 = new Student2(); 
      		 Student2 stu2 = new Student2();
      		 
      		 stu1.setName("김선비");
      		 stu2.setName("최단비");
      		 
      		 stu1.setAge(15);
      		 stu2.setAge(17);
      		 
      		 stu1.printInfo();
      		 stu2.printInfo();
      		 
      		 
      	}
      
      }

객체 간의 관계

  • 집합 관계 : 완성품과 부품의 관계
  • 사용 관계 : 다른 객체의 필드를 읽고 변경하거나 메소드 호출하는 관계
  • 상속 관계 : 부모와 자식 관계, 필드, 메소드 물려받음

예제

  • 도트(.) 연산자
    • 객체가 가지고 있는 필드나 메소드에 접근하고자 할 때 참조변수 뒤에 붙인다.

2. 생성자 선언과 호출

생성자 오버로딩

  • 매개변수를 달리하는 생성자를 여러 개 선언하는 것
  • 매개변수의 타입, 개수, 순서가 다르게 여러 개의 생성자 선
  • 매개변수의 타입, 개수, 선언된 순서가 똑같을 경우 매개변수 이름만 바꾸는 것은 생성자 오버로딩이 아님
  • 생성자가 오버로딩되어 있을 경우, new 연산자로 생성자를 호출할 때 제공되는 매개값의 타입과 수에 따라 실행될 생성자가 결정

예시

  • 라이브러리 클래스 : Student
package day0620_2;

public class Student
{
	String name;
	String subject;
	int fee;
	double returnFee;
	
	// 같은 이름을 가진 메소드를 () 안에 파라미터나 타입을 달리 해서 다양한 형태로
	// 사용 가능 => 메소드 오버로딩
	Student(){} //기본생성자
	Student(String name, String subject, int fee){
		this.name = name;
		this.subject = subject;
		this.fee = fee;
	}
	
public void calcReturnFee(String subject) {
	int resultFee = 0;
	if(subject.equals("javaprogram")) {
		resultFee =this.fee/4;
	}
	else if(subject.equals("jspprogram")) {
		resultFee = this.fee/5;
	}
	else {
		System.out.println("그런 과정명은 없습니다.");
	}
}

public void print() {
	System.out.println(this.name +"씨의 과정명은 "+this.subject+"이고 "+this.fee +"이며 "+ "환급금은 "+this.returnFee+"입니다.");
}

}
  • 실행 클래스 : Main
package day0620_2;

public class Main
{

	public static void main(String[] args)
	{
		Student st1 = new Student("이ㅇㄹ","javaprogram",30);
		st1.calcReturnFee(st1.subject);
		st1.print();
		
		Student st2 = new Student("서유미","javaprogram",40000);
		st2.calcReturnFee(st2.subject);
		st2.print();
		
		Student st3 = new Student("ㄴㄴㄴ","Engliesh",58000);
		st3.calcReturnFee(st3.subject);
		st3.print();

	}

}

예제 2

  • 라이브러리 클래스 : Calculator
package day0620_2;

public class Calculator 
{
	int num1, num2, result;
	
	Calculator(){} //기본생성자
	Calculator(int n1, int n2){ // 클래스는 객체 생성 => 데이터를 조작하는 작업 공
		this.num1 = n1;
		this.num2 =n2;
	}
	
	public int add() {
		int result = num1 + num2;
		return result;
	}
	
	public int sub() {
		int result = 0;
		if(num1>num2)
		 result = num1 - num2;
		else result = num2 - num1;
		return result;
	}
	
	public int multi() {
		int result = num1 * num2;
		return result;
	}
	
	public int div() {
		int result = 0;
		if(num2>0) {
		result = num1 / num2;}
		else System.out.println("0으로 나눌 수 없습니다.");
		return result;
	}
}
  • 실행 파일 : Main
package day0620_2;

public class Main1
{

	public static void main(String[] args)
	{
		Calculator cal = new Calculator(10, 20);
		
		System.out.println(cal.add());
		System.out.println(cal.sub());
		System.out.println(cal.multi());
		System.out.println(cal.div());

	}

}

3. 클래스의 구성 멤버

생성자, 필드, 메소드

  • 생성자
    • new 연산자로 객체 생성시 객체의 초기화 역

    • 객체 생성 시 호출되는 특수한 메소드로 new 연산자가 객체가 생성자 이용하여 객체 생성

      Book book = new Book();
    • 생성자의 특징

      • 생성자명은 클래스명과 동일
      • 메서드지만 반환형(리턴 타입)이 없는 형태
      • 선언형태는 메소드와 비슷
    • 디폴트 생성자

      • 생성자 명이 클래스명과 같다

      • 단 생성자 오버로딩이 되있다면 반드시 개발자는 디폴트생성자를 만들어줘야 한다.

        클래스(){};
    • 생성자 선언

      • 객체를 다양하게 초기화하기 위해 생성자를 직접 선언할 수 있음

        클래스(매개변수, ...){
        }
  • 필드
    • 객체의 데이터를 저장하는 역할. 선언 형태는 변수 선언과 비슷하지만 쓰임새는 다름
  • 메소드
    • 객체가 수행할 동작. 함수로도 불림
    • 필드는 클래스 블록에서 선언되어야 함
    • 타입은 필드에 저장할 데이터의 종류를 결정. 기본 타입, 참조 타입 모두 가능
    • 메소드 선언
      리턴타입 메소드명(매개변수,...){
      실행할 코드를 작성하는 곳..
      }
      boolean login(String i, String p) {
      		if(i.equals("hong")&&p.equals("12345")) {
      		return true;
      		}
      		else return false;
      	}

예제 : 생성자

  • 라이브러리 클래스 : Car
package day0620_2;

public class Car
{
	int gas;

	void setGas(int gas)
	{ // 리턴 값이 없는 메소드 매개변수 gas를 받아서 객체 변수 this.gas에 저장
		this.gas = gas;
	}

	// 리턴값이 boolean인 메소드로 gas 필드값이 0이면 false 0이 아니면 true를 리턴하는 isLeftGas()
	boolean isLeftGas()
	{
		if (gas == 0)
		{
			System.out.println("가스가 없다.");
			return false;
		} else
		{
			System.out.println("gas가 있습니다.");
			return true;
		}
	}

	// 리턴값이 없는 메소드로 run(), gas 필드값이 0이면, return 문으로 메소드 종료
	void run()
	{ // 리턴값이 없다 = void
		while (true)
		{
			if (gas > 0)
			{
				System.out.printf("달립니다.(gas잔량: %d)\n", this.gas);
				
				gas -=1; 
			}
			else {
				System.out.printf("멈춥니다.(gas잔량: %d)\n", this.gas);
				return; //리턴값이 없이 return만 적는다면 강제 종료
			}

		}
	}
}
  • 실행 클래스 : CarEX
package day0620_2;

public class CarEx
{

	public static void main(String[] args)
	{
		// 1. Car 객체 생성
		Car mycar = new Car();
		//2. gas 주입
		mycar.setGas(5);
		
		//mycar.isLeftGas();
		
		// 3, 실행
		if(mycar.isLeftGas()) {
			System.out.println("출발합니다.");
			mycar.run();
		}
		System.out.println("gas를 새로 주입해주세요.");
	}

}

응용문제

  • 입력을 받아서 처리하는 것
  • 라이브러리 클래스
public class MemberService
{
	String name;
	String id;
	String password;
	int age;
	
	MemberService(){}
	MemberService(String id, String password){
		this.id = id;
		this.password = password;
	}
 
	boolean login(String id, String password) {
		if(this.id.equals(id) && this.password.equals(password)) {
			return true;
		}else {
			return false;
		}
	}
	
	void logout(String id) {
		System.out.println(id + "님이 로그아웃 하셨습니다.");
	}	
		
	
}
  • 실행 클래스
package quiz0620;

import java.util.Scanner;

public class MemberServiceEx
{
	
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		System.out.println("회원가입");
		System.out.println("id를 입력하세요");
		String id = in.next();
		System.out.println("비밀번호를 입력하세요.");
		String pwd = in.next();
		
		MemberService m1 = new MemberService();
		
		System.out.println("회원 가입완료되었습니다. 로그인 하시려면 아이디와 패스워드를 입력해 주세요.");
		
		System.out.println("id를 입력하세요.");
		id = in.next();
		System.out.println("비밀번호를 입력하세요");
		pwd = in.next();
		
		boolean login = m1.login(id, pwd);
		
		if(login) System.out.println("로그인 성공");
		else System.out.println("로그인 실패");
		
		m1.logout(id);
	
	}
}

Quiz 개념

1. 객체와 클래스에 대한 설명으로 틀린 것? 3
- 클래스는 객체를 생성하기 위한 설계도와 같은 것이다.
- new 연산자로 클래스의 생성자를 호출함으로써 객체가 생성된다.
- 하나의 클래스로 하나의 객체만 생성할 수 있다. => 여러 개 생성 가능
- 객체는 클래스의 인스턴스이다.=> 해당 클래스에 적재되었다라는 느낌

2. 클래스 구성 멤버가 아닌 것은? 4
- 필드
- 생성자
- 메소드
- 로컬 변수 => 메소드 안의 지역 변

3. 필드, 생성자, 메소드에 대한 설명으로 틀린 것? 4
- 필드는 객체의 데이터를 저장
- 생성자는 객체의 초기화 담당
- 메소드는 객체의 동작 부분으로 실행 코드를 가지고 있는 블록
- 클래스는 반드시 필드와 메소드를 가져야 한다. => 반드시는 아님

4. 필드에 대한 설명으로 틀린 것? 3
- 필드는 메소드에서 사용 가능
- 인스턴스 필드 초기화는 생성자에서 가능
- 필드는 반드시 생성자 전에 선언 => x 어디서든 가능
- 필드는 초기값을 주지 않더라도 기본값 자동 초기화

5. 생성자에 대한 설명으로 틀린 것은?
- 객체 생성 시 생성자 호출이 반드시 필요한 것은 아니다. => 필요
- 생성자는 다른 생성자 호출을 위해 this() 사용 가능
- 생성자가 선언되지 않으면 컴파일러가 기본 생성자 추가
- 외부에서 객체 생성할 수 없도록 생성자에 private 접근 제한자 붙일 수 있음

6. 메소드에 대한 설명으로 틀린 것? 4
- 리턴값이 없는 메소드는 리턴 타입 void로 해야함
- 리턴 타입 있는 메소드는 리턴값을 지정하기 위해 반드시 return 문 필요
- 매개값 수를 모르면“...”이용해서 매개변수 선언 가능
- 메소드 이름 중복 선언 불가 => 메소드 오버로딩으로 가능

4. 필드 선언과 사용

필드 사용

  • 필드값을 읽고 변경하는 것 : 클래스로부터 객체가 생성된 후에 필드를 사용할 수 있음
  • 필드는 객체 내부의 생성자와 메소드 내부에서 사용할 수 있고, 객체 외부에서도 접근해서 사용할 수 있음

5. 인스턴스 멤버

인스턴스 멤버 선언 및 사용

  • 필드와 메서드
    • 선언방법에 따라 인스턴스 멤버와 정적멤버로 분류
    • 인스턴스 멤버로 선언이 되면 객체 생성 후 사용 가능
      • 객체에 소속된 멤버 = 인스턴스 멤버
      • this 키워드
        • 객체 내부에서는 인스턴스 멤버에 접근하기 위해 사용되는 명령어
        • 객체 자신을 this 라고 가르킨다.

6. 정적멤버

정적 멤버 선언

  • 정적 멤버 : 고정적으로 사용하는 멤버
  • 정적 필드, 정적 메소드, 정적 블럭은 공용의 의미로 적용하면 편리한 기능 제공
  • static은 static 끼리 사용가능
  • 정적멤버 선언되면 객체생성 없이 사용 가능
    • 직접 접근 가능
    • 공용으로 오픈해 놓아 누구나 편하게 호출하여, 사용하도록 함
static double pi = 3.14159; //static 키워드 붙여지면 정적멤버

final static

  • 초기화 되면 고정 값으로 읽기만 가능 쓰기 불가 => 값 변경 불가
final static String model ="LED1900";
final 타입 필드 = 초기값;
  • 초기화 하는 방법
    • 필드 선언시 초기값 대입
    • 생성자에서 초기값 대입

예제

  • 라이브러리 클래스
package day0620_2;

public class Television
{
	static String company = "SAMSUNG"; //누구나 봐야 하는 거기에 static
	final static String model ="LED1900"; // 읽기만 가능 쓰기 불가 => 값 변경 불가
	static String info;
	int speed; // static 안에 사용 불가 메모리 공간이 다르기 때문 
	void m1() {}
	
	static {
		String menu ="TV  메뉴 안내 입니다."; // 메모리 공간이 같아서 사용가능
		info = company + "-" +model;
		//m1(); 정적멤버와 인스턴스 멤버는 같은 공간에서 사용 불가 => main에서만 가능
	}
	
}
  • 실행 클래스
package day0620_2;

public class Main
{

	public static void main(String[] args)
	{
		
		// 1. static 부르기
		System.out.println(Television.info); //어디서든 출력 가능 => 원래대로라면 객체 생성했어야 하는디
		
		// 2. 객체 만들기 main에서만 1과 2를 혼재해서 사용 가능
 		Television t1 = new Television();
		int s = t1.speed;

	}

}

상수(불변의 값)

  • 객체마다 저장할 필요가 없다
  • static final 타입 상수 = 초기값;

7. 패키지

패키지 선언

  • 패키지 이름은 모두 소문자로 작성. 패키지 이름이 서로 중복되지 않도록 회사 도메인 이름의 역순으로 작성하고, 마지막에는 프로젝트 이름을 붙여줌 ⇒ 클래스 이름은 안넣음

자바의 패키지

  • 클래스의 일부분이며, 클래스를 식별하는 용도
  • 패키지는 주로 개발 회사의 도메인 이름 역순으로 만듦
  • 상위 패키지와 하위패키지를 .으로 구분
  • 패키지에 속한 바이트코드 파일(~.class)는 따로 떼어내어 다른 디렉토리로 이동

import문

  • 다른 패키지에 있는 클래스를 사용하려면 import 문을 이용해서 어떤 패키지의 클래스를 사용하는지 명시
  • import 문은 패키지 선언과 클래스 선언 사이에 작성
  • import 키워드 뒤에는 사용하고자 하는 클래스의 전체 이름을 기술
  • 패키지 구조

package javastudy1.day0620.hyundai;

import javastudy1.day0620.hankook.Tire;
import javastudy1.day0620.kumho.AllSeasonTire;
//import javastudy1.day0620.kumho.Tire;

public class Car
{
	javastudy1.day0620.hankook.Tire tire1 = new	javastudy1.day0620.hankook.Tire();
	javastudy1.day0620.kumho.Tire tire2 = new	javastudy1.day0620.kumho.Tire ();
	
	Tire t3 = new Tire();
	AllSeasonTire t4 = new AllSeasonTire();
}

8. 접근 제한자

  • 중요한 필드와 메소드가 외부로 노출되지 않도록 해 객체의 무결성을 유지하기 위해서 접근 제한자 사용

캡슐화

  • 정보의 은닉화를 위해 접근제한자를 이용 객체의 필드를 외부로 변경하거나, 메소드를 호출할 수 없도록 막아야 할 필요가 있다.
  • 중요한 필드나 메소드가 외부로 노출되지 않도록 객체의 무결

public, protected, private

  • public : 클래스, 필드, 생성자, 메소드 ⇒ 제한 범위 : 없음(같은 패키지도 다른 패키지도 사용 가능)
  • protected : 필드, 생성자, 메소드 ⇒ 제한 범위 : 같은 패키지이거나 자식 객체만 사용 가능
  • (defalut) : 클래스, 필드, 생성자, 메소드 ⇒ 제한범위 : 같은 패키지
  • private : 필드, 생성자,메소드 ⇒ 제한범위 : 객체 내부(=클래스 내부)

    private로 된 필드의 경우 필드에 한 해서 getter, setter해주면 a.getF3(), a.setF3() 느낌으로 간접 접근은 가능하다. ⇒ 간접 접근 방식

⇒ 필드나 메서드는 어디에서나 읽거나 호출할 수 있는 것이 아니고, 어떤 접근제한자를 갖느냐에 따라 호출 여부나 접근 여부가 결정

클래스의 접근 제한

  • 클래스 선언 시 public 접근 제한자 생략시 다른 패키지에서 사용 불가
  • 클래스 선언 시 public 접근 제한자를 붙이면 클래스는 같은 패키지 뿐 아니라 다른 패키지에서도 사용 가능
**public class Student
{
	private String name;
	private String subject;
	private int fee;
	private double returnFee;
	
	public Student(){};
	public Student(String name, String subject, int fee){
		this.name = name;
		this.subject = subject;
		this.fee=fee;
	}
	
	public void calcReturnFee() {
		if(subject.equals("javaprogram")) {
			returnFee = (double)fee/4;
		}
		else if(subject.equals("jspprogram")){
			returnFee = (double)fee/5;
		}
	}
	
	public void print() {
		System.out.printf("%s씨의 과정명은 %s이고  교육비는 %d이며 환급금은 %.1f입니다.", name, subject, fee, returnFee);
	}

	public static void main(String args[]){
		Student stu = new Student("장동건", "jspprogram", 500000);
		 stu.calcReturnFee();
		stu.print();
	}

}**

9. Getter와 Setter

Getter

  • 데이터를 검증해서 유효한 값만 필드에 저장

Setter

  • 필드값이 객체 외부에서 사용하기에 부적절한 경우, 적절한 값으로 변환해서 리턴할 수 있는 메소

package moringquiz0621;

public class Account {
    private int balance;
    private static final int MIN_BALANCE = 0;
    private static final int MAX_BALANCE = 1000000;

    public Account() {
    }

    public Account(int balance) {
        setBalance(balance);
    }

    public int getBalance() { //값이 밖에 보이기 위한 작업 반환이 꼭 있어야 함
        return balance;
    }

    public void setBalance(int balance) { //값을 세팅하면서 받고
        if (balance < MIN_BALANCE || balance > MAX_BALANCE) {
            return; //초과시 balance값 유지
        }
        this.balance = balance;
    }

    public static void main(String[] args) {
        Account account = new Account();

        account.setBalance(10000);
        System.out.println("현재 잔고: " + account.getBalance());

        account.setBalance(-100);
        System.out.println("현재 잔고: " + account.getBalance());

        account.setBalance(2000000);
        System.out.println("현재 잔고: " + account.getBalance());

        account.setBalance(30000);
        System.out.println("현재 잔고: " + account.getBalance());
    }
}

10. 싱글톤 패턴

싱글톤 패턴

  • 생성자를 private 접근 제한해서 외부에서 new 연산자로 생성자를 호출할 수 없도록 막아서
    외부에서 마음대로 객체를 생성하지 못하게 함
  • 대신 싱글톤 패턴이 제공하는 정적 메소드를 통해 접적으로 객체를 얻을 수 있음
  • 어플리케이션을 전체에서 단 하나의 객체만을 생성해서 사용하고 싶다면 싱글톤 패턴 적용
  • 싱글톤 패턴은 핵심은 생성자를 private 접근 제한해서 외부에서 new 연산자 호출할 수 없다.

구조

public class 클래스{
	private static 클래스 singletone = new 클래스();
	
	private 클래스() {};
	
	public static 클래스 getInstance() {
		return singletone;
	}
}

예시

public class SingleToneTest
{
	private static SingleToneTest singletone = new SingleToneTest();
	
	private SingleToneTest() {}
	
	public static SingleToneTest getInstance() {
		return singletone;
	}
}
public class Main
{

	public static void main(String[] args)
	{
		// 정적 메소드를 호출해서 싱글톤 객체를 얻어온다.
		SingleToneTest obj1 = SingleToneTest.getInstance();
		SingleToneTest obj2 = SingleToneTest.getInstance();
		
		if(obj1==obj2) {
			System.out.println("같은 객체값");
		}
		else System.out.println("다른 객체값");

	}

}

회고

TMI이지만 6월 20일은 내 생일이었다. 친구들이랑 생일 파티도 하고 다른 친구들이랑 근로에서 만나게 된 사람들한테까지 선물과 축하를 받아서 행복한 하루였다.
강의에 대한 회고를 하자면.. 오늘은 사람들이 전부 힘겨운 날이었나보다. 강사님께서도 그걸 느끼셨는지 쉬는 시간을 5분정도 더 주셨다.. 나도 일주일 내내 온전히 쉬는날이 없어서 인가 조금 지치긴 했다. 그래도 나는 과제는 밤새서라도 하는 주의라서 생일 파티하고 와서 밤 12시부터 새벽 4시까지 과제 해서 냈다.

공부하는 건 힘들지만 뭔가를 배운다는 건 두근거리고 좋은 일 같다. 어느정도 자바 떼고 나면 인프런 강의 듣는 것도 욕심 내보고 싶다. 주말에 강의 들으면서 복습 & 새로운 기술 공부 좀 해야지 화이팅!!!

profile
내 지식을 기록하여, 다른 사람들과 공유하여 함께 발전하는 사람이 되고 싶다. 참고로 워드프레스는 아직 수정중

0개의 댓글