## 커리큘럼(12-30/변경)
```
01. Java (v)
02. git 
03. Database
04. Jsp [Server]

05. 미니프로젝트 (3W)
06. HTML,CSS  
07. JS

08. SpringFramework , SrpingBoot
09. React JS [Front-end]
10. 중간프로젝트 (1M)
11. Linux 명령어
12. AWS 클라우드
13. DevOps - Docker
14. App - Android
15. 최종프로젝트 (1M)
```
---

# 정적 제한자 Static
- 사용 제한자(Usage Level modifier)
- static 제한자는 **변수, 메서드에 적용**되는 자바 키워드
- **static 메서드**나 변수는 **해당 클래스의 객체 없이도 참조 가능**(객체 생성을 통한 참조도 가능능)
- **static 블록 안**(static 메서드, 정적 초기화자)에는 **static변수만 사용**해야하고, **static메서드만 호출** 가능 
	+ 즉 **static 블록에서 non-static 멤버를 객체 생성 없이 직접 참조 불가**
- static제한자는 지정된 변수와 메서드를 객체와 무관하게 만들어주기 때문에 **this를 가질수 없음**
- static 메서드는 **non-static 메서드로 재정의 될 수 없음**
- 대표적인 static메서드는 애플리케이션의 main()메서드
- static에 단순히 블록({})을 사용한 경우에는 정적 초기화자라고 부르며, static 변수를 초기화하는 역할을 가지고 클래스가 로딩될 때 main()메서드가 있더라도 그보다 앞서 딱 한번 실행


```
static {
    System.out.println("Static block is executed.");
    staticVariable = 10; // static 변수 초기화
}

public static void main(String args[]){
	System.out.println("Main method is executed.");

	System.out.println(staticVariable);
}

// 실행결과
>> Static block is exectued.
>> Main method is executed.
>> 10
```

## 정적 변수(static field)
- **static 변수**는 모든 객체들이 공유하는 **공유변수**가 됨
- 객체 생성 없이 클래스 이름만으로 참조 가능(객체를 만들어 참조할 수도 있음)


```
public static void main(String args[]){
	Count c1 = new Count();
	c1.a++;
	c1.b++;
	System.out.println(c1.a); // non-static변수
	System.out.println(c1.b); // static변수

	//----------------------------------------
	// 실행결과
	// >> 1
	// >> 1
	// ----------------------------------------
	Count c2 = new Count();
	c2.a++;
	c2.b++;
	System.out.println(c2.a); // non-static 변수
	System.out.println(c2.b); // static 변수

		//----------------------------------------
	// 실행결과
	// >> 1
	// >> 2           // 모든 객체들이 공유하는 공유변수
	// ----------------------------------------
	System.out.println(c1.b); // Count 클래스에 있는 static 변수 b
	System.out.println(Count.b);
}
```

## 정적 메서드(static method)
- **static 메서드**는 sdtatic 변수와 마찬가지로 해당 클래스의 **객체 생성 없이도 참조가 가능**
- static 메서드에서 멤버를 참조할 때 주의해야 할 사항은 **static 메서드 안에서는 non-static 멤버를 객체 생성 없이 직접 참조할 수 없다**는것
- **static 메서드 안**에서는 **static 변수를 선언할 수 없음**


```
// static 패키지
public class Count{
	public int a =0;
	public static int b=0;

	public static int doIt(){
//		return ++a; // static메서드 안에서는 non-static 멤버를 객체 생성 없이 직접 참조할 수 없음
		return ++b;
	}
}

public class StaticMethodExample{
	public static void main(String args[]){
		System.out.println(count.doIt());
		System.out.println(count.doIt());
		System.out.println(count.doIt());
	}
}

// 실행 결과
>> 1
>> 2
>> 3
```

## 정적 초기화자(static Initializer)
- 정적 초기화자는 **static 변수들의 초기화에 사용**
	- static 변수는 객체 생성 없이도 사용해야하므로 생성자를 통해 초기화할 수 없음
- 정적 초기화자는 **클래스가 로딩될 때 생성자와 main() 메서드에 앞서 오직 단 한번만 실행**
	- **애플리케이션 실행 중 반드시 한번만 실행되어야 할 로직이 있다면 이곳에 기술**


```
public class StaticInit{
	// static initializer
	static{
		System.out.println("static initializer가 수행됨");
	}
	public staticInit(){
		System.out.println("constructor 호출");
	}
}

public class StaticInitExample{
	public static void main(String args[]){
		StaticInit a1 = new StaticInit();
		System.out.println(s1);
		StaticInit a2 = new StaticInit();
		System.out.println(s2);
		System.out.println("main() 메서드 종료");
	}
}

// 실행결과
// >> static initializer가 수행됨    // 정적 초기화자 실행
// >> Constructor 호출
// >> static_.StaticInit@주소1
// >> Constructor 호출
// >> static_.StaticConstructor@주소2
// >> main() 메서드 종료
```

