본문으둜 κ±΄λ„ˆλ›°κΈ°

🌈 Chapter 1: Birth

  • κ°μ²΄λŠ” μžμ‹ μ˜ κ°€μ‹œμ„± λ²”μœ„(scope of visibility) μ•ˆμ—μ„œ μ‚΄μ•„κ°„λ‹€.
if (price < 100) {
Cash extra = new Cash(5);
price.add(extra);
}
  • μ˜ˆμ œμ—μ„œ if블둝 μ•ˆμ—μ„œλ§Œ extraλΌλŠ” 객체λ₯Ό λ³Ό 수 있기 λ•Œλ¬Έμ—, if블둝 λ‚΄λΆ€κ°€ extra 객체의 κ°€μ‹œμ„± λ²”μœ„κ°€ λœλ‹€. μ˜ˆμ œμ—μ„œ 숫자 5λŠ” 객체 내뢀에 λ‚¨μ•„μžˆκ³ , priceλŠ” 객체의 외뢀에 μ‘΄μž¬ν•œλ‹€.
  • 객체지ν–₯ ν”„λ‘œκ·Έλž˜λ°μ—μ„œ 객체와 객체의 역할을 μ΄ν•΄ν•¨μœΌλ‘œμ¨ μ½”λ“œμ˜ μœ μ§€λ³΄μˆ˜μ„±μ„ ν–₯μƒμ‹œν‚¬ 수 μžˆλ‹€. μ½”λ“œμ˜ κΈΈμ΄λŠ” 더 짧아지고, μ†Œν™”ν•˜κΈ° μ‰¬μ›Œμ§€λ©°, λͺ¨λ“ˆμ„±μ΄ ν–₯μƒλ˜κ³ , 응집도가 높아진닀.

πŸ¦„ -er둜 λλ‚˜λŠ” 이름을 μ‚¬μš©ν•˜μ§€ λ§ˆμ„Έμš”β€‹

  • ν΄λž˜μŠ€λŠ” 객체의 νŒ©ν† λ¦¬μ΄λ‹€.
  • ν΄λž˜μŠ€λŠ” 객체λ₯Ό μƒμ„±ν•˜κ³  ν΄λž˜μŠ€κ°€ 객체λ₯Ό μΈμŠ€ν„΄μŠ€ν™”ν•œλ‹€λΌκ³  ν‘œν˜„ν•œλ‹€.
class Cash {
public Cash(int dollars) {
// ...
}
}

Cash five = new Cash(5);
  • newλŠ” 객체의 νŒ©ν† λ¦¬λ₯Ό μ œμ–΄ν•  수 μžˆλŠ” μ›μ‹œμ μΈ μˆ˜λ‹¨μ΄λ‹€.
  • newλŠ” Cash 클래슀의 정적 λ©”μ„œλ“œμ΄λ©°, newκ°€ 호좜되면 Cashν΄λž˜μŠ€κ°€ μ œμ–΄λ₯Ό νšλ“ν•œ ν›„ five객체λ₯Ό μƒμ„±ν•œλ‹€.
  • new μ—°μ‚°μžκ°€ μ‹€ν–‰λ˜κΈ° 전에 뢀가적인 λ‘œμ§μ„ 더할 수 있기 λ•Œλ¬Έμ—, newμ—°μ‚°μžλ₯Ό 보닀 μœ μ—°ν•˜κ²Œ μ‚¬μš©ν•  수 μžˆλ‹€.
class Shapes {
public Shape make(String name) {
if (name.equals("circle")) {
return new Circle();
}

if (name.equals("rectangle")) {
return new Rectangle();
}

throw new IllegalArgumentException("not found");
}
}
  • 클래슀λ₯Ό ν”Œμš”ν•  λ•Œ 객체λ₯Ό κΊΌλ‚Ό 수 있고, 더 이상 ν•„μš”ν•˜μ§€ μ•Šμ€ 객체λ₯Ό λ°˜ν™˜ν•  수 μžˆλŠ” 객체의 μ›¨μ–΄ν•˜μš°μŠ€λ‘œ λ³΄λŠ” 것이 μ’‹λ‹€.
  • ν΄λž˜μŠ€λŠ” 객체의 ν…œν”Œλ¦Ώμ΄ μ•„λ‹ˆλ‹€ νŒ©ν† λ¦¬μ΄λ‹€. (ν΄λž˜μŠ€λŠ” 객체의 λŠ₯동적인 κ΄€λ¦¬μžλΌκ³  생각해야 ν•œλ‹€.)
  • μ•„λž˜μ˜ μ˜ˆμ œλŠ” 객체λ₯Ό 이름을 μ§“λŠ”λ° 잘λͺ»λœ λ°©λ²•μœΌλ‘œ 클래슀의 객체듀이 무엇을 ν•˜κ³  μžˆλŠ”μ§€λ₯Ό μ‚΄νŽ΄λ³Έ ν›„ κΈ°λŠ₯에 κΈ°λ°˜ν•΄μ„œ 이름을 μ§“λŠ” 방법이닀.
