1~2. 상속 (Inheritance)


κ°œλ…

  • 기쑴의 클래슀둜 μƒˆλ‘œμš΄ 클래슀λ₯Ό μž‘μ„±ν•˜λŠ” 것. (μ½”λ“œμ˜ μž¬μ‚¬μš©)
  • 두 클래슀λ₯Ό λΆ€λͺ¨μ™€ μžμ‹μœΌλ‘œ 관계λ₯Ό λ§Ίμ–΄μ£ΌλŠ” 것.
class μžμ‹ν΄λž˜μŠ€ extends λΆ€λͺ¨ν΄λž˜μŠ€ {
	// ...
}
class Parent { }
class Child extends Parent {
	// ...
}

νŠΉμ§•

  • μžμ†μ€ μ‘°μƒμ˜ λͺ¨λ“  멀버λ₯Ό μƒμ†λ°›λŠ”λ‹€. (μƒμ„±μž, μ΄ˆκΈ°ν™”λΈ”λŸ­ μ œμ™Έ)
  • μžμ†μ˜ 멀버 κ°œμˆ˜λŠ” 쑰상보닀 적을 수 μ—†λ‹€. (κ°™κ±°λ‚˜ λ§Žλ‹€.)
class Parent {
	int age;
}
class Child extends Parent { }
  • μžμ†μ˜ 변경은 쑰상에 영ν–₯을 λ―ΈμΉ˜μ§€ μ•ŠλŠ”λ‹€.
class Parent {
	int age;
}
class Child extends Parent {
	void play() {
		System.out.println("λ†€μž~");
	}
}

3~4. 클래슀 κ°„μ˜ 관계, 상속과 포함


포함(composite)μ΄λž€?

  • 클래슀의 λ©€λ²„λ‘œ μ°Έμ‘°λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λŠ” 것
  • μž‘μ€ λ‹¨μœ„μ˜ 클래슀λ₯Ό λ§Œλ“€κ³ , 이 듀을 μ‘°ν•©ν•΄μ„œ 클래슀λ₯Ό λ§Œλ“ λ‹€.
class Circle {
	int x;
	int y;
	int r;
}
class Point {
	int x;
	int y;
}
class Circle {
	Point c = new Point();
	int r;
}
class Car {
	Engine e = new Engine();
	Door[] d = new Door[4];
}

클래슀 κ°„μ˜ 관계 κ²°μ •ν•˜κΈ°

  • 상속관계 β€˜~은 ~이닀.’
    • 원은 점이닀.
  • 포함관계 β€˜~은 ~을 가지고 μžˆλ‹€.’
    • 원은 점을 가지고 μžˆλ‹€. (더 μžμ—°μŠ€λŸ½κΈ° λ•Œλ¬Έμ— 포함관계가 적합)

5~6. 단일 상속, Object 클래슀


단일 상속 (Single Inheritance)

class TvDVD extends Tv, DVD { // μ—λŸ¬. 쑰상은 ν•˜λ‚˜λ§Œ ν—ˆμš©λœλ‹€.
	// ...
	// Tv.power() 와 DVD.power() κ°€ μ‘΄μž¬ν–ˆμ„ λ•Œ 좩돌 우렀
}
  • JavaλŠ” λ‹¨μΌμƒμ†λ§Œμ„ ν—ˆμš©ν•œλ‹€. (C++은 닀쀑상속 ν—ˆμš©)
class TvDVD extends Tv {
	DVD dvd = new DVD();
	void play() {
		dvd.play();
	}
	void stop() {
		dvd.stop();
	}
	void rew() {
		dvd.rew();
	}
	void ff() {
		dvd.ff();
	}
}
  • 비쀑이 높은 클래슀 ν•˜λ‚˜λ§Œ μƒμ†κ΄€κ³„λ‘œ, λ‚˜λ¨Έμ§€λŠ” ν¬ν•¨κ΄€κ³„λ‘œ ν•œλ‹€.

Object 클래슀 - λͺ¨λ“  클래슀의 쑰상

class Tv {
	// ...
}
class SmartTv extends Tv {
	// ...
}
// 컴파일러 μžλ™ μΆ”κ°€
class Tv extends Object {
	// ...
}
class SmartTv extends Tv {
	// ...
}
  • λΆ€λͺ¨κ°€ μ—†λŠ” ν΄λž˜μŠ€λŠ” μžλ™μ μœΌλ‘œ Object 클래슀λ₯Ό μƒμ†λ°›κ²Œ λœλ‹€.
  • λͺ¨λ“  ν΄λž˜μŠ€λŠ” Object ν΄λž˜μŠ€μ— μ •μ˜λœ 11개의 λ©”μ„œλ“œλ₯Ό μƒμ†λ°›λŠ”λ‹€.
    • toString() equals(Object obj) hashcode() ...

7~9. μ˜€λ²„λΌμ΄λ”©


μ˜€λ²„λΌμ΄λ”© (overriding)

class Point {
	int x;
	int y;
	String getLocation() {
		return "x :" + x + ", y:" + y;
	}
}
class Point3D extends Point {
	int z;
	// μ˜€λ²„λΌμ΄λ”©
	String getLocation() {
		return "x :" + x + ", y:" + y + ", z:" + z;
	}
}
  • 상속받은 μ‘°μƒμ˜ λ©”μ„œλ“œλ₯Ό μžμ‹ μ— 맞게 λ³€κ²½ν•˜λŠ” 것

μ˜€λ²„λΌμ΄λ”©μ˜ 쑰건

  1. μ„ μ–ΈλΆ€(λ°˜ν™˜νƒ€μž…, λ©”μ„œλ“œ 이름, λ§€κ°œλ³€μˆ˜ λͺ©λ‘)κ°€ 쑰상 클래슀의 λ©”μ„œλ“œμ™€ μΌμΉ˜ν•΄μ•Ό ν•œλ‹€.
  2. μ ‘κ·Ό μ œμ–΄μžλ₯Ό 쑰상 클래슀의 λ©”μ„œλ“œλ³΄λ‹€ 쒁은 λ²”μœ„λ‘œ λ³€κ²½ν•  수 μ—†λ‹€.
  3. μ˜ˆμ™ΈλŠ” 쑰상 클래슀의 λ©”μ„œλ“œλ³΄λ‹€ 많이 μ„ μ–Έν•  수 μ—†λ‹€.
    • μ™œ? 쑰상이 λͺ¨λ“  μžμ†μ˜ μ˜ˆμ™Έλ₯Ό κ°λ‹Ήν•˜κΈ° λ•Œλ¬Έμ—

μ˜€λ²„λ‘œλ”© vs μ˜€λ²„λΌμ΄λ”©

class Parent {
	void parentMethod() {}
}
class Child extends Parent {
	void parentMethod() {}      // μ˜€λ²„λΌμ΄λ”©
	void parentMethod(int i) {} // μ˜€λ²„λ‘œλ”©
	
	void childMethod() {}       // λ©”μ„œλ“œ μ •μ˜
	void childMethod(int i) {}  // μ˜€λ²„λ‘œλ”©
	void childMethod() {}       // μ—λŸ¬. μ€‘λ³΅μ •μ˜
}
  • μ˜€λ²„λ‘œλ”©(overloading) 기쑴에 μ—†λŠ” 이름이 같은 μƒˆλ‘œμš΄ λ©”μ„œλ“œλ₯Ό μ •μ˜ν•˜λŠ” 것(new)
  • μ˜€λ²„λΌμ΄λ”©(overriding) 상속받은 λ©”μ„œλ“œμ˜ λ‚΄μš©μ„ λ³€κ²½ν•˜λŠ” 것(change, modify)

