λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

πŸ“šμ½μ€ μ±… 정리/μžλ°” 객체지ν–₯ 원리와 이해

[μŠ€ν”„λ§ μž…λ¬Έμ„ μœ„ν•œ μžλ°” 객체지ν–₯의 원리와 이해] 2μž₯ : μžλ°”μ™€ 절차적/ꡬ쑰적 ν”„λ‘œκ·Έλž˜λ°

μžλ°” ν”„λ‘œκ·Έλž˜λ° 개발과 ꡬ동

μžλ°”λŠ” μžλ°” κ°œλ°œλ„κ΅¬μΈ JDKλ₯Ό μ΄μš©ν•΄ 개발되고 개발된 ν”„λ‘œκ·Έλž¨μ€ JRE에 μ˜ν•΄ μ»΄ν“¨ν„°μ˜ JVM μƒμ—μ„œ κ΅¬λ™λœλ‹€.

- JDKλŠ” 컴파일러 포함

- JREλŠ” μžλ°” μ‹€ν–‰κΈ° 포함

- JVM은 μžλ°” 가상 기계

 

μžλ°” κ°œλ°œμžλŠ” 본인이 μ‚¬μš© 쀑인 ν”Œλž«νΌμ— μ„€μΉ˜λœ JVM용으둜 ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜κ³  λ°°ν¬ν•˜λ©΄
각 ν”Œλž«νΌμ— λ§žλŠ” JVM이 μ•Œμ•„μ„œ ν”„λ‘œκ·Έλž¨μ„ 아무 λ¬Έμ œμ—†μ΄ κ΅¬λ™μ‹œμΌœμ€€λ‹€.

-> μ΄λŸ¬ν•œ μžλ°”μ˜ νŠΉμ„±μ„ "Write Once Run Anywhere" 라고 ν•œλ‹€.

 

객체 지ν–₯ ν”„λ‘œκ·Έλž¨μ˜ λ©”λͺ¨λ¦¬ μ‚¬μš© 방식

λ©”λͺ¨λ¦¬ ꡬ성

ν”„λ‘œκ·Έλž¨ 싀행에 λ”°λ₯Έ T λ©”λͺ¨λ¦¬ ꡬ쑰 λ³€ν™”

Tλ©”λͺ¨λ¦¬ ꡬ쑰

Tλ©”λͺ¨λ¦¬ κ΅¬μ‘°λŠ” μŠ€νƒœν‹± μ˜μ—­, μŠ€νƒ μ˜μ—­, νž™ μ˜μ—­μœΌλ‘œ λ‚˜λˆŒ 수 μžˆλ‹€.

 

μ‹€ν–‰ μ½”λ“œ

public class Start {
	public static void main(String[] args) {
		System.out.println("Hello OOP!!!");
	}
}

main() λ©”μ„œλ“œ μ‹€ν–‰λ˜κΈ° μ „ JVMμ—μ„œ μˆ˜ν–‰ν•˜λŠ” μ „μ²˜λ¦¬ μž‘μ—…

  • java.lang νŒ¨ν‚€μ§€λ₯Ό T λ©”λͺ¨λ¦¬ μŠ€νƒœν‹± μ˜μ—­μ— 배치
  • import 된 νŒ¨ν‚€μ§€λ₯Ό T λ©”λͺ¨λ¦¬ μŠ€νƒœν‹± μ˜μ—­μ— 배치
  • ν”„λ‘œκ·Έλž¨ μƒμ˜ λͺ¨λ“  클래슀λ₯Ό T λ©”λͺ¨λ¦¬ μŠ€νƒœν‹± μ˜μ—­μ— 배치

메인 λ©”μ„œλ“œκ°€ μ‹€ν–‰λ˜λ €λ©΄ 메인 λ©”μ„œλ“œλ₯Ό μœ„ν•œ "μŠ€νƒ ν”„λ ˆμž„"이 ν•„μš”ν•˜λ‹€. 이λ₯Ό μŠ€νƒ μ˜μ—­μ— 확보해쀀닀.

이후 λ©”μ„œλ“œμ˜ "인자λ₯Ό μ €μž₯ν•  λ³€μˆ˜κ³΅κ°„"을 μŠ€νƒ ν”„λ ˆμž„μ˜ 맨 밑에 ν™•λ³΄ν•œλ‹€.

메인 λ©”μ„œλ“œ μŠ€νƒ ν”„λ ˆμž„κ³Ό 인자 λ³€μˆ˜ 곡간