class CashFormatter {
private int dollars;

CashFormatter(int dlr) {
this.dollars = dlr;
}

public String format() {
return String.format("$ %d", this.dollars);
}
}
  • μœ„μ™€ 같이 클래슀의 이름은 객체가 λ…ΈμΆœν•˜κ³  μžˆλŠ” κΈ°λŠ₯에 κΈ°λ°˜ν•΄μ„œλŠ” μ•ˆλœλ‹€.
  • 클래슀의 이름은 무엇을 ν•˜λŠ”μ§€κ°€ μ•„λ‹ˆλΌ 무엇인지에 κΈ°λ°˜ν•΄μ•Ό ν•œλ‹€.
class Cash {
private int dollars;
Cash(int dlr) {
this.dollars = dlr;
}

public String usd() {
return String.format("$ %d", this.dollars);
}
}
  • λ‹€μ‹œ λ§ν•΄μ„œ, κ°μ²΄λŠ” 그의 μ—­λŸ‰(capability)으둜 νŠΉμ •μ§€μ–΄μ Έμ•Ό ν•œλ‹€.
  • μ—¬κΈ°μ„œ λ§ν•˜λŠ” κ²ƒμ²˜λŸΌ λ°”λ‘œ 접미사 -er을 μ‚¬μš©ν•˜λ©΄ μ•ˆλœλ‹€. (Manager, Controller, Helper, Handler, Writer, Validator, Router etc..)
  • μ˜ˆμ™ΈμΈ κ·œμΉ™λ„ μ‘΄μž¬ν•˜λŠ”λ° 였랜 μ‹œκ°„μ΄ 흐λ₯΄λ©΄μ„œ μ˜λ―Έκ°€ μ •μ°©λœ κ²½μš°μ΄λ‹€. λŒ€ν‘œμ μΈ μ˜ˆκ°€ computer, user이닀.
  • κ°μ²΄λŠ” 객체의 μ™ΈλΆ€ 세계와 λ‚΄λΆ€ 세계λ₯Ό μ΄μ–΄μ£ΌλŠ” μ—°κ²°μž₯μΉ˜κ°€ μ•„λ‹ˆλΌ κ°μ²΄λŠ” μΊ‘μŠν™”λœ λ°μ΄ν„°μ˜ λŒ€ν‘œμžμ΄λ‹€. 즉, λŒ€ν‘œμžλŠ” 슀슀둜 결정을 내리고 행동할 수 μžˆλŠ” 자립적인 엔티티이닀.
  • λ•Œλ¬Έμ— 클래슀의 이름이 -er둜 λλ‚œλ‹€λ©΄, 이 클래슀의 μΈμŠ€ν„΄μŠ€λŠ” μ‹€μ œλ‘œλŠ” 객체가 μ•„λ‹ˆλΌ μ–΄λ–€ 데이터λ₯Ό λ‹€λ£¨λŠ” μ ˆμ°¨λ“€μ˜ 집합일 뿐이닀.
  • μ˜¬λ°”λ₯Έ 클래슀λ₯Ό 이름은 클래슀의 객체듀이 무엇을 μΊ‘μŠν™”ν•  것인지λ₯Ό κ΄€μ°°ν•˜κ³  이 μš”μ†Œλ“€μ— 뢙일 μ ν•©ν•œ 이름을 μ°Ύμ•„μ•Ό ν•œλ‹€.
class PrimeNumbers
def initialize(origin)
@origin = origin
end

def each
@origin
.select{ |i| prime? i }
.each{ |i| yield i }
end