10~11. μ°Έμ‘°λ³€μˆ˜ super, μƒμ„±μž super()


μ°Έμ‘°λ³€μˆ˜ super

  • 객체 μžμ‹ μ„ κ°€λ¦¬ν‚€λŠ” μ°Έμ‘°λ³€μˆ˜. μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œ(μƒμ„±μž)λ‚΄μ—λ§Œ 쑴재
  • μ‘°μƒμ˜ 멀버λ₯Ό μžμ‹ μ˜ 멀버와 ꡬ별할 λ•Œ μ‚¬μš©
  • λ°”λ‘œ μƒμœ„ 쑰상을 의미
    • Parent β†’ Child β†’ GrandChild 일 λ•Œ
    • GrandChild 의 super λŠ” Child
public class Ex7_2 {
	public static void main(String[] args) {
		Child c = new Child();
		c.method();
	}
}
class Parent {
	int x = 10; // super.x
}
class Child extends Parent {
	int x = 20; // this.x
	void method() {
		System.out.println("x=" + x);
		System.out.println("this.x=" + this.x);
		System.out.println("super.x=" + super.x);
	}
}
public class Ex7_3 {
	public static void main(String[] args) {
		Child2 c = new Child2();
		c.method();
	}
}
class Parent2 {
	int x = 10; // super.x λ©΄μ„œ this.x
}
class Child2 extends Parent2 {
	void method() {
		System.out.println("x=" + x);
		System.out.println("this.x=" + this.x);
		System.out.println("super.x=" + super.x);
	}
}

super() - μ‘°μƒμ˜ μƒμ„±μž

  • μ‘°μƒμ˜ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•  λ•Œ μ‚¬μš©
  • μ‘°μƒμ˜ λ©€λ²„λŠ” μ‘°μƒμ˜ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•΄μ„œ μ΄ˆκΈ°ν™”
class Point {
	int x, y;
	Point(int x, int y) {
		this.x = x;
		this.y = y;
	}
}
class Point3D extends Point {
	int z;
	// λΆ€μ μ ˆν•œ μ΄ˆκΈ°ν™”
	Point3D(int x, int y, int z) {
		this.x = x; // μ‘°μƒμ˜ 멀버λ₯Ό μ΄ˆκΈ°ν™”
		this.y = y; // μ‘°μƒμ˜ 멀버λ₯Ό μ΄ˆκΈ°ν™”
		this.z = z;
	}
	// μ˜¬λ°”λ₯Έ μ΄ˆκΈ°ν™”
	Point3D(int x, int y, int z) {
		super(x, y); // μ‘°μƒν΄λž˜μŠ€μ˜ μƒμ„±μž Point(int x, int y)λ₯Ό 호좜
		this.z = z;  // μžμ‹ μ˜ 멀버λ₯Ό μ΄ˆκΈ°ν™”
	}
}
  • μƒμ„±μžμ˜ 첫 쀄에 λ°˜λ“œμ‹œ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•œλ‹€.
    • 그렇지 μ•ŠμœΌλ©΄ μ»΄νŒŒμΌλŸ¬κ°€ μƒμ„±μžμ˜ 첫 쀄에 super();λ₯Ό μ‚½μž…

12~14. νŒ¨ν‚€μ§€, 클래슀 패슀


νŒ¨ν‚€μ§€ (package)

  • μ„œλ‘œ κ΄€λ ¨λœ 클래슀의 묡음
  • ν΄λž˜μŠ€λŠ” 클래슀 파일(*.class), νŒ¨ν‚€μ§€λŠ” 폴더, ν•˜μœ„ νŒ¨ν‚€μ§€λŠ” ν•˜μœ„ 폴더
  • 클래슀의 μ‹€μ œ 이름(full name)은 νŒ¨ν‚€μ§€λ₯Ό 포함. (java.lang.String)

νŒ¨ν‚€μ§€μ˜ μ„ μ–Έ

  • νŒ¨ν‚€μ§€λŠ” μ†ŒμŠ€νŒŒμΌμ˜ 첫 번째 λ¬Έμž₯으둜 단 ν•œλ²ˆ μ„ μ–Έ
  • 같은 μ†ŒμŠ€ 파일의 ν΄λž˜μŠ€λ“€μ€ λͺ¨λ‘ 같은 νŒ¨ν‚€μ§€μ— μ†ν•˜κ²Œ λœλ‹€.
  • νŒ¨ν‚€μ§€ 선언이 μ—†μœΌλ©΄ μ΄λ¦„μ—†λŠ”(unnamed) νŒ¨ν‚€μ§€μ— μ†ν•˜κ²Œ λœλ‹€.

클래슀 패슀 (class path)

  • 클래슀 파일(*.class)의 μœ„μΉ˜λ₯Ό μ•Œλ €μ£ΌλŠ” 경둜(path)
  • ν™˜κ²½λ³€μˆ˜ classpath둜 κ΄€λ¦¬ν•˜λ©°, κ²½λ‘œκ°„μ˜ κ΅¬λΆ„μžλŠ” β€˜;’λ₯Ό μ‚¬μš©
    • classpath(ν™˜κ²½λ³€μˆ˜)에 νŒ¨ν‚€μ§€μ˜ 루트λ₯Ό λ“±λ‘ν•΄μ€˜μ•Ό 함.

15~16. import문, static import문


import문

class ImportTest {
	java.util.Date today = new java.util.Date();
}
import java.util.Date;
class ImportTest {
	Date today = new Date();
}
  • 클래슀λ₯Ό μ‚¬μš©ν•  λ•Œ νŒ¨ν‚€μ§€ 이름을 μƒλž΅ν•  수 μžˆλ‹€.
  • μ»΄νŒŒμΌλŸ¬μ—κ²Œ ν΄λž˜μŠ€κ°€ μ†ν•œ νŒ¨ν‚€μ§€λ₯Ό μ•Œλ €μ€€λ‹€.
  • java.langνŒ¨ν‚€μ§€μ˜ ν΄λž˜μŠ€λŠ” importν•˜μ§€ μ•Šκ³ λ„ μ‚¬μš©ν•  수 μžˆλ‹€.
    • String, Object, System, Thread, …

import문의 μ„ μ–Έ

import νŒ¨ν‚€μ§€λͺ….클래슀λͺ…;
	λ˜λŠ”
import νŒ¨ν‚€μ§€λͺ….*;
  • import문을 μ„ μ–Έν•˜λŠ” 방법은 λ‹€μŒκ³Ό κ°™λ‹€.
import java.util.*;
import java.text.*;
// javaνŒ¨ν‚€μ§€μ˜ λͺ¨λ“  클래슀 (νŒ¨ν‚€μ§€ μ œμ™Έ)
import java.*;
  • import문은 νŒ¨ν‚€μ§€λ¬Έκ³Ό 클래슀 μ„ μ–Έμ˜ 사이에 μ„ μ–Έν•œλ‹€.
  • import문은 컴파일 μ‹œμ— μ²˜λ¦¬λ˜λ―€λ‘œ ν”„λ‘œκ·Έλž¨μ˜ μ„±λŠ₯에 영ν–₯μ—†μŒ.
  • μ•„λž˜μ˜ 두 μ½”λ“œλŠ” μ„œλ‘œ μ˜λ―Έκ°€ λ‹€λ₯΄λ‹€.