κ°„λ‹¨ν•œ ν”„λ‘œκ·Έλž¨μ„ μ‹œμž‘ν•˜κΈ° μœ„ν•΄ JREλŠ” λ’€μ—μ„œ JVMμ΄λΌλŠ” 가상 머신을 λΆ€νŒ…ν•˜κ³  JVM은 λ©”λͺ¨λ¦¬ ꡬ쑰λ₯Ό λ§Œλ“€μ–΄ 각쒅 νŒ¨ν‚€μ§€ λ‘œλ”©, 메인 λ©”μ„œλ“œ μŠ€νƒ ν”„λ ˆμž„ 배치, λ³€μˆ˜ 곡간 배치 λ“±μ˜ 일을 μ²˜λ¦¬ν–ˆλ‹€.

 

λ©”μ„œλ“œμ˜ 끝을 λ‚˜νƒ€λ‚΄λŠ” λ‹«λŠ” μ€‘κ΄„ν˜Έλ₯Ό λ§Œλ‚˜λ©΄ μƒμ„±ν•œ "μŠ€νƒ ν”„λ ˆμž„"이 사라진닀.
ν”„λ‘œκ·Έλž¨μ˜ μ‹œμž‘μ μΈ 메인 λ©”μ„œλ“œκ°€ λλ‚˜λ©΄ JREλŠ” JVM을 μ’…λ£Œν•˜κ³  JRE μžμ²΄λ„ 운영체제 μƒμ˜ λ©”λͺ¨λ¦¬μ—μ„œ μ‚¬λΌμ§€κ²Œ λœλ‹€.

 

λ³€μˆ˜μ™€ 블둝을 μƒμ„±ν•˜λ©΄ λ©”λͺ¨λ¦¬ κ΅¬μ‘°λŠ” μ–΄λ–»κ²Œ λ³€ν™”ν• κΉŒ?

μ‹€ν–‰ μ½”λ“œ

public class Start2 {
	public static void main(String[] args) {
		int i;
		i = 10;

		double d = 20.0;
	}
}

μ‹€ν–‰ ν›„ λ©”λͺ¨λ¦¬ ꡬ쑰

iλ₯Ό μ„ μ–Έν•˜κ²Œ 되면 JVM이 i λ³€μˆ˜λ₯Ό μœ„ν•œ μŠ€νƒ 곡간을 ν™•λ³΄ν•œλ‹€. 이 ν›„ 값을 ν• λ‹Ήν•˜λ©΄ λ³€μˆ˜ 곡간에 값을 ν• λ‹Ήν•˜κ²Œ λœλ‹€.

dλŠ” μ„ μ–Έκ³Ό λ™μ‹œμ— 값을 ν• λ‹Ήν–ˆλ‹€. λ˜‘κ°™μ΄ μŠ€νƒ 곡간을 λ¨Όμ € ν™•λ³΄ν•˜κ³  값을 ν• λ‹Ήν•˜κ²Œ λœλ‹€.

블둝 μŠ€νƒ ν”„λ ˆμž„

if 블둝 μ‚¬μš©μ‹œμ—λ„ μƒˆλ‘œμš΄ μŠ€νƒ ν”„λ ˆμž„μ΄ μƒμ„±λœλ‹€.

 

이 λ•Œ if 블둝 밖에 μžˆλŠ” 메인 λ©”μ„œλ“œ λ‚΄ λ³€μˆ˜μ—λŠ” 접근이 κ°€λŠ₯ν•˜λ‹€.

 

ν•˜μ§€λ§Œ, 메인 λ©”μ„œλ“œμ—μ„œλŠ” if문에 μžˆλŠ” λ³€μˆ˜μ— μ ‘κ·Όν•  수 μ—†λ‹€.

-> 메인 λ©”μ„œλ“œ μ‹€ν–‰ μ‹œμ—λŠ” [if μŠ€νƒ ν”„λ ˆμž„]이 μ‘΄μž¬ν•  수 μ—†μœΌλ―€λ‘œ...

 

λ³€μˆ˜λŠ” 어디에 μ‘΄μž¬ν• κΉŒ?

"λ³€μˆ˜λŠ” λ©”λͺ¨λ¦¬μ— μ‘΄μž¬ν•œλ‹€."

λ³€μˆ˜λŠ” μŠ€νƒ, νž™, μŠ€νƒœν‹± μ˜μ—­ 3ꡰ데 λͺ¨λ‘μ— μ‘΄μž¬ν•œλ‹€.

 

지역 λ³€μˆ˜λŠ” μŠ€νƒ ν”„λ ˆμž„ μ•ˆμ—μ„œ 일생을 보낸닀.