def prime?(x)
# ...
end
end
  • PrimeNumbers ν΄λž˜μŠ€λŠ” μˆ«μžλ“€μ˜ 리슀트처럼 ν–‰λ™ν•˜μ§€λ§Œ 였직 μ†Œμˆ˜λ§Œ λ°˜ν™˜ν•œλ‹€.
  • 이처럼 숫자 리슀트λ₯Ό μΊ‘μŠν™”ν•˜κ³  μžˆλŠ” λ™μ•ˆμ—λŠ”, μ™ΈλΆ€μ—μ„œ 직접 객체 내뢀에 ν¬ν•¨λœ 숫자 리슀트λ₯Ό μ²˜λ¦¬ν•˜κ±°λ‚˜ μ‘°νšŒν•˜λ„λ‘ ν—ˆμš©ν•΄μ„œλŠ” μ•ˆλœλ‹€. PrimeNumbersλŠ” 숫자의 λ¦¬μŠ€νŠΈμ΄λ‹€.(is a) 리슀트 κ·Έ μžμ²΄μ΄λ‹€.

πŸ¦„ μƒμ„±μž ν•˜λ‚˜λ₯Ό μ£Ό μƒμ„±μžλ‘œ λ§Œλ“œμ„Έμš”β€‹

  • constructorλŠ” μƒˆλ‘œμš΄ 객체에 λŒ€ν•œ μ§„μž…μ μœΌλ‘œ λͺ‡ 개의 μΈμžλ“€μ„ 전달받아, μ–΄λ–€ 일을 μˆ˜ν–‰ν•œ ν›„, μž„λ¬΄λ₯Ό μˆ˜ν–‰ν•  수 μžˆλ„λ‘ 객체λ₯Ό μ€€λΉ„μ‹œν‚¨λ‹€.
class Cash {
private int dollar;
Cash(int dlr) {
this.dollars = dlr;
}
}
  • μ˜ˆμ œλŠ” ν•˜λ‚˜μ˜ constructorκ°€ μ‘΄μž¬ν•˜κ³  μˆ˜ν–‰ν•˜λŠ” ν•˜λ‚˜μ˜ μž‘μ—…μ€ 인자둜 μ „λ‹¬λœ λ‹¬λŸ¬λ₯Ό dollarsλΌλŠ” μ΄λ¦„μ˜ private μ •μˆ˜ ν”„λ‘œνΌν‹°μ— μΊ‘μŠν™”ν•˜λŠ” 것이닀.
  • μ΄λ•Œ 2 ~ 3개의 λ©”μ„œλ“œμ™€ 5 ~ 10개의 constructorλ₯Ό ν¬ν•¨ν•˜λŠ” 것이 μ λ‹Ήν•˜λ‹€.
  • constructor의 κ°œμˆ˜κ°€ λ§Žμ•„μ§ˆ 수둝 더 κ°œμ„ λ˜κ³ , μ‚¬μš©μž μž…μž₯μ—μ„œ 클래슀λ₯Ό 더 νŽΈν•˜κ²Œ μ‚¬μš©ν•  수 μžˆλ‹€. ν•˜μ§€λ§Œ λ©”μ„œλ“œκ°€ λ§Žμ•„μ§ˆμˆ˜λ‘ 클래슀λ₯Ό μ‚¬μš©ν•˜κΈ°λŠ” 더 μ–΄λ €μ›Œμ§„λ‹€. λ©”μ„œλ“œκ°€ λ§Žμ•„μ§€λ©΄ 클래슀의 초점이 흐렀지고, 단일 μ±…μž„ 원칙을 μœ„λ°˜ν•œλ‹€.
  • constructor의 주된 μž‘μ—…μ€ 제곡된 인자λ₯Ό μ‚¬μš©ν•΄μ„œ μΊ‘μŠν™”ν•˜κ³  μžˆλŠ” ν”„λ‘œνΌν‹°λ₯Ό μ΄ˆκΈ°ν™”ν•˜λŠ” 일이닀. 이런 μ΄ˆκΈ°ν™” λ‘œμ§μ„ 단 ν•˜λ‚˜μ˜ constructorμ—λ§Œ μœ„μΉ˜μ‹œν‚€κ³  μ£Ό constructor라고 λΆ€λ₯΄κΈ°λ₯Ό ꢌμž₯ν•˜κ³  μ•„λž˜μ˜ 예제처럼 λΆ€ constructor라고 λΆ€λ₯΄λŠ” λ‹€λ₯Έ constructor듀이 이 μ£Ό constructorλ₯Ό ν˜ΈμΆœν•˜λ„λ‘ λ§Œλ“€μ–΄μ•Ό ν•œλ‹€.