import java.sql.*;  // java.sql.Date
import java.util.*; // java.util.Date
public class ImportTest {
	public static void main(String[] args) {
		java.util.Date today = new java.util.Date();
	}
}
  • 이름이 같은 ν΄λž˜μŠ€κ°€ μ†ν•œ 두 νŒ¨ν‚€μ§€λ₯Ό importν•  λ•ŒλŠ” 클래슀 μ•žμ— νŒ¨ν‚€μ§€λͺ…을 λΆ™μ—¬μ€˜μ•Ό ν•œλ‹€.

static import문

import static java.lang.Integer.*;   // Integer클래슀의 λͺ¨λ“  staticλ©”μ„œλ“œ
import static java.lang.Math.random; // Math.random()만
import static java.lang.System.out;  // System.out을 out만으둜 μ°Έμ‘°κ°€λŠ₯
  • static멀버λ₯Ό μ‚¬μš©ν•  λ•Œ 클래슀 이름을 μƒλž΅ν•  수 있게 ν•΄μ€€λ‹€.

17~20. μ œμ–΄μž, static, final, abstract


μ œμ–΄μž(modifier)

public class ModifierTest {
	public static final int WIDTH = 200;
	public static void main(String[] args) {
		System.out.println("WIDTH=" + WIDTH);
	}
}
  • ν΄λž˜μŠ€μ™€ 클래슀의 멀버(멀버 λ³€μˆ˜, λ©”μ„œλ“œ)에 뢀가적인 의미 λΆ€μ—¬
    • μ ‘κ·Ό μ œμ–΄μž - public protected (default) private
    • κ·Έ μ™Έ - static final abstract native transient synchronized volatile strictfp
  • ν•˜λ‚˜μ˜ λŒ€μƒμ— μ—¬λŸ¬ μ œμ–΄μžλ₯Ό 같이 μ‚¬μš©κ°€λŠ₯(μ ‘κ·Ό μ œμ–΄μžλŠ” ν•˜λ‚˜λ§Œ)

static - 클래슀의, 곡톡적인

λŒ€μƒμ˜λ―Έ
λ©€λ²„λ³€μˆ˜λͺ¨λ“  μΈμŠ€ν„΄μŠ€μ— κ³΅ν†΅μ μœΌλ‘œ μ‚¬μš©λ˜λŠ” 클래슀 λ³€μˆ˜κ°€ λœλ‹€. 클래슀 λ³€μˆ˜λŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ§€ μ•Šκ³ λ„ μ‚¬μš© κ°€λŠ₯ν•˜λ‹€. ν΄λž˜μŠ€κ°€ λ©”λͺ¨λ¦¬μ— λ‘œλ“œλ  λ•Œ μƒμ„±λœλ‹€.
λ©”μ„œλ“œμΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ§€ μ•Šκ³ λ„ 호좜이 κ°€λŠ₯ν•œ static λ©”μ„œλ“œκ°€ λœλ‹€. static λ©”μ„œλ“œ λ‚΄μ—μ„œλŠ” μΈμŠ€ν„΄μŠ€ 멀버듀을 직접 μ‚¬μš©ν•  수 μ—†λ‹€.

final - λ§ˆμ§€λ§‰μ˜, 변경될 수 μ—†λŠ”

λŒ€μƒμ˜λ―Έ
ν΄λž˜μŠ€λ³€κ²½λ  수 μ—†λŠ” 클래슀, ν™•μž₯될 수 μ—†λŠ” ν΄λž˜μŠ€κ°€ λœλ‹€. κ·Έλž˜μ„œ final둜 μ§€μ •λœ ν΄λž˜μŠ€λŠ” λ‹€λ₯Έ 클래슀의 쑰상이 될 수 μ—†λ‹€.
λ©”μ„œλ“œλ³€κ²½λ  수 μ—†λŠ” λ©”μ„œλ“œ, final둜 μ§€μ •λœ λ©”μ„œλ“œλŠ” μ˜€λ²„λΌμ΄λ”©μ„ 톡해 μž¬μ •μ˜ 될 수 μ—†λ‹€.
λ©€λ²„λ³€μˆ˜ μ§€μ—­λ³€μˆ˜λ³€μˆ˜ μ•žμ— final 이 λΆ™μœΌλ©΄, 값을 λ³€κ²½ν•  수 μ—†λŠ” μƒμˆ˜κ°€ λœλ‹€.
final class AbstractTest {   // 쑰상이 될 수 μ—†λŠ” 클래슀
	final int MAX_SIZE = 10;   // 값을 λ³€κ²½ν•  수 μ—†λŠ” λ©€λ²„λ³€μˆ˜ (μƒμˆ˜)
	final void getMaxSize() {  // μ˜€λ²„λΌμ΄λ”©μ„ ν•  수 μ—†λŠ” λ©”μ„œλ“œ (λ³€κ²½λΆˆκ°€)
		final int LV = MAX_SIZE; // 값을 λ³€κ²½ν•  수 μ—†λŠ” μ§€μ—­λ³€μˆ˜ (μƒμˆ˜)
		return MAX_SIZE;
	}
}

abstract - μΆ”μƒμ˜, λ―Έμ™„μ„±μ˜

λŒ€μƒμ˜λ―Έ
클래슀클래슀 내에 좔상 λ©”μ„œλ“œκ°€ μ„ μ–Έλ˜μ–΄ μžˆμŒμ„ μ˜λ―Έν•œλ‹€.
λ©”μ„œλ“œμ„ μ–ΈλΆ€λ§Œ μž‘μ„±ν•˜κ³  κ΅¬ν˜„λΆ€λŠ” μž‘μ„±ν•˜μ§€ μ•Šμ€ 좔상 λ©”μ„œλ“œμž„μ„ μ•Œλ¦°λ‹€.
abstract class AbstractTest { // 좔상 클래슀 (좔상 λ©”μ„œλ“œλ₯Ό ν¬ν•¨ν•œ 클래슀)
	abstract void move();       // 좔상 λ©”μ„œλ“œ (κ΅¬ν˜„λΆ€κ°€ μ—†λŠ” λ©”μ„œλ“œ)
}
AbstractTest a = new AbstractTest(); // μ—λŸ¬. 좔상 클래슀의 μΈμŠ€ν„΄μŠ€ μƒμ„±λΆˆκ°€

21. μ ‘κ·Ό μ œμ–΄μž


  • private - 같은 클래슀 λ‚΄μ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯
  • (default) - 같은 νŒ¨ν‚€μ§€ λ‚΄μ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯
  • protected - 같은 νŒ¨μ§€ν‚€ λ‚΄μ—μ„œ, 그리고 λ‹€λ₯Έ νŒ¨ν‚€μ§€μ˜ μžμ†ν΄λž˜μŠ€μ—μ„œ μ ‘κ·Ό κ°€λŠ₯
  • public - μ ‘κ·Ό μ œν•œμ΄ μ—†μŒ
μ œμ–΄μžκ°™μ€ ν΄λž˜μŠ€κ°™μ€ νŒ¨ν‚€μ§€μžμ† ν΄λž˜μŠ€μ „μ²΄
publicβ­•β­•β­•β­•
protectedβ­•β­•β­•
(default)β­•β­•
privateβ­•