### staic 요약
+ static멤버는 **객체 생성 없이 클래스명.이름 으로 참조 가능**
+ **static변수**는 **객체간 값의 공유**를 의미
+ **static메서드**는 **같은 static멤버만 참조가능** (클래스명.메서드명 으로 참조)
	- static메서드의 예시


	```
		Math.random();
		Arrays.toString(배열명);
		Integer.parseInt(문자열);
	```

## 싱글톤 패턴(Singleton Design Pattern)
- **어떤 클래스의 객체는 오직 하나임을 보장**하며, 이 객체에 접근할 수 있는 전역적인 접촉점을 제공하는 패턴
- **클래스 객체를 유일하게 하나만 생성**하여 모든 곳에서 하나의 객체에 접근하게 하여, **전역의 개념으로 객체를 사용**할 수 있음.
- **객체의 생성을 제한**하기 위해 사용


```
public class Compnay{
	private String str;

	private static Company c = new Company(); // static 객체 생성

	private Company(){
		str= "company";
		System.out.println(str);
	}

	// getter메서드를 이용해 객체반환
	public static Company getCompany(){
		return c;
	}
}

public class SingletonExample{
	public static void main(String args[]){
		Company c1= Company.getCompany();
		Company c2 =Company.getComapny();

		System.out.println(c1==c2); // true
	
	}
}
```

---
# 금지의 규제 final
## final 키워드
+ 클래스, 메서드, 변수에 적용되며 abstract와 동시에 사용될 수 없음
+ **final 클래스의 경우에는 상속이 안됨**(서브클래스를 가질 수 없음);
+ **재정의 불가**
+ **변수 값 변경 불가**


## final 클래스(final class)
+ 클래스 선언 시 final을 사용하면 그 클래스는 상속불가
+ 자식 클래스를 가질 수 없고, 오직 외부에서 객체 생성을 통해서만 사용 가능
	+ <대표적인 예> : String 클래스

## final 메서드(final method)
+ final 메서드는 자식 클래스에서 부모 클래스의 **메서드를 재정의(오버라이딩)하지 못하게 함**
+ 클래스에 final이 붙지 않는다면 상속은 가능하므로 자식 클래스에서 final 메서드의 참조는 가능
+ 자식 클래스에서 반드시 부모의 메서드를 기능의 변경없이 사용하도록 강요할 경우 final 메서드 선언

## final 변수(final variable)
+ **한번 값을 할당**하면 그 **값을 변경할 수 없음**
+ final 변수는 선언시에 초기화하는 방법과 생성자를 통하여 초기화하는 방법이 있는데 만약 초기화하지 않고 남겨두면 컴파일 에러 발생


## 상수(constant)
+ 자바에서는 **불변의 값을 저장하는 필드**를 상수라고 부름
+ 객체마다 저장할 필요가 없는는 공용성을 가져야 하며, 여러가지 값으로 초기화 될수 없기 때문에 **static과 final 제한자를 동시에 붙여 선언**
+ 상수 이름은 모두 대문자로 작성하는 것이 관례, 연결된 단어라면 "_"로 연결
	+ ex) `public static final long VERSION = 1L;`
---

# 추상 - abstract
+ **클래스와 메서드**에 적용
+ 추상(abstract) 클래스는 **실체 클래스들의 메서드들의 이름을 통일할 목적**으로 사용
+ **추상(abstract) 메서드가 있는 클래스**는 반드시 **추상 클래스**여야 함 
+ 추상 클래스에 반드시 추상 메서드만 선언할 필요는 없고 일반 메서드도 선언 가능

## 추상 클래스(abstarct class)
+ 추상 클래스는 new 키워드를 이용해서 객체를 만들지 못하고 **오직 상속을 통해서 자식 클래스로 구체화** 시켜야함
+ 추상 클래스도 일반 클래스와 마찬가지로 **멤버변수, 생성자, 메서드를 선언 가능**
+ new를 사용해 직접 생성자를 호출할 수는 없지만 **자식 객체가 생성될 때 super()를 호출해 추상 클래스 객체를 생성**하므로 **추상 클래스도 생성자가 반드시 있어야함**

## 추상 메서드(abstract method)
+ **추상 클래스내에서만 선언 가능**
+ **메서드의 선언부만 있고 메서드 실행 내용이 들어가는 중괄호{}가 없는 메서드**
+ 추상 클래스를 설계할 때 자식 클래스가 반드시 실행 내용을 채우도록 강요하고 싶은 메서드가 있을 경우, 해당 메서드를 추상 메서드로 선언
+ **자식 클래스에서 반드시 부모 추상클래스의 추상 메서드를 재정의**하여 실행내용을 작성해야함