클래슀 멀버 λ³€μˆ˜λŠ” μŠ€νƒœν‹± μ˜μ—­μ—μ„œ 일생을 보낸닀. (μŠ€νƒœν‹± μ˜μ—­μ— 자리작으면 JVM이 μ’…λ£Œλ  λ•ŒκΉŒμ§€ κ³ μ •λœ(static)μƒνƒœλ‘œ μ˜μ—­μ„ 차지함)

객체 멀버 λ³€μˆ˜λŠ” νž™ μ˜μ—­μ—μ„œ 일생을 보낸닀. (객체 멀버 λ³€μˆ˜λ“€μ€ 객체와 ν•¨κ»˜ "가비지 컬렉터"에 μ˜ν•΄ 일생을 마침)

 

λ©”μ„œλ“œ 호좜과 λ©”λͺ¨λ¦¬

μ‹€ν–‰ μ½”λ“œ

public class Start4 {
	public static void main(String[] args) {
		int k = 5;
		int m;

		m = square(k);
	}

	private static int square(int k) {
		int result;
		
		k = 25;

		result = k;

		return result;
	}
}

ν΄λž˜μŠ€μ— square λ©”μ„œλ“œκ°€ μΆ”κ°€λ˜κ³  메인 λ©”μ„œλ“œ 싀행도쀑 square()λ©”μ„œλ“œκ°€ μ‹€ν–‰λ˜λ©΄ λ©”λͺ¨λ¦¬ κ΅¬μ‘°λŠ” μ–΄λ–»κ²Œ 될까?

λ©”λͺ¨λ¦¬ ꡬ쑰

 

  • sqaureλ©”μ„œλ“œλŠ” μƒˆλ‘œμš΄ μŠ€νƒ ν”„λ ˆμž„μ„ λ§Œλ“ λ‹€.
  • squareλ©”μ„œλ“œμ˜ k와 메인 λ©”μ„œλ“œμ˜ kλŠ” μ΄λ¦„은 κ°™μ§€λ§Œ μ™„μ „νžˆ λ³„λ„μ˜ λ³€μˆ˜ 곡간을 κ°€μ§€λ―€λ‘œ μ„œλ‘œμ—κ²Œ 영ν–₯을 주지 μ•ŠλŠ”λ‹€.
  • square의 result 값은 λ©”μ„œλ“œ μ’…λ£Œ μ‹œ μ‚¬λΌμ§€λ―€λ‘œ "λ°˜ν™˜ κ°’"에 λ³΅μ‚¬ν•˜κ³  ν•¨μˆ˜λ₯Ό μ’…λ£Œν•΄μ•Όλ§Œ λ©”μΈμ—μ„œ 값을 받을 수 μžˆλ‹€.
  • λ©”μ„œλ“œμ˜ λΈ”λž™λ°•μŠ€ν™” -> μž…λ ₯κ°’κ³Ό λ°˜ν™˜κ°’μ— μ˜ν•΄μ„œλ§Œ λ©”μ„œλ“œ 사이에 값이 전달될 뿐 μ„œλ‘œ λ‚΄λΆ€μ˜ μ§€μ—­λ³€μˆ˜λ₯Ό λ³Ό 수 μ—†λ‹€.

λ©”μ„œλ“œ κ°„ λ³€μˆ˜ μ°Έμ‘°λ₯Ό κΈˆμ§€ν•œ 이유

1. λ©”μ„œλ“œλŠ” μžμ‹ λ§Œμ˜ κ³ μœ ν•œ κ³΅κ°„μ΄λ―€λ‘œ μΉ¨λ²”ν•˜λ©΄ μ•ˆλœλ‹€.

2. μ„œλ‘œμ˜ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜λ €λ©΄ μœ„μΉ˜(μ£Όμ†Œ)λ₯Ό μ•Œμ•„μ•Ό ν•˜λŠ”λ° 그럴러면 포인터가 ν•„μš”ν•˜λ‹€. (포인터 μ—†λŠ”κ²Œ μžλ°”μ˜ μž₯점)

3. 포인터가 μ—†μ–΄μ„œ λ©”μ„œλ“œκ°„ λ³€μˆ˜ μ°Έμ‘°κ°€ λΆˆκ°€λŠ₯ν•˜λ‹€.

 

μžλ°”λŠ” λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ 인자λ₯Ό μ €μž₯ν•œ 값을 λ³΅μ‚¬ν•΄μ„œ μ „λ‹¬ν•˜λŠ” "Call by value"방식을 μ‚¬μš©ν•˜κ³  μžˆλ‹€.

 