22. μΊ‘μŠν™”


μΊ‘μŠν™”μ™€ μ ‘κ·Ό μ œμ–΄μž

public class Time {
	// μ™ΈλΆ€μ—μ„œ 직접 μ ‘κ·Όν•˜μ§€ λͺ»ν•˜λ„둝 private
	private int hour;
	private int minute;
	private int second;
	// λ©”μ„œλ“œλ₯Ό 톡해 κ°„μ ‘ μ ‘κ·Ό ν—ˆμš©
	public int getHour() {
		return hour;
	}
	public void setHour(int hour) {
		if (hour < 0 || hour > 23) {
			return;
		}
		this.hour = hour;
	}
}
  • μ ‘κ·Ό μ œμ–΄μžλ₯Ό μ‚¬μš©ν•˜λŠ” 이유
    • μ™ΈλΆ€λ‘œλΆ€ν„° 데이터λ₯Ό λ³΄ν˜Έν•˜κΈ° μœ„ν•΄μ„œ
    • μ™ΈλΆ€μ—λŠ” λΆˆν•„μš”ν•œ, λ‚΄λΆ€μ μœΌλ‘œλ§Œ μ‚¬μš©λ˜λŠ”, 뢀뢄을 감좔기 μœ„ν•΄μ„œ

23. λ‹€ν˜•μ„± (polymorphism)


κ°œλ…

  • 쑰상 νƒ€μž… μ°Έμ‘° λ³€μˆ˜λ‘œ μžμ† νƒ€μž… 객체λ₯Ό λ‹€λ£¨λŠ” 것
Tv t = new SmartTv(); // νƒ€μž… 뢈일치
class Tv {
	boolean power;
	int channel;
	void power() {
		power = !power;
	}
	void channelUp() {
		++channel;
	}
	void channelDown() {
		--channel;
	}
}
class SmartTv extends Tv {
	boolean caption;
	void displayCaption(String text) {
		if (caption) {
			System.out.println(text);
		}
	}
}

νŠΉμ§•

SmartTv s = new SmartTv(); // μ°Έμ‘°λ³€μˆ˜μ™€ μΈμŠ€ν„΄μŠ€μ˜ νƒ€μž…μ΄ 일치
Tv      t = new SmartTv(); // μ‘°μƒνƒ€μž… μ°Έμ‘°λ³€μˆ˜λ‘œ μžμ†νƒ€μž… μΈμŠ€ν„΄μŠ€ μ°Έμ‘°
// μ‘°μƒνƒ€μž… Tvμ°Έμ‘°λ³€μˆ˜λ‘œ μžμ†νƒ€μž… SmartTvμΈμŠ€ν„΄μŠ€λ₯Ό μ°Έμ‘°ν•  경우 μ‘°μƒμ˜ λ©€λ²„λ§Œ μ‚¬μš©ν•  수 있음
  • 객체와 μ°Έμ‘°λ³€μˆ˜μ˜ νƒ€μž…μ΄ μΌμΉ˜ν•  λ•Œμ™€ μΌμΉ˜ν•˜μ§€ μ•Šμ„ λ•Œμ˜ 차이?
Tv      t = new SmartTv(); // OK.
SmartTv s = new Tv();      // μ—λŸ¬.
  • μžμ† νƒ€μž…μ˜ μ°Έμ‘°λ³€μˆ˜λ‘œ 쑰상 νƒ€μž…μ˜ 객체λ₯Ό 가리킬 수 μ—†λ‹€.

μž₯점

  • λ‹€ν˜•μ  λ§€κ°œλ³€μˆ˜ - λ©”μ„œλ“œ 호좜 μ‹œ, μžμ‹ κ³Ό 같은 νƒ€μž… λ˜λŠ” μžμ† νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό λ„˜κΈΈ 수 있음
  • ν•˜λ‚˜μ˜ 배열에 μ—¬λŸ¬ μ’…λ₯˜μ˜ 객체λ₯Ό μ €μž₯ν•˜μ—¬ λ‹€λ£° 수 있음

24~25. μ°Έμ‘°λ³€μˆ˜μ˜ ν˜•λ³€ν™˜


  • μ°Έμ‘°λ³€μˆ˜μ˜ ν˜•λ³€ν™˜ μ‹œ λ³€ν•˜λŠ” 것
    • λ‹¬λΌμ§€λŠ” 것 : 객체의 νƒ€μž…
    • κ·ΈλŒ€λ‘œμΈ 것 : 객체 자체, μ£Όμ†Œκ°’
  • μ°Έμ‘°λ³€μˆ˜μ˜ ν˜•λ³€ν™˜μ„ ν•˜λŠ” 이유
    • μ‚¬μš©ν•  수 μžˆλŠ” λ©€λ²„μ˜ 갯수λ₯Ό μ‘°μ ˆν•˜κΈ° μœ„ν•΄μ„œ
  • 쑰상 μžμ† κ΄€κ³„μ˜ μ°Έμ‘°λ³€μˆ˜λŠ” μ„œλ‘œ ν˜•λ³€ν™˜ κ°€λŠ₯
class Car { }
class FireEngine extends Car { }
class Ambulance extends Car { }
FireEngine f = new FireEngine();
Car c = (Car)f;                // OK. 쑰상인 Carνƒ€μž…μœΌλ‘œ ν˜•λ³€ν™˜ (μ—…μΊμŠ€νŒ…)
FireEngine f2 = FireEngine(c); // OK. μžμ†μΈ FireEngineνƒ€μž…μœΌλ‘œ ν˜•λ³€ν™˜ (λ‹€μš΄μΊμŠ€νŒ…)
Ambulance a = (Ambulance)f;    // μ—λŸ¬. 상속관계가 μ•„λ‹Œ 클래슀 κ°„μ˜ ν˜•λ³€ν™˜ λΆˆκ°€
  • ν˜•λ³€ν™˜ μ‹œ μ‹€μ œ μΈμŠ€ν„΄μŠ€κ°€ 무엇인지가 μ€‘μš”
public class Ex7_7 {
	public static void main(String[] args) {
		Car car = null;
		FireEngine fe = new FireEngine();
		FireEngine fe2 = (FireEngine)car; // λ‹€μš΄μΊμŠ€νŒ…
		Car car2 = (Car)fe2;              // μ—…μΊμŠ€νŒ…
		car2.drive();                     // NullPointerException λ°œμƒ.
                                      // μ™œ? κΈ°μ‘΄ μΈμŠ€ν„΄μŠ€μΈ car이 null이기 λ•Œλ¬Έμ—
		Car c = new Car();
		FireEngine f = (FireEngine)c; // ν˜•λ³€ν™˜ μ‹€ν–‰ μ—λŸ¬ ClassCastException λ°œμƒ.
		f.water();                    // μ»΄νŒŒμΌμ€ OK.
                                  // μ‹€μ œ κ°μ²΄λŠ” CarμΈμŠ€ν„΄μŠ€μ΄κΈ° λ•Œλ¬Έμ— f.water() μ‚¬μš©λΆˆκ°€
	}
}

26. instanceof μ—°μ‚°μž


  • μ°Έμ‘°λ³€μˆ˜μ˜ ν˜•λ³€ν™˜ κ°€λŠ₯ μ—¬λΆ€ 확인에 μ‚¬μš©. κ°€λŠ₯ν•˜λ©΄ true λ°˜ν™˜
  • ν˜•λ³€ν™˜ 전에 λ°˜λ“œμ‹œ instanceof 둜 확인해야 함
void doWork(Car c) {
	if (c instanceof FireEngine) {   // 1. ν˜•λ³€ν™˜μ΄ κ°€λŠ₯ν•œμ§€ 확인
		FireEngine fe = (FireEngine)c; // 2. ν˜•λ³€ν™˜
		fe.water();
	}
}
FireEngine fe = new FireEngine();
System.out.println(fe instanceof Object);     // true
System.out.println(fe instanceof Car);        // true
System.out.println(fe instanceof FireEngine); // true
Object obj = (Object)fe; // OK.
Car    c   = (Car)fe;    // OK.

27~28. λ§€κ°œλ³€μˆ˜μ˜ λ‹€ν˜•μ„±


class Product {
	int price;
	int bonusPoint;
}
class Tv extends Product { }
class Computer extends Product { }
class Audio extends Product { }
class Buyer {
	int money = 1000;
	int bonusPoint = 0;
}
// Product의 μžμ† νƒ€μž…μΈ Tv, Computer, Audio λͺ¨λ‘ λ§€κ°œλ³€μˆ˜λ‘œ 받을 수 있음
void buy(Product p) {
	money -= p.price;
	bonusPoint += p.bonusPoint;
}
Buyer b = new Buyer();
Tv tv = new Tv();
Computer com = new Computer();
b.buy(tv);
b.buy(com);
  • μ°Έμ‘°ν˜• λ§€κ°œλ³€μˆ˜λŠ” λ©”μ„œλ“œ 호좜 μ‹œ, μžμ‹ κ³Ό 같은 νƒ€μž… λ˜λŠ” μžμ† νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό λ„˜κΈΈ 수 있음

27~28. μ—¬λŸ¬ μ’…λ₯˜μ˜ 객체λ₯Ό λ°°μ—΄λ‘œ 닀루기


Product p[] = new Product[3];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio();
class Buyer {
	int money = 1000;
	int bonusPoint = 0;
	Product[] cart = new Product[10];
	int i = 0;
	void buy(Product p) {
		if(money < p.price) {
			System.out.println("μž”μ•‘λΆ€μ‘±");
			return;
		}
		money -= p.price;
		bonusPoint += p.bonusPoint;
		cart[i++] = p;
	}
}
  • μ‘°μƒνƒ€μž…μ˜ 배열에 μžμ†λ“€μ˜ 객체λ₯Ό 담을 수 있음

31~32. 좔상 클래슀, 좔상 λ©”μ„œλ“œ


좔상 클래슀 (abstract class)

abstract class Player {        // 좔상 클래슀 (λ―Έμ™„μ„± 클래슀)
	abstract void play(int pos); // 좔상 λ©”μ„œλ“œ (λͺΈν†΅{}이 μ—†λŠ” λ―Έμ™„μ„± λ©”μ„œλ“œ)
	abstract void stop();        // 좔상 λ©”μ„œλ“œ
}
  • κ°œλ…
    • λ―Έμ™„μ„± 섀계도. λ―Έμ™„μ„± λ©”μ„œλ“œλ₯Ό κ°–κ³  μžˆλŠ” 클래슀
public abstract class AbstractClass {
 
    private final String name;
 
    public AbstractClass(final String name) {
        this.name = name;
    }
 
    abstract void method();
 
    public String getName() {
        return name;
    }
}

Abstract Class, 좔상 ν΄λž˜μŠ€λž€ ν•˜λ‚˜ μ΄μƒμ˜ abstract λ©”μ„œλ“œλ₯Ό μ„ μ–Έν•œ 클래슀둜써 이λ₯Ό μƒμ†ν•˜λŠ” μžμ† ν΄λž˜μŠ€μ—μ„œ μ™„μ„±ν•˜λ„λ‘ μœ λ„ν•˜λŠ” ν΄λž˜μŠ€λ‹€.

일반 ν΄λž˜μŠ€μ— abstract λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν–ˆκΈ° λ•Œλ¬Έμ— μΈμŠ€ν„΄μŠ€ν™”κ°€ λΆˆκ°€ν•˜κ³  λ―Έμ™„μ„± 섀계도라고도 λΆˆλ¦°λ‹€.

  • 단일 μƒμ†λ§Œ κ°€λŠ₯ν•˜λ‹€.
  • 좔상 클래슀λ₯Ό μƒμ†ν•˜λŠ” μ§‘ν•©κ°„μ—λŠ” μ—°κ΄€ 관계가 μžˆλ‹€.
Player p = new Player(); // μ—λŸ¬. 좔상 클래슀의 μΈμŠ€ν„΄μŠ€ 생성 λΆˆκ°€
  • λ‹€λ₯Έ 클래슀 μž‘μ„±μ— 도움을 μ£ΌκΈ° μœ„ν•œ 것. μΈμŠ€ν„΄μŠ€ 생성 λΆˆκ°€.
class AudioPlayer extends Player {
	void play(int pos) {
		// 좔상 λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„
	}
	void stop() {
		// 좔상 λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„
	}
}
AudioPlayer ap = new AudioPlayer(); // OK.
  • 상속을 톡해 좔상 λ©”μ„œλ“œλ₯Ό μ™„μ„±ν•΄μ•Ό μΈμŠ€ν„΄μŠ€ 생성 κ°€λŠ₯

좔상 λ©”μ„œλ“œ (abstract method)

// 주석을 톡해 μ–΄λ–€ κΈ°λŠ₯을 μˆ˜ν–‰ν•  λͺ©μ μœΌλ‘œ μž‘μ„±ν•˜μ˜€λŠ”μ§€ μ„€λͺ…
abstract λ¦¬ν„΄νƒ€μž… λ©”μ„œλ“œμ΄λ¦„();
  • κ°œλ…
    • λ―Έμ™„μ„± λ©”μ„œλ“œ. κ΅¬ν˜„λΆ€ (λͺΈν†΅ { }) κ°€ μ—†λŠ” λ©”μ„œλ“œ
abstract class Player {        // 좔상 클래슀
	abstract void play(int pos); // 좔상 λ©”μ„œλ“œ
	abstract void stop();        // 좔상 λ©”μ„œλ“œ
}
class AudioPlayer extends Player {
	void play(int pos) {
		// 좔상 λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„
	}
	void stop() {
		// 좔상 λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„
	}
}
// 좔상 λ©”μ„œλ“œλ₯Ό 1개 밖에 κ΅¬ν˜„ν•˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— abstract
abstract class AbstractPlayer extends Player {
	void play(int pos) {
		// 좔상 λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„
	}
}
  • κΌ­ ν•„μš”ν•˜μ§€λ§Œ μžμ†λ§ˆλ‹€ λ‹€λ₯΄κ²Œ κ΅¬ν˜„λ  κ²ƒμœΌλ‘œ μ˜ˆμƒλ˜λŠ” 경우