class Cash {
private int dollars;

Cash(float dlr) { // λΆ€
this((int) dlr);
}

Cash(String dlr) { // λΆ€
this(Cash.parse(dlr));
}

Cash(int dlr) { // μ£Ό constructor
this.dollars = dlr;
}
}
  • μœ μ§€λ³΄μˆ˜μ„±μ„ μœ„ν•΄ μ£Ό constructorλ₯Ό λͺ¨λ“  λΆ€ constructor뒀에 μœ„μΉ˜μ‹œν‚¨λ‹€.
  • ν•˜λ‚˜μ˜ μ£Ό constructor와 λ‹€μˆ˜μ˜ λΆ€ constructor μ›μΉ™μ˜ 핡심은 쀑볡 μ½”λ“œλ₯Ό λ°©μ§€ν•˜κ³  섀계λ₯Ό 더 κ°„κ²°ν•˜κ²Œ λ§Œλ“€κΈ° λ•Œλ¬Έμ— μœ μ§€λ³΄μˆ˜μ„±μ΄ ν–₯μƒλœλ‹€λŠ” 것이닀.
  • λ‚΄λΆ€μ˜ ν”„λ‘œνΌν‹°λŠ” 였직 ν•œ κ³³μ—μ„œλ§Œ μ΄ˆκΈ°ν™”ν•΄μ•Ό ν•œλ‹€λŠ” 핡심 원칙이닀.

πŸ¦„ μƒμ„±μžμ— μ½”λ“œλ₯Ό 넣지 λ§ˆμ„Έμš”β€‹

  • μ£Ό constructorμ—λŠ” 객체 μ΄ˆκΈ°ν™” ν”„λ‘œμ„ΈμŠ€λ₯Ό μ‹œμž‘ν•˜λŠ” μœ μΌν•œ μž₯μ†Œμ΄κΈ° λ•Œλ¬Έμ— μ œκ³΅λ˜λŠ” μΈμžλ“€μ€ μ™„μ „ν•΄μ•Ό ν•œλ‹€.
  • 인자λ₯Ό μ–΄λ–»κ²Œ 닀루어야 ν• κΉŒ?
  • 일단, μΈμžμ— 손을 λŒ€μ§€λ§λΌλŠ” 것이닀.
class Cash {
private int dollars;

Cash(String dlr) {
this.dollars = Integer.parseInt(dlr);
}
}
  • μœ„μ—μ„œ ν΄λž˜μŠ€κ°€ 내뢀에 μΊ‘μŠν™”ν•˜κ³  μžˆλŠ” 것은 μ •μˆ˜ν˜•μ΄μ§€λ§Œ, constructor에 μ„ μ–Έλœ 인자의 νƒ€μž…μ€ λ¬Έμžμ—΄μ΄λ‹€. λ•Œλ¬Έμ— μ „λ‹¬λœ λ¬Έμžμ—΄μ„ μ •μˆ˜λ‘œ λ³€ν™˜ν•  ν•„μš”κ°€ μžˆμ–΄ 이 μž‘μ—…μ„ constructorλ‚΄λΆ€μ—μ„œ μ²˜λ¦¬ν•˜κ³  μžˆλ‹€. ν•˜μ§€λ§Œ μ΄λŸ¬ν•œ 방법은 μ•„μ£Ό 잘λͺ»λœ 방법이닀.
  • 객체 μ΄ˆκΈ°ν™”μ—λŠ” μ½”λ“œκ°€ μ—†μ–΄μ•Όν•˜κ³  인자λ₯Ό κ±΄λ“œλ €μ„œλŠ” μ•ˆλœλ‹€. λŒ€μ‹ , ν•„μš”ν•˜λ‹€λ©΄ μΈμžλ“€μ„ λ‹€λ₯Έ νƒ€μž…μ˜ 객체둜 κ°μ‹Έκ±°λ‚˜ κ°€κ³΅ν•˜μ§€ μ•Šμ€ ν˜•μ‹μœΌλ‘œ μΊ‘μŠν™”ν•΄μ•Ό ν•œλ‹€.
  • λ‹€μŒμ€ 인자λ₯Ό μ „λ‹¬λœ ν…μŠ€νŠΈλ₯Ό κ±΄λ“œλ¦¬μ§€ μ•Šκ³  λ™μΌν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•œ μ˜ˆμ‹œμ΄λ‹€.