객체λ₯Ό λ„˜κΈ°λŠ” 것도 객체의 μ£Όμ†Œκ°’μ„ λ³΅μ‚¬ν•΄μ„œ λ„˜κΈ°λŠ” 것이닀.

-> μžλ°”λŠ” 사싀상 "Call by reference"κ°€ μ—†λ‹€.

μ „μ—­λ³€μˆ˜μ™€ λ©”λͺ¨λ¦¬

μ‹€ν–‰ μ½”λ“œ

public class Start5 {
	static int share;

	public static void main(String[] args) {
		share = 55;

		int k = fun(5, 7);

		System.out.println(share);
	}

	private static int fun(int m, int p) {
		share = m + p;

		return m - p;
	}
}

μ‹€ν–‰ 쀑간 λ©”λͺ¨λ¦¬ ꡬ쑰

μ „μ—­ λ³€μˆ˜λŠ” μŠ€νƒœν‹± μ˜μ—­μ— ν• λ‹Ήλ˜λŠ” 것을 확인할 수 μžˆλ‹€.

λ˜ν•œ, 메인 λ©”μ„œλ“œμ™€ fun()λ©”μ„œλ“œ 두 κ³³ λͺ¨λ‘μ—μ„œ λ³€μˆ˜μ— μ ‘κ·Όμžˆλ‹€.
(μŠ€νƒ ν”„λ ˆμž„μ— 독립전인 μ „μ—­ λ³€μˆ˜)

 

μ „μ—­ λ³€μˆ˜λŠ” ν”„λ‘œμ νŠΈ 규λͺ¨κ°€ 컀지면 κ°’μ˜ λ³€ν™”λ₯Ό μΆ”μ ν•˜κΈ°κ°€ μ–΄λ ΅λ‹€. λ˜λ„λ‘ ν”Όν•˜μž.

λ©€ν‹° μŠ€λ ˆλ“œ / λ©€ν‹°ν”„λ‘œμ„ΈμŠ€μ˜ 이해

λ©€ν‹°μŠ€λ ˆλ“œ

λ©€ν‹°μŠ€λ ˆλ“œλŠ” μŠ€νƒμ˜μ—­μ„ λΆ„ν• ν•΄μ„œ μ‚¬μš©

λ©€ν‹° ν”„λ‘œμ„ΈμŠ€

λ©€ν‹° ν”„λ‘œμ„ΈμŠ€λŠ” λ‹€μˆ˜μ˜ Tλ©”λͺ¨λ¦¬λ₯Ό 생성해 μ‚¬μš©

  • λ©€ν‹° μŠ€λ ˆλ“œλŠ” μŠ€νƒ μ˜μ—­λ§Œ λΆ„ν• ν–ˆμœΌλ―€λ‘œ ν•˜λ‚˜μ˜ μŠ€λ ˆλ“œμ—μ„œ λ‹€λ₯Έ μŠ€λ ˆλ“œμ˜ μŠ€νƒœν‹± μ˜μ—­κ³Ό νž™ μ˜μ—­μ€ κ³΅μœ ν•΄μ„œ μ‚¬μš©ν•  수 μžˆλ‹€.
    • λ©€ν‹° ν”„λ‘œμ„ΈμŠ€ λŒ€λΉ„ λ©”λͺ¨λ¦¬λ₯Ό 적게 μ‚¬μš©ν•˜λŠ” ꡬ쑰
  • λ©€ν‹° ν”„λ‘œμ„ΈμŠ€λŠ” ν•˜λ‚˜μ˜ ν”„λ‘œμ„ΈμŠ€κ°€ λ‹€λ₯Έ ν”„λ‘œμ„ΈμŠ€μ˜ T λ©”λͺ¨λ¦¬ μ˜μ—­μ„ μ ˆλŒ€ μΉ¨λ²”ν•  수 μ—†λŠ” ꡬ쑰
    • μ•ˆμ „ν•œ κ΅¬μ‘°μ΄μ§€λ§Œ λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ€ 크닀.

-> μš”μ²­λ‹Ή μŠ€λ ˆλ“œ(Servlet)κ°€ μš”μ²­λ‹Ή ν”„λ‘œμ„ΈμŠ€(CGI)보닀 효율적인 이유

 

-> λ©€ν‹°μ“°λ ˆλ“œμ—μ„œ μ „μ—­λ³€μˆ˜ μ‚¬μš©μ€ 문제λ₯Ό λ°œμƒμ‹œν‚€κ³  해결을 μœ„ν•œ lock은 λ©€ν‹°μŠ€λ ˆλ“œμ˜ μž₯점을 버린 것과 κ°™λ‹€