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

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

[μŠ€ν”„λ§ μž…λ¬Έμ„ μœ„ν•œ μžλ°” 객체 지ν–₯의 원리와 이해] 4μž₯ : μžλ°”κ°€ ν™•μž₯ν•œ 객체 지ν–₯

abstract ν‚€μ›Œλ“œ - 좔상 λ©”μ„œλ“œμ™€ 좔상 클래슀

좔상 λ©”μ„œλ“œλ₯Ό ν•˜λ‚˜λΌλ„ 가지고 μžˆλŠ” 클래슀λ₯Ό 좔상 클래슀라고 λΆ€λ₯Έλ‹€.

 

λ„λŒ€μ²΄ μ™œ λͺΈμ²΄κ°€ 없이 μ„ μ–Έλ§Œ μžˆλŠ” λ©”μ„œλ“œκ°€ ν•„μš”ν• κΉŒ??

 

**문제점**

1. 동물 ν΄λž˜μŠ€λŠ” μ–΄λ–»κ²Œ μšΈμ–΄μ•Ό ν•˜λŠ”μ§€ λͺ¨λ₯Έλ‹€. (μš°λŠ” λ©”μ„œλ“œλ₯Ό μ •μ˜ν•  수 μ—†λ‹€.. -> μ •μ˜ν•˜λ”λΌλ„ μΈμŠ€ν„΄μŠ€λ‘œ 생성해선 μ•ˆλœλ‹€.)

2. 그런데 동물 μ°Έμ‘° λ³€μˆ˜λ₯Ό 톡해 λͺ¨λ“  동물을 μšΈκ²Œν•˜κ³  μ‹Άλ‹€. (ν•˜μœ„ν΄λž˜μŠ€μ—μ„œ μ˜€λ²„λΌμ΄λ“œ ν•  μƒμœ„ λ©”μ„œλ“œκ°€ ν•„μš”ν•¨...)

 

**ν•΄κ²° 방법**

좔상 ν΄λž˜μŠ€μ™€ 좔상 λ©”μ„œλ“œ μ‚¬μš©ν•˜λ©΄ 1번의 문제λ₯Ό ν•΄κ²°κ°€λŠ₯ν•˜λ‹€. μš°λŠ” λ©”μ„œλ“œλŠ” ν•˜μœ„ ν΄λž˜μŠ€μ—κ²Œ κ΅¬ν˜„μ„ 맑길 수 있고 μΆ”μƒν΄λž˜μŠ€λŠ” μΈμŠ€ν„΄μŠ€κ°€ 될 수 μ—†λ‹€. (문제점 λͺ¨λ‘ ν•΄κ²°!!)

 

2번 λ¬Έμ œλ„ 좔상 λ©”μ„œλ“œλ‘œ ν•˜μœ„ν΄λž˜μŠ€μ—κ²Œ λ©”μ„œλ“œμ˜ κ΅¬ν˜„μ„ κ°•μ œν•  수 μžˆλ‹€. (κ΅¬ν˜„ μ•ˆν•˜λ©΄ 컴파일 μ—λŸ¬)

λ˜ν•œ, μƒμœ„ 클래슀의 μ°Έμ‘° λ³€μˆ˜λ‘œ ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œ μ˜€λ²„λΌμ΄λ“œν•œ λ©”μ„œλ“œ 호좜이 κ°€λŠ₯해진닀!

 

  • 좔상 ν΄λž˜μŠ€λŠ” μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€ 수 μ—†λ‹€ (new μ‚¬μš© λΆˆκ°€)
  • 좔상 λ©”μ„œλ“œλŠ” ν•˜μœ„ ν΄λž˜μŠ€μ—κ²Œ λ©”μ„œλ“œμ˜ κ΅¬ν˜„μ„ κ°•μ œν•œλ‹€.
  • 좔상 λ©”μ„œλ“œλ₯Ό ν¬ν•¨ν•˜λŠ” ν΄λž˜μŠ€λŠ” λ°˜λ“œμ‹œ 좔상 ν΄λž˜μŠ€μ—¬μ•Ό ν•œλ‹€.

μƒμ„±μž

객체λ₯Ό μƒμ„±ν•˜λŠ” λ©”μ„œλ“œ (객체 μƒμ„±μž λ©”μ„œλ“œ) = μƒμ„±μž