class Cash {
private Number dollars;

Cash(String dlr) { // λΆ€ constructor
this(new StringAsInteger(dlr));
}

Cash(Number dlr) { // μ£Ό constructor
this.dollars = dlr;
}
}

class StringAsInteger implements Number {
private String source;

StringAsInteger(String src) {
this.source = src;
}

int intValue() {
return Integer.parseInt(this.source);
}
}

Cash five = new Cash("5");
  • 첫 번째 예제의 객체 fiveλŠ” 숫자 5λ₯Ό μΊ‘μŠν™”ν•˜μ§€λ§Œ, 두 번째 예제의 객체 fiveλŠ” Number처럼 λ³΄μ΄λŠ” StringAsInteger μΈμŠ€ν„΄μŠ€λ₯Ό μΊ‘μŠν™”ν•œλ‹€.
  • μ§„μ •ν•œ 객체지ν–₯μ—μ„œ μΈμŠ€ν„΄μŠ€ν™”λž€ 더 μž‘μ€ 객체듀을 μ‘°ν•©ν•΄μ„œ 더 큰 객체λ₯Ό λ§Œλ“œλŠ” 것을 μ˜λ―Έν•œλ‹€. 객체듀을 μ‘°ν•©ν•΄μ•Ό ν•˜λŠ” 단 ν•˜λ‚˜μ˜ μ΄μœ λŠ” μƒˆλ‘œμš΄ 계약을 μ€€μˆ˜ν•˜λŠ” μƒˆλ‘œμš΄ μ—”ν‹°ν‹°κ°€ ν•„μš”ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.
  • 제일 처음 ν•  일은 객체λ₯Ό μΈμŠ€ν„΄μŠ€ν™”ν•˜λŠ” 것이고 두 번째 ν•  일은 객체가 우리λ₯Ό μœ„ν•΄ μž‘μ—…μ„ ν•˜κ²Œ λ§Œλ“œλŠ” 것이닀. constructorλŠ” μ–΄λ–€ 일을 μˆ˜ν–‰ν•˜λŠ” 곳이 μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— constructorμ•ˆμ—μ„œ μΈμžμ—κ²Œ μ–΄λ–€ μž‘μ—…μ„ μš”μ²­ν•΄μ„œλŠ” μ•ˆλœλ‹€. λ‹€μ‹œ λ§ν•΄μ„œ μƒμ„±μžλŠ” μ½”λ“œκ°€ μ—†μ–΄μ•Όν•˜κ³ , 였직 ν• λ‹Ήλ¬Έλ§Œ 포함해야 ν•œλ‹€.
  • 이 쑰언을 μ§€μ§€ν•˜λŠ” μ΄μœ λŠ” 첫째둜 constructor에 μ½”λ“œκ°€ 없을 경우 μ„±λŠ₯ μ΅œμ ν™”κ°€ 더 쉽기 λ•Œλ¬Έμ— μ½”λ“œμ˜ μ‹€ν–‰ 속도가 더 빨라진닀.
class StringAsInteger implements Number {
private String text;

public StringAsInteger(String txt) {
this.text = txt;
}

public int intValue() {
return Integer.parseInt(this.text);
}
}

Number num = new StringAsInteger("123");
num.intValue();
num.intValue();
  • μœ„ μ½”λ“œλŠ” intValue()λ₯Ό ν˜ΈμΆœν•  λ•Œλ§ˆλ‹€ 맀번 ν…μŠ€νŠΈλ₯Ό μ •μˆ˜λ‘œ νŒŒμ‹±ν•œλ‹€.