abstract class Player {        // 좔상 클래슀
	boolean pause;
	int currentPos;
	Player() {                   // 좔상 ν΄λž˜μŠ€λ„ μƒμ„±μžκ°€ μžˆμ–΄μ•Ό 함
		pause = false;
		currentPos = 0;
	}
	// μ§€μ •λœ μœ„μΉ˜(pos)μ—μ„œ μž¬μƒν•˜λŠ” κΈ°λŠ₯을 μž‘μ„±ν•΄μ•Ό 함
	abstract void play(int pos); // 좔상 λ©”μ„œλ“œ
	// μž¬μƒμ„ μ¦‰μ‹œ λ©ˆμΆ”λŠ” κΈ°λŠ₯을 μž‘μ„±ν•΄μ•Ό 함
	abstract void stop();        // 좔상 λ©”μ„œλ“œ
	void play() {
		play(currentPos);          // 좔상 λ©”μ„œλ“œ μ‚¬μš© κ°€λŠ₯
                               // μ™œ? μ–΄μ§œν”Ό 좔상 ν΄λž˜μŠ€λŠ” 객체 생성이 λΆˆκ°€λŠ₯
                               // μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œλ₯Ό 호좜 ν•  수 μžˆλ‹€λŠ” 것은
                               // μžμ†μ΄ μ™„μ„±λœ 클래슀λ₯Ό λ§Œλ“€μ—ˆλ‹€λŠ” 의미기 λ•Œλ¬Έμ—
	}
}
  • 좔상 λ©”μ„œλ“œ 호좜 κ°€λŠ₯ (호좜 ν•  λ•ŒλŠ” μ„ μ–ΈλΆ€λ§Œ ν•„μš”)
  • 좔상 λ©”μ„œλ“œλ₯Ό μ„ μ–Έν•¨μœΌλ‘œμ¨ μžμ†λ“€μ—κ²Œ μžˆμ–΄μ„œ 각자 ν•„μˆ˜ κΈ°λŠ₯을 μž‘μ„±ν•˜κ²Œ 끔 κ°•μ œμ„±μ„ λΆ€μ—¬

33~34. 좔상 클래슀의 μž‘μ„±


  • μ—¬λŸ¬ ν΄λž˜μŠ€μ— κ³΅ν†΅μ μœΌλ‘œ μ‚¬μš©λ  수 μžˆλŠ” 좔상 클래슀λ₯Ό λ°”λ‘œ μž‘μ„±ν•˜κ±°λ‚˜ κΈ°μ‘΄ 클래슀의 곡톡 뢀뢄을 λ½‘μ•„μ„œ 좔상 클래슀λ₯Ό λ§Œλ“ λ‹€.
abstract class Unit {
	int x, y;
	abstract void move(int x, int y);
	void stop()             { }
}
class Marine extends Unit {
	void move(int x, int y) { }
	void stimPack()         { }
}
class Tank extends Unit {
	void move(int x, int y) { }
	void changeMode()       { }
}
class Dropship extends Unit {
	void move(int x, int y) { }
	void load()             { }
	void unload()           { }
}
Unit[] group = new Unit[3];
group[0] = new Marine();
group[1] = new Tank();
group[2] = new Dropship();
for (int i = 0; i < group.length; i++) {
	group[i].move(100, 200);
}
  • 좔상화 ↔ ꡬ체화
  • μΆ”μƒν™”λœ μ½”λ“œλŠ” κ΅¬μ²΄ν™”λœ μ½”λ“œλ³΄λ‹€ μœ μ—°ν•˜λ‹€. 변경에 유리
GregorianCalendar cal = new GregorianCalendar(); // ꡬ체적
Calendar cal = Calendar.getInstance();           // 좔상적

35~37. μΈν„°νŽ˜μ΄μŠ€μ˜ μ„ μ–Έ, 상속, κ΅¬ν˜„


μΈν„°νŽ˜μ΄μŠ€

interface PlayingCard {
	public static final int SPADE = 4;
	final int DIAMOND = 3; // public static final μƒλž΅ κ°€λŠ₯
	static int HEART = 2;  // public static final μƒλž΅ κ°€λŠ₯
	int CLOVER = 1;        // public static final μƒλž΅ κ°€λŠ₯
	public abstract String getCardNumber();
	String getCardKind();  // public abstract μƒλž΅ κ°€λŠ₯
}
  • 좔상 λ©”μ„œλ“œμ˜ 집합 (ν”„λ‘œκ·Έλž˜λ° 관점)
  • κ΅¬ν˜„λœ 것이 μ „ν˜€ μ—†λŠ” 섀계도. 껍데기 (λͺ¨λ“  멀버가 public)
interface Interface {
 
    /* public static final */ String name = "name";
 
    /* public abstract */ void method();
 
    /* public */ static void staticMethod() {
        System.out.println("do something");
    }
 
    /* public */ default void defaultMethod() {
        System.out.println("do something");
    }
}

Interface λž€ μƒμˆ˜μ™€ abstract λ©”μ„œλ“œμ˜ μ§‘ν•©μœΌλ‘œ Abstract Class 와 λ™μΌν•˜κ²Œ 이λ₯Ό κ΅¬ν˜„ν•˜λŠ” ν΄λž˜μŠ€μ—μ„œ abstract λ©”μ„œλ“œλ₯Ό μ™„μ„±ν•˜λ„λ‘ κ°•μ œν•˜μ§€λ§Œ Abstract Class 보닀 좔상화 정도가 λ†’λ‹€.

좔상 ν΄λž˜μŠ€κ°€ λ―Έμ™„μ„± 섀계도라면 μΈν„°νŽ˜μ΄μŠ€λŠ” κΈ°λ³Έ 섀계도라고 ν•  수 μžˆλ‹€.

  • 닀쀑 상속이 κ°€λŠ₯ν•˜λ‹€.
  • μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λŠ” μ§‘ν•©κ°„μ—λŠ” 관계가 없을 수 μžˆλ‹€.
  • JDK1.8 static λ©”μ„œλ“œμ™€ default λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•  수 있게 λ˜μ—ˆλ‹€.
  • default λ©”μ„œλ“œμ˜ λͺ©μ μ€ κ΅¬ν˜„μ²΄μ— κ³΅ν†΅μ μœΌλ‘œ μ‚¬μš©λ  λ©”μ„œλ“œλ₯Ό μΈν„°νŽ˜μ΄μŠ€μ— μ„ μ–Έν•˜κΈ° μœ„ν•¨μ΄λ‹€.

μΈν„°νŽ˜μ΄μŠ€μ˜ 상속

  • μΈν„°νŽ˜μ΄μŠ€μ˜ 쑰상은 μΈν„°νŽ˜μ΄μŠ€λ§Œ κ°€λŠ₯ (Objectκ°€ 졜고 쑰상이 μ•„λ‹˜)
  • 닀쀑 상속 κ°€λŠ₯ (좔상 λ©”μ„œλ“œλŠ” μΆ©λŒν•΄λ„ 문제 μ—†μŒ. μ™œ? κ΅¬ν˜„λΆ€κ°€ μ—†μœΌλ‹ˆκΉŒ)
interface Fightable extends Movalbe, Attackable { }
interface Movable {
	void move(int x, int y);
}
interface Attackable {
	void attack(Unit u);
}

μΈν„°νŽ˜μ΄μŠ€μ˜ κ΅¬ν˜„

  • μΈν„°νŽ˜μ΄μŠ€μ— μ •μ˜λœ 좔상 λ©”μ„œλ“œλ₯Ό μ™„μ„±ν•˜λŠ” 것
class Fighter implements Fightable {
	// μΈν„°νŽ˜μ΄μŠ€μ— μ •μ˜λœ μΆ”μƒλ©”μ„œλ“œλ₯Ό λͺ¨λ‘ κ΅¬ν˜„ν•΄μ•Ό 함
	public void move(int x, int y) {
		// λ‚΄μš© κ΅¬ν˜„
	}
	public void attack(Unit u) {
		// λ‚΄μš© κ΅¬ν˜„
	}
}
  • μΌλΆ€λ§Œ κ΅¬ν˜„ν•˜λŠ” 경우, 클래슀 μ•žμ— abstract λ₯Ό λΆ™μ—¬μ•Ό 함
abstract class Fighter implements Fightable {
	public void move(int x, int y) {
		// λ‚΄μš© κ΅¬ν˜„
	}

좔상 ν΄λž˜μŠ€μ™€ μΈν„°νŽ˜μ΄μŠ€μ˜ 차이점

  • 좔상 ν΄λž˜μŠ€λŠ” 일반 ν΄λž˜μŠ€μ™€ κ°™μ§€λ§Œ 좔상 λ©”μ„œλ“œλ₯Ό κ°–κ³  있음
  • μΈν„°νŽ˜μ΄μŠ€λŠ” 좔상 λ©”μ„œλ“œ (static λ©”μ„œλ“œ, default λ©”μ„œλ“œ, μƒμˆ˜) 만 κ°–κ³  있음
    • iv, μƒμ„±μž, μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œ 등을 κ°€μ§ˆ 수 μ—†μŒ

38. μΈν„°νŽ˜μ΄μŠ€μ™€ λ‹€ν˜•μ„±


  • μΈν„°νŽ˜μ΄μŠ€λ„ κ΅¬ν˜„ 클래슀의 λΆ€λͺ¨
class Fighter extends Unit implements Fightable {
	public void move(int x, int y) {
		// λ‚΄μš© κ΅¬ν˜„
	}
	public void attack(Fightable f) {
		// λ‚΄μš© κ΅¬ν˜„
	}
}
// 쑰상 클래슀 -> μžμ† 객체
Unit      u = new Fighter();
// μΈν„°νŽ˜μ΄μŠ€λ„ κ°€λŠ₯. ν•˜μ§€λ§Œ, μΈν„°νŽ˜μ΄μŠ€μ— μ„ μ–Έλœ κΈ°λŠ₯만 μ‚¬μš© κ°€λŠ₯
Fightable f = new Fighter();
f.move(100, 200);
f.attack(new Fighter());
  • μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ©”μ„œλ“œμ˜ λ¦¬ν„΄νƒ€μž…μœΌλ‘œ 지정할 수 있음
// Fightable μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜
Fightable method() {
	return new Fighter();
}
class Fighter extends Unit implements Fightable {
	public void move(int x, int y) {
		// λ‚΄μš© κ΅¬ν˜„
	}
	public void attack(Fightable f) {
		// λ‚΄μš© κ΅¬ν˜„
	}
}

39. μΈν„°νŽ˜μ΄μŠ€μ˜ μž₯점


  • 두 λŒ€μƒ(객체) κ°„μ˜ β€˜μ—°κ±Έ, λŒ€ν™”, μ†Œν†΅β€™μ„ λ•λŠ” β€˜μ€‘κ°„ 역할’
  • μ„ μ–Έ(섀계)와 κ΅¬ν˜„μ„ 뢄리 μ‹œν‚¬ 수 있음
// 껍데기 + μ•Œλ§Ήμ΄
class B {
	public void method() {
		System.out.println("methodInB");
	}
}
// 껍데기
interface I {
	public void method();
}
// μ•Œλ§Ήμ΄
class B implements I {
	public void method() {
		System.out.println("methodInB");
	}
}
  • μΈν„°νŽ˜μ΄μŠ€ 덕뢄에 Bκ°€ λ³€κ²½λ˜μ–΄λ„ AλŠ” μ•ˆ λ°”κΏ€ 수 있게 λœλ‹€. (λŠμŠ¨ν•œ κ²°ν•©)
    • Aκ°€ B에 의쑴적일 λ•Œ
class A {
	public void methodA(B b) {
		b.methodB();
	}
}
class B {
	public void methodB() {
		System.out.println("methodB()");
	}
}
class InterfaceTest {
	public static void main(String args[]) {
		A a = new A();
		a.methodA(new B());
	}
}
// B와 관계 없어진 A
class A {
	public void methodA(I i) {
		i.methodB();
	}
}
interface I {
	void methodB();
}
class B implemetns I {
	public void methodB() {
		System.out.println("methodB()");
	}
}
// Bλ₯Ό C둜 λ³€κ²½ μ‹œ AλŠ” λ³€κ²½ μ—†μŒ
class C implemetns I {
	public void methodB() {
		System.out.println("methodB() in C");
	}
}
  • 개발 μ‹œκ°„μ„ 단좕
    • Aκ°€ B에 의쑴적일 λ•Œ B의 μΈν„°νŽ˜μ΄μŠ€λ₯Ό 미리 κ΅¬ν˜„ν•¨μœΌλ‘œμ¨ Bκ°€ μ™„μ„±λ˜κΈ° μ „ Aλ₯Ό 개발
  • 변경에 μœ λ¦¬ν•œ μœ μ—°ν•œ 섀계가 κ°€λŠ₯
  • ν‘œμ€€ν™”κ°€ κ°€λŠ₯ (Aκ°€ μ˜μ‘΄ν•˜λŠ” B와 C의 곡톡 ν‘œμ€€μ„ μš”κ΅¬ν•  수 있음)
  • μ„œλ‘œ κ΄€κ³„μ—†λŠ” ν΄λž˜μŠ€λ“€μ„ 관계λ₯Ό 맺어쀄 수 있음
// GroundUnit μžμ†μœΌλ‘œ Marine, SCV, Tank κ°€ 있고
// SCV, Tank 만 repair() λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•˜κ³  싢을 λ•Œ
// repairable μ΄λΌλŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•¨μœΌλ‘œμ¨ κ΄€κ³„μ—†λŠ” 클래슀 간에 곡톡점 생성 κ°€λŠ₯
void repair(Repariable r) {
	if (r instanceof Unit) {
		Unit u = (Unit)r;
		while (u.hitPoint != u.MAX_HP) {
			u.hitPoint++;
		}
	}
}

40~41. default λ©”μ„œλ“œ, static λ©”μ„œλ“œ


  • μΈν„°νŽ˜μ΄μŠ€μ— default λ©”μ„œλ“œ, static λ©”μ„œλ“œ μΆ”κ°€ κ°€λŠ₯. (JDK 1.8 λΆ€ν„°)
  • μΈν„°νŽ˜μ΄μŠ€μ— μƒˆλ‘œμš΄ λ©”μ„œλ“œ(좔상 λ©”μ„œλ“œ)λ₯Ό μΆ”κ°€ν•˜κΈ° 어렀움.
    • 기쑴에 μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν–ˆλ˜ λ‹€μˆ˜μ˜ ν΄λž˜μŠ€κ°€ μΈν„°νŽ˜μ΄μŠ€μ— μƒˆλ‘œμš΄ λ©”μ„œλ“œκ°€ 생겼을 λ•Œ 각자 ν•΄λ‹Ή λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•΄μ•Ό ν–ˆμŒ
    • ν•΄κ²°μ±… β‡’ λͺΈν†΅μ΄ μžˆλŠ” default method
  • default λ©”μ„œλ“œ = μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œ(μΈν„°νŽ˜μ΄μŠ€ 원칙 μœ„λ°˜)
interface MyInterface {
	void method();
	default void newMethod() { // λ‚΄μš© κ΅¬ν˜„ }
}
  • default λ©”μ„œλ“œκ°€ 기쑴의 λ©”μ„œλ“œμ™€ μΆ©λŒν•  λ•Œμ˜ ν•΄κ²°μ±…
    • μ—¬λŸ¬ μΈν„°νŽ˜μ΄μŠ€μ˜ default λ©”μ„œλ“œ κ°„μ˜ 좩돌
      • μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ ν΄λž˜μŠ€μ—μ„œ default λ©”μ„œλ“œλ₯Ό μ˜€λ²„λΌμ΄λ”©ν•΄μ•Ό 함
    • default λ©”μ„œλ“œμ™€ 쑰상 클래슀의 λ©”μ„œλ“œ κ°„μ˜ 좩돌
      • 쑰상 클래슀의 λ©”μ„œλ“œκ°€ μƒμ†λ˜κ³ , default λ©”μ„œλ“œλŠ” λ¬΄μ‹œ

42~44. λ‚΄λΆ€ 클래슀의 μ’…λ₯˜, νŠΉμ§•, μ„ μ–Έ


λ‚΄λΆ€ 클래슀 (inner class)

  • 클래슀 μ•ˆμ˜ 클래슀
class A {   // μ™ΈλΆ€ 클래슀
	class B { // λ‚΄λΆ€ 클래슀
		// 객체 생성 없이 A의 멀버 μ ‘κ·Ό κ°€λŠ₯
		...
	}
}

μž₯점

  • λ‚΄λΆ€ ν΄λž˜μŠ€μ—μ„œ μ™ΈλΆ€ 클래슀의 멀버듀을 μ‰½κ²Œ μ ‘κ·Όν•  수 있음
  • μ½”λ“œμ˜ λ³΅μž‘μ„±μ„ 쀄일 수 있음 (μΊ‘μŠν™”)

νŠΉμ§•

  • λ‚΄λΆ€ 클래슀의 μ’…λ₯˜μ™€ μœ νš¨λ²”μœ„(scope)λŠ” λ³€μˆ˜μ™€ 동일
class Outer {
	class InstanceInner { }
	static class StaticInner { }
	void myMethod() {
		class LocalInner { }
	}
}
λ‚΄λΆ€ ν΄λž˜μŠ€νŠΉμ§•
μΈμŠ€ν„΄μŠ€ ν΄λž˜μŠ€μ™ΈλΆ€ 클래슀의 λ©€λ²„λ³€μˆ˜ μ„ μ–Έμœ„μΉ˜μ— μ„ μ–Έ. μ™ΈλΆ€ 클래슀의 μΈμŠ€ν„΄μŠ€ λ©€λ²„μ²˜λŸΌ 닀루어짐. 주둜 μ™ΈλΆ€ 클래슀의 μΈμŠ€ν„΄μŠ€ 멀버듀과 κ΄€λ ¨λœ μž‘μ—…μ— μ‚¬μš©
static ν΄λž˜μŠ€μ™ΈλΆ€ 클래슀의 λ©€λ²„λ³€μˆ˜ μ„ μ–Έμœ„μΉ˜μ— μ„ μ–Έ μ™ΈλΆ€ 클래슀의 static λ©€λ²„μ²˜λŸΌ 닀루어짐. 주둜 μ™ΈλΆ€ 클래슀의 static 멀버, 특히 static λ©”μ„œλ“œμ— μ‚¬μš©λ  λͺ©μ μœΌλ‘œ μ„ μ–Έ
local ν΄λž˜μŠ€μ™ΈλΆ€ 클래슀의 λ©”μ„œλ“œλ‚˜ μ΄ˆκΈ°ν™” λΈ”λŸ­ μ•ˆμ— μ„ μ–Έ μ„ μ–Έλœ μ˜μ—­ λ‚΄λΆ€μ—μ„œλ§Œ μ‚¬μš© κ°€λŠ₯
읡λͺ… 클래슀클래슀의 μ„ μ–Έκ³Ό 객체의 생성을 λ™μ‹œμ— ν•˜λŠ” μ΄λ¦„μ—†λŠ” 클래슀 (일회용)

45~50. λ‚΄λΆ€ 클래슀의 μ œμ–΄μžμ™€ μ ‘κ·Όμ„±


  • λ‚΄λΆ€ 클래슀의 μ œμ–΄μžλŠ” λ³€μˆ˜μ— μ‚¬μš© κ°€λŠ₯ν•œ μ œμ–΄μžμ™€ 동일
    • 일반 ν΄λž˜μŠ€λŠ” default λž‘ public 만 κ°€λŠ₯
    • λ‚΄λΆ€ ν΄λž˜μŠ€λŠ” protected λž‘ private 도 κ°€λŠ₯
class Outer {
	private class InstanceInner { }
	protected static class StaticInner { }
	void myMethod() {
		class LocalInner { }
	}
}

λ‚΄λΆ€ 클래슀의 μ œμ–΄μžμ™€ μ ‘κ·Όμ„± - 예제

class Ex7_12 {
	class InstanceInner {
		int iv = 100;
		// static int cv = 100;       // μ—λŸ¬. static λ³€μˆ˜λ₯Ό μ„ μ–Έν•  수 μ—†μŒ
		final static int CONST = 100; // μƒμˆ˜λŠ” ν—ˆμš©
	}
	static class StaticInner {
		int iv = 200;
		static int cv = 200; // static 클래슀만 static 멀버 μ •μ˜ κ°€λŠ₯
	}
	void myMethod() {
		class LocalInner {
			int iv = 300;
			// static int cv = 300;       // μ—λŸ¬. static λ³€μˆ˜λ₯Ό μ„ μ–Έν•  수 μ—†μŒ
			final static int CONST = 300; // μƒμˆ˜λŠ” ν—ˆμš©
		}
	}
	public static void main(String[] args) {
		System.out.println(InstanceInner.CONST);
		System.out.println(StaticInner.cv);
		// System.out.println(LocalInner.CONST); // μ—λŸ¬. λ©”μ„œλ“œ λ‚΄μ—μ„œλ§Œ κ°€λŠ₯
	}
}

51~52. 읡λͺ… 클래슀


  • 이름이 μ—†λŠ” 일회용 클래슀. μ •μ˜μ™€ 생성을 λ™μ‹œμ—
new μ‘°μƒν΄λž˜μŠ€μ΄λ¦„() {
	// 멀버 μ„ μ–Έ
}
new κ΅¬ν˜„μΈν„°νŽ˜μ΄μŠ€μ΄λ¦„() {
	// 멀버 μ„ μ–Έ
}

읡λͺ… 클래슀 - 예제

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Ex7_18 {
	public static void main(String[] args) {
		Button b = new Button();
		// 클래슀 μ •μ˜μ™€ 객체 생성 λ”°λ‘œ
		b.addActionListener(new EventHandler());
		// 클래슀 μ •μ˜μ™€ 객체 생성 λ™μ‹œμ—
		b.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				System.out.println("ActionEvent occurred!!");
			}
		});
	}
}
class EventHandler implements ActionListener {
	public void actionPerformed(ActionEvent e) {
		System.out.println("ActionEvent occurred!!");
	}
}