μƒμ„±μžμ— λŒ€ν•œ μžλ°”μ˜ νŠΉμ§•

  • κ°œλ°œμžκ°€ μ•„λ¬΄λŸ° μƒμ„±μžλ„ λ§Œλ“€μ§€ μ•ŠμœΌλ©΄ κΈ°λ³Έ μƒμ„±μžλ₯Ό μžλ™μœΌλ‘œ λ§Œλ“€μ–΄μ€Œ
  • μΈμžκ°€ μžˆλŠ” μƒμ„±μžλ₯Ό ν•˜λ‚˜λΌλ„ λ§Œλ“€λ©΄ μžλ°”λŠ” κΈ°λ³Έμƒμ„±μžλ₯Ό λ§Œλ“€μ§€ μ•ŠμŒ.

클래슀 생성 μ‹œμ˜ μ‹€ν–‰ 블둝, static 블둝

public class Driver05 {
	public static void main(String[] args) {
		System.out.println("main λ©”μ„œλ“œ μ‹œμž‘!");
		System.out.println(Animal.age);
	}
}

class Animal {
	static int age = 0;

	static {
		System.out.println("Animal class ready on!");
	}
}

μœ„ μ½”λ“œμ—μ„œ Animal의 μŠ€νƒœν‹± 블둝은 μ–Έμ œ 처음 μ‹€ν–‰λ κΉŒ?

정닡은 Animal.age둜 정적 속성을 μ‚¬μš©ν•  λ•Œμ΄λ‹€.

 

ν•΄λ‹Ή ν΄λž˜μŠ€κ°€ μ½”λ“œμ—μ„œ 맨 처음 μ‚¬μš©λ  λ•Œ T λ©”λͺ¨λ¦¬ μŠ€νƒœν‹± μ˜μ—­μ— λ‘œλ”©λ˜λ©°, 이 λ•Œ 단 ν•œλ²ˆλ§Œ static 블둝이 μ‹€ν–‰λœλ‹€.

 

**ν΄λž˜μŠ€κ°€ 제일 처음 μ‚¬μš©λ˜λŠ” 경우**

  • 클래슀의 정적 속성 μ‚¬μš©ν•  λ•Œ
  • 클래슀의 정적 λ©”μ„œλ“œ μ‚¬μš©ν•  λ•Œ
  • 클래슀의 μΈμŠ€ν„΄μŠ€ λ§Œλ“€ λ•Œ

κΈ°μ–΅ν•΄μ•Όν•  것

1. Tλ©”λͺ¨λ¦¬ ꡬ쑰 상 μŠ€νƒœν‹± λΈ”λ‘μ—μ„œ μ‚¬μš©ν•  수 μžˆλŠ” 속성과 λ©”μ„œλ“œλŠ” static 멀버 뿐이닀. 

-> 일반 객체 λ©€λ²„λŠ” 아직 생성 μ „μ΄λ―€λ‘œ μ ‘κ·Όν•  수 μ—†λ‹€.

2. ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ μ‹œ 클래슀λ₯Ό λ°”λ‘œ staticμ˜μ—­μ— λ‘œλ”©ν•˜μ§€ μ•ŠλŠ” 것은 λ©”λͺ¨λ¦¬λ₯Ό μ’€ 더 효율적으둜 μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œμ΄λ‹€.

-> ν•œλ²ˆ λ‘œλ”©λ˜λ©΄ μ’…λ£Œμ „κΉŒμ§€ static μ˜μ—­μ—μ„œ λ©”λͺ¨λ¦¬ λ°˜ν™˜ λΆˆκ°€..

 

final ν‚€μ›Œλ“œ

λ§ˆμ§€λ§‰, μ΅œμ’… 클래슀, λ³€μˆ˜, λ©”μ„œλ“œ..

 

final과 클래슀

final ν΄λž˜μŠ€λŠ” 상속을 ν—ˆλ½ν•˜μ§€ μ•ŠλŠ”λ‹€. (ν•˜μœ„ 클래슀λ₯Ό λ§Œλ“€ 수 μ—†λ‹€.)

 

final κ³Ό λ³€μˆ˜

public class 고양이 {
	final static int μ •μ μƒμˆ˜1 = 1;
	final static int μ •μ μƒμˆ˜2;

	final int κ°μ²΄μƒμˆ˜1 = 1;
	final int κ°μ²΄μƒμˆ˜2;

	static {
		μ •μ μƒμˆ˜2 = 2;

		// μƒμˆ˜λŠ” ν•œλ²ˆ μ΄ˆκΈ°ν™” 되면 값을 λ³€κ²½ν•  수 μ—†λ‹€.
		// μ •μ μƒμˆ˜2 = 4;
	}

	고양이() {
		κ°μ²΄μƒμˆ˜2 = 2;

		// μƒμˆ˜λŠ” ν•œλ²ˆ μ΄ˆκΈ°ν™” 되면 값을 λ³€κ²½ν•  수 μ—†λ‹€.
		// κ°μ²΄μƒμˆ˜2 = 4;

		final int μ§€μ—­μƒμˆ˜1 = 1;
		final int μ§€μ—­μƒμˆ˜2;

		μ§€μ—­μƒμˆ˜2 = 2;
	}
}

-> final λ³€μˆ˜ μ΄ˆκΈ°ν™” 방법!

final static을 μ •μ˜λœ 정적 μƒμˆ˜λŠ” μ„ μ–Έκ³Ό λ™μ‹œμ— μ΄ˆκΈ°ν™”ν•˜κ±°λ‚˜ 정적 μƒμ„±μžμ— ν•΄λ‹Ήν•˜λŠ” static 블둝 λ‚΄λΆ€μ—μ„œ μ΄ˆκΈ°ν™” κ°€λŠ₯.

final [type]으둜 μ •μ˜λœ 객체 μƒμˆ˜λŠ” λ˜‘κ°™μ΄ 객체 μƒμˆ˜ μ„ μ–Έκ³Ό λ™μ‹œμ— μ΄ˆκΈ°ν™” ν•˜κ±°λ‚˜ 객체 μƒμ„±μžμ—μ„œ μ΄ˆκΈ°ν™” κ°€λŠ₯ν•˜λ‹€.

 

finalκ³Ό λ©”μ„œλ“œ

public class 동물 {
	final void μˆ¨μ‰¬λ‹€() {
		System.out.println("호흑 쀑");
	}
}

class 포유λ₯˜ extends 동물 {
	// μ—λŸ¬ λ°œμƒ: Cannot override the final method from 동물
	/*
	 * void μˆ¨μ‰¬λ‹€() { System.out.println("호흑 쀑"); }
	 */
}

λ©”μ„œλ“œκ°€ final이면 μ΅œμ’… λ©”μ„œλ“œμ΄λ―€λ‘œ μ˜€λ²„λΌμ΄λ”©μ„ κΈˆμ§€ν•œλ‹€.

instanceof μ—°μ‚°μž

λ§Œλ“€μ–΄μ§„ 객체가 νŠΉμ • 클래슀의 μΈμŠ€ν„΄μŠ€μΈμ§€ ν™•μΈν•˜λŠ” μ—°μ‚°μž

μ‚¬μš©λ°©λ²• : `κ°μ²΄μ°Έμ‘°λ³€μˆ˜ instanceof 클래슀λͺ…`

 

class 동물 {

}

class μ‘°λ₯˜ extends 동물 {

}

class νŽ­κ·„ extends μ‘°λ₯˜ {

}

public class Driver {
	public static void main(String[] args) {
		동물 동물객체 = new 동물();
		동물 μ‘°λ₯˜κ°μ²΄ = new μ‘°λ₯˜();
		동물 νŽ­κ·„κ°μ²΄ = new νŽ­κ·„();

		System.out.println(동물객체 instanceof 동물);

		System.out.println(μ‘°λ₯˜κ°μ²΄ instanceof 동물);
		System.out.println(μ‘°λ₯˜κ°μ²΄ instanceof μ‘°λ₯˜);

		System.out.println(νŽ­κ·„κ°μ²΄ instanceof 동물);
		System.out.println(νŽ­κ·„κ°μ²΄ instanceof μ‘°λ₯˜);
		System.out.println(νŽ­κ·„κ°μ²΄ instanceof νŽ­κ·„);

		System.out.println(νŽ­κ·„κ°μ²΄ instanceof Object);
	}
}

μ‹€ν–‰ κ²°κ³ΌλŠ” λͺ¨λ‘ 참이닀.

νŽ­κ·„κ°μ²΄ instanceof 동물 κ°€ 참인 μ΄μœ λŠ” "객체 μ°Έμ‘° λ³€μˆ˜ νƒ€μž…"이 μ•„λ‹Œ "μ‹€μ œ 객체의 νƒ€μž…"에 μ˜ν•΄ 처리되기 λ•Œλ¬Έμ΄λ‹€.

-> μ΄λŠ” LSP(λ¦¬μŠ€μ½”ν”„ μΉ˜ν™˜ 법칙)을 μ–΄κΈ°λ“œ μ½”λ“œμ—μ„œ 주둜 λ‚˜νƒ€λ‚˜λŠ” μ—°μ‚°μžμ΄λ‹€. (λ¦¬νŒ©ν† λ§μ˜ λŒ€μƒ)

 

package ν‚€μ›Œλ“œ

package ν‚€μ›Œλ“œλŠ” λ„€μž„μŠ€νŽ˜μ΄μŠ€(이름 곡간)을 λ§Œλ“€μ–΄μ£ΌλŠ” μ—­ν• 

**ν•„μš”μ„±**

μ—¬λŸ¬ 개발 쑰직이 ν•˜λ‚˜μ˜ ν”„λ‘œμ νŠΈμ— μ°Έκ°€ν•  λ•Œ λ°œμƒν•  수 μžˆλŠ” λ³€μˆ˜λͺ… 쀑볡 문제λ₯Ό packageλ₯Ό 톡해 이름 곡간을 λ‚˜λˆ„μ–΄ ν•΄κ²°ν•œλ‹€.

ex) packageλͺ….λ³€μˆ˜λͺ…

interface ν‚€μ›Œλ“œμ™€ implements ν‚€μ›Œλ“œ

  • μΈν„°νŽ˜μ΄μŠ€λŠ” public 좔상 λ©”μ„œλ“œμ™€ public 정적 μƒμˆ˜λ§Œ κ°€μ§ˆ 수 μžˆλ‹€.
  • default λ©”μ„œλ“œ 좔가됨
interface Speakable {
	double PI = 3.14159;
	final double absoluteZeroPoint = -275.15;

	void sayYes();
}

그럼 μœ„μ˜ μ½”λ“œμ—μ„  객체 λ³€μˆ˜, μƒμˆ˜, 일반 λ©”μ„œλ“œκ°€ μ‘΄μž¬ν•˜λŠ”λ° ν‹€λ¦° μ½”λ“œμΈκ°€?

-> μ•„λ‹ˆλ‹€. μžλ°” μ–Έμ–΄ μ„€κ³„νŒ€μ˜ 배렀둜 μΈν„°νŽ˜μ΄μŠ€λŠ” λ©”μ„œλ“œμ™€ 속성에 μžλ™μœΌλ‘œ abstract, public, static, final을 λΆ™μ—¬μ€€λ‹€.

this ν‚€μ›Œλ“œ

객체가 자기 μžμ‹ μ„ 지칭할 λ•Œ μ“°λŠ” ν‚€μ›Œλ“œ
class νŽ­κ·„ {
	int var = 10;

	void test() {
		int var = 20;

		System.out.println(var);
		System.out.println(this.var);
	}
}

public class Driver {
	public static void main(String[] args) {
		νŽ­κ·„ λ½€λ‘œλ‘œ = new νŽ­κ·„();
		λ½€λ‘œλ‘œ.test();
	}
}

T λ©”λͺ¨λ¦¬

μœ„ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜κ²Œ 되면 

System.out.println(var); λŠ” λ½€λ‘œλ‘œ.test() μ§€μ—­λ³€μˆ˜κ°€ μžˆλŠ” μŠ€νƒν”„λ ˆμž„μ˜ varλ₯Ό 좜λ ₯ν•˜κ²Œλ˜κ³ 

System.out.println(this.var);  νŽ­κ·„ 객체 λ³€μˆ˜λŠ” μ§€μ—­λ³€μˆ˜μ™€ 이름이 μ€‘λ³΅λ˜λ―€λ‘œ this.var라고 μ§€μ •ν•΄μ€˜μ•Ό ν•œλ‹€.

 

  • 지역 λ³€μˆ˜μ™€ μ†μ„±μ˜ 이름이 같은 경우 지역 λ³€μˆ˜κ°€ μš°μ„ ν•œλ‹€.
  • 객체 λ³€μˆ˜μ™€ 이름이 같은 지역 λ³€μˆ˜κ°€ μžˆλŠ” 경우 객체 λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜λ €λ©΄ this μ ‘λ‘μ‚¬λ‘œ μ‚¬μš©ν•œλ‹€.
  • 정적 λ³€μˆ˜μ™€ 이름이 같은 지역 λ³€μˆ˜κ°€ μžˆλŠ” 경우 정적 λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜λ €λ©΄ 클래슀λͺ…을 μ ‘λ‘μ‚¬λ‘œ μ‚¬μš©ν•œλ‹€.

super ν‚€μ›Œλ“œ

λ°”λ‘œ μœ„ μƒμœ„ 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό μ§€μΉ­ν•œλ‹€.
class 동물 {
	void method() {
		System.out.println("동물");
	}
}

class μ‘°λ₯˜ extends 동물 {
	void method() {
		super.method();
		System.out.println("μ‘°λ₯˜");
	}
}

class νŽ­κ·„ extends μ‘°λ₯˜ {
	void method() {
		super.method();
		System.out.println("νŽ­κ·„");

		// Syntax error on token "super", Identifier expected
		// super.super.method();
	}
}

public class Driver {
	public static void main(String[] args) {
		νŽ­κ·„ λ½€λ‘œλ‘œ = new νŽ­κ·„();
		λ½€λ‘œλ‘œ.method();
	}
}

μœ„ μ½”λ“œμ²˜λŸΌ super ν‚€μ›Œλ“œλ₯Ό 톡해 μƒμœ„ 클래슀의 μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  수 μžˆλ‹€.

 

ν•˜μ§€λ§Œ, super.super ν˜•νƒœμ˜ μƒμœ„μ˜ μƒμœ„ 클래슀의 μΈμŠ€ν„΄μŠ€μ—λŠ” 접근이 λΆˆκ°€λŠ₯ν•˜λ‹€...

μ˜ˆλΉ„ 고수λ₯Ό μœ„ν•œ ν•œλ§ˆλ””

객체 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ 객체λͺ….κ°μ²΄λ©”μ„œλ“œ() κ°€ μ•„λ‹Œ 클래슀λͺ….κ°μ²΄λ©”μ„œλ“œ()κ°€ ν˜ΈμΆœλœλ‹€!

 

**이유**

νŽ­κ·„ 객체가 100κ°œμ΄μƒ μƒμ„±λœλ‹€κ³  κ°€μ •ν•˜λ©΄ heap μ˜μ—­μ— νŽ­κ·„ 객체가 100개 μƒμ„±λ˜κ³  test()λ©”μ„œλ“œκ°€ 100개 이상 μƒμ„±λ˜κ²Œ λœλ‹€.

 

객체 멀버 λ©”μ„œλ“œλŠ” 객체 λ©€λ²„μ˜ μ†μ„±λ§Œ λ‹€λ₯Ό 뿐 λ‚˜λ¨Έμ§€λŠ” λͺ¨λ‘ κ°™λ‹€. 

 

κ·Έλž˜μ„œ JVM은 지λŠ₯적으둜 객체 멀버 λ©”μŠ€λ“œλ₯Ό μŠ€νƒœν‹± μ˜μ—­μ— 단 ν•˜λ‚˜λ§Œ λ³΄μœ ν•˜κ²Œ λœλ‹€.

그리고 test() λ©”μ„œλ“œ 호좜 μ‹œ 객체 μžμ‹ μ„ this 객체 μ°Έμ‘° λ³€μˆ˜λ‘œ λ„˜κΈ΄λ‹€. (객체 멀버 정보 λ„˜κΉ€)

 

JVMμ—μ„œ μ΅œμ ν™”ν•œ Tλ©”λͺ¨λ¦¬ ꡬ쑰