class StringAsInteger implements Number {
private int num;

public StringAsInteger(String txt) {
this.num = Integer.parseInt(txt);
}

public int intValue() {
return this.num;
}
}
  • ν…μŠ€νŠΈ νŒŒμ‹±μ€ 객체λ₯Ό μ΄ˆκΈ°ν™”ν•˜λŠ” μ‹œμ μ— 단 ν•œ 번 μˆ˜ν–‰ν•˜κΈ° λ•Œλ¬Έμ— μ‹€μ œλ‘œ 이 μ½”λ“œκ°€ 더 νš¨μœ¨μ μ΄λ‹€. ν•˜μ§€λ§Œ constructorμ—μ„œ 직접 νŒŒμ‹±μ„ μˆ˜ν–‰ν•˜λŠ” 두 번재 μ˜ˆμ œλŠ” μ΅œμ ν™”κ°€ λΆˆκ°€λŠ₯ν•˜λ‹€. 이 κ²½μš°μ—λŠ” 객체λ₯Ό λ§Œλ“€ λ•Œλ§ˆλ‹€ 맀번 νŒŒμ‹±μ΄ μˆ˜ν–‰λ˜κΈ° λ•Œλ¬Έμ— μ‹€ν–‰ μ—¬λΆ€λ₯Ό μ œμ–΄ν•  수 μ—†λ‹€. intValue()λ₯Ό ν˜ΈμΆœν•  ν•„μš”κ°€ μ—†λŠ” κ²½μš°μ—λ„ CPUλŠ” νŒŒμ‹±μ„ μœ„ν•΄ μ‹œκ°„μ„ μ†Œλͺ¨ν•œλ‹€.
  • λ°˜λŒ€λ‘œ 인자λ₯Ό μ „λ‹¬λœ μƒνƒœ κ·ΈλŒ€λ‘œ μΊ‘μŠν™”ν•˜κ³  λ‚˜μ€‘μ— μš”μ²­μ΄ μžˆμ„ λ•Œ νŒŒμ‹±ν•˜λ„λ‘ ν•˜λ©΄, 클래슀의 μ‚¬μš©μžλ“€μ΄ νŒŒμ‹± μ‹œμ μ„ 자유둭게 κ²°μ •ν•  수 있게 λœλ‹€.
  • νŒŒμ‹±μ„ μ—¬λŸ¬ 번 μˆ˜ν–‰λ˜μ§€ μ•Šλ„λ‘ ν•˜κ³  μ‹Άλ‹€λ©΄ λ°μ½”λ ˆμ΄ν„°λ₯Ό μΆ”κ°€ν•΄μ„œ 졜초의 νŒŒμ‹± κ²°κ³Όλ₯Ό 캐싱할 μˆ˜λ„ μžˆλ‹€.
class CachedNumber implements Number {
private Number origin;

private Collection<Integer> cached = new ArrayList<>(1);

public CachedNumber(Number num) {
this.origin = num;
}

public int intValue() {
if (this.cached.isEmpty()) {
this.cached.add(this.origin.intValue());
}

return this.cached.get(0);
}
}

Number num = new CachedNumber(
new StringAsInteger("123");
);
num.intValue(); // 첫 번째 νŒŒμ‹±
num.intValue(); // μ—¬κΈ°μ„œλŠ” νŒŒμ‹±ν•˜μ§€ μ•ŠμŒ
  • 객체λ₯Ό μΈμŠ€ν„΄μŠ€ν™”ν•˜λŠ” λ™μ•ˆμ— 객체λ₯Ό λ§Œλ“œλŠ” 일 μ΄μ™Έμ—λŠ” μ–΄λ–€ 일도 μˆ˜ν–‰ν•˜μ§€ μ•ŠλŠ”λ‹€. μ‹€μ œ μž‘μ—…μ€ 객체의 λ©”μ„œλ“œκ°€ μˆ˜ν–‰ν•œλ‹€. 이둜 μΈν•΄μ„œ μš°λ¦¬κ°€ 직접 이 과정을 μ œμ–΄ν•  수 μžˆλ‹€.
  • λ”°λΌμ„œ μƒμ„±μžμ—μ„œ μ½”λ“œλ₯Ό μ—†μ• λ©΄ μ‚¬μš©μžκ°€ μ‰½κ²Œ μ œμ–΄ν•  수 μžˆλŠ” 투λͺ…ν•œ 객체λ₯Ό λ§Œλ“€ 수 있으며, 객체λ₯Ό μ΄ν•΄ν•˜κ³  μž¬μ‚¬μš©ν•˜κΈ°λ„ μ‰¬μ›Œμ§„λ‹€.