상속

파이 ΰ°‡Β·2023λ…„ 6μ›” 5일
1
post-thumbnail

πŸ’‘ λͺ©ν‘œ : μžλ°”μ˜ 상속에 λŒ€ν•΄ ν•™μŠ΅ν•΄λ³΄μž.

⚑️ λͺ©μ°¨

  • μžλ°” μƒμ†μ˜ νŠΉμ§•
  • super ν‚€μ›Œλ“œ
  • λ©”μ†Œλ“œ μ˜€λ²„λΌμ΄λ”©
  • λ‹€μ΄λ‚˜λ―Ή λ©”μ†Œλ“œ λ””μŠ€νŒ¨μΉ˜ (Dynamic Method Dispatch)
  • 좔상 클래슀
  • final ν‚€μ›Œλ“œ
  • Object 클래슀

μƒμ†μ˜ κ°œλ…

상속(inheritance)μ΄λž€ 기쑴의 ν΄λž˜μŠ€μ— κΈ°λŠ₯을 μΆ”κ°€ν•˜κ±°λ‚˜ μž¬μ •μ˜ν•˜μ—¬ μƒˆλ‘œμš΄ 클래슀λ₯Ό μ •μ˜ν•˜λŠ”κ²ƒμ„ μ˜λ―Έν•œλ‹€. μ΄λŸ¬ν•œ 상속은 μΊ‘μŠν™”, 좔상화와 λ”λΆˆμ–΄ 객체 지ν–₯ ν”„λ‘œκ·Έλž˜λ°μ„ κ΅¬μ„±ν•˜λŠ” μ€‘μš”ν•œ νŠΉμ§• 쀑 ν•˜λ‚˜μ΄λ‹€. 상속을 μ΄μš©ν•˜λ©΄ 기쑴에 μ •μ˜λ˜μ–΄ μžˆλŠ” 클래슀의 λͺ¨λ“  ν•„λ“œμ™€ λ©”μ„œλ“œλ₯Ό λ¬Όλ €λ°›μ•„, μƒˆλ‘œμš΄ 클래슀λ₯Ό 생성할 수 μžˆλ‹€.

μƒμ†μ˜ μž₯점

  1. 기쑴에 μž‘μ„±λœ μ½”λ“œλ₯Ό μž¬ν™œμš© ν•  수 μžˆμ–΄ κ°œλ°œμ‹œκ°„μ΄ λ‹¨μΆ•λœλ‹€.
  2. λ¨Όμ € μž‘μ„±ν•œ κ²€μ¦λœ ν”„λ‘œκ·Έλž¨μ„ μž¬μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— μ‹ λ’°μ„± μžˆλŠ” ν”„λ‘œκ·Έλž¨ 개발 κ°€λŠ₯.
  3. 클래슀 κ°„ 계측적 λΆ„λ₯˜ 및 관리가 κ°€λŠ₯ν•˜μ—¬ μœ μ§€λ³΄μˆ˜κ°€ μš©μ΄ν•˜λ‹€.

상속 μ„ μ–Έ

  • λΆ€λͺ¨ 클래슀λ₯Ό 슈퍼 클래슀(super class), 상속 λ°›λŠ” μžμ‹ 클래슀λ₯Ό μ„œλΈŒ 클래슀(sub class)라고 ν•œλ‹€.
  • 상속을 μ„ μ–Έν•  λ•ŒλŠ” extends ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•œλ‹€.
public class Phone {
	
    public void call() {
    	System.out.println("μ „ν™”λ₯Ό κ²λ‹ˆλ‹€...");
	}
    
    public void send() {
    	System.out.println("μ „ν™”λ₯Ό λ°›μŠ΅λ‹ˆλ‹€...");
	}
}
public class SmartPhone extends Phone { 
//상속 μ„ μ–Έ (μŠ€λ§ˆνŠΈν°μ€ μ „ν™”κΈ°λ₯Ό μƒμ†λ°›λŠ”λ‹€.)

	public void wifi()	{
    	System.out.println("μ™€μ΄νŒŒμ΄λ₯Ό μ—°κ²°ν•©λ‹ˆλ‹€...");
	}
}
  • 슀마트폰 ν΄λž˜μŠ€λŠ” μ „ν™”κΈ° 클래슀의 call(), send() κΈ°λŠ₯을 λ¬Όλ €λ°›μœΌλ―€λ‘œ 슀마트폰 ν΄λž˜μŠ€μ—μ„œ λ©”μ„œλ“œλ₯Ό λ‹€μ‹œ λ°˜λ³΅ν•˜μ—¬ μž‘μ„±ν•  ν•„μš”κ°€ μ—†λ‹€.
  • 슀마트폰의 μΆ”κ°€ κΈ°λŠ₯인 wifi() λ©”μ„œλ“œλ§Œ μž‘μ„±ν•˜λ©΄ λœλ‹€.

μ„œλΈŒ 클래슀 객체

public class Ex01 {
	public static void main(String[]args) {
    	Phone p1 = new Phone(); // μ „ν™”κΈ° 객체 생성
        
        p1.call();
        p1.send();
        
        SmartPhone p2 = new SmartPhone(); // 슀마트폰 객체 생성
        
        p2.call(); 	 // 슀마트폰 ν΄λž˜μŠ€μ—μ„œ μ „ν™”κΈ° 클래슀의 λ©”μ„œλ“œμ— μ ‘κ·Ό
        p2.send();
        p2.wifi();   // κΈ°λŠ₯ ν™•μž₯
	}
}
  • μƒμ„±λœ κ°μ²΄λŠ” p1, p2이닀.
  • p1 κ°μ²΄λŠ” Phone 클래슀의 κΈ°λŠ₯만 가지고 p2λŠ” Phone ν΄λž˜μŠ€μ™€ SmartPhone 클래슀의 κΈ°λŠ₯ λͺ¨λ‘ κ°€μ§ˆ 수 μžˆλ‹€.

μƒμ†μ˜ νŠΉμ§•

  • μžλ°”μ—μ„œλŠ” 닀쀑 상속을 μ§€μ›ν•˜μ§€ μ•ŠλŠ”λ‹€.
    • extends ν‚€μ›Œλ“œ λ’€μ—λŠ” ν•˜λ‚˜μ˜ 클래슀만 올 수 μžˆλ‹€.
  • μžλ°”μ—μ„œλŠ” μƒμ†μ˜ 횟수λ₯Ό μ œν•œν•˜μ§€ μ•ŠλŠ”λ‹€.
  • μžλ°”μ—μ„œ κ³„μΈ΅κ΅¬μ‘°μ˜ μ΅œμƒμœ„μ— java.lang.Object ν΄λž˜μŠ€κ°€ μžˆλ‹€.
    μžλ°”μ—μ„œ λͺ¨λ“  ν΄λž˜μŠ€λŠ” Object 클래슀λ₯Ό μžλ™μœΌλ‘œ 상속 받도둝 λ˜μ–΄μžˆλ‹€.
    toString(), equals()와 같은 λ©”μ„œλ“œλ₯Ό λ°”λ‘œ μ‚¬μš©ν•  수 μžˆλ‹€.
    https://programmingnote.tistory.com/32

super ν‚€μ›Œλ“œ

super ν‚€μ›Œλ“œλŠ” λΆ€λͺ¨ ν΄λž˜μŠ€λ‘œλΆ€ν„° 상속받은 ν•„λ“œλ‚˜ λ©”μ„œλ“œλ₯Ό μžμ‹ ν΄λž˜μŠ€μ—μ„œ μ°Έμ‘°ν•˜λŠ”λ° μ‚¬μš©ν•˜λŠ” μ°Έμ‘° λ³€μˆ˜μ΄λ‹€. μΈμŠ€ν„΄μŠ€ λ³€μˆ˜μ˜ 이름과 지역 λ³€μˆ˜μ˜ 이름이 같을 경우 μΈμŠ€ν„΄μŠ€ λ³€μˆ˜ μ•žμ— this ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ κ΅¬λΆ„ν•˜λŠ” κ²ƒμ²˜λŸΌ, λΆ€λͺ¨ 클래슀의 멀버와 μžμ‹ 클래슀의 멀버가 동일할 경우 super ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ ꡬ별할 수 있고, superλ₯Ό μ‚¬μš©ν•˜μ—¬ λΆ€λͺ¨ 클래슀의 멀버에 μ ‘κ·Ό ν•  수 μžˆλ‹€. this와 λ§ˆμ°¬κ°€μ§€λ‘œ super μ°Έμ‘° λ³€μˆ˜λ₯Ό μ‚¬μš©ν•  수 μžˆλŠ” λŒ€μƒλ„ μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œ 뿐이며, 클래슀 λ©”μ„œλ“œ(static)μ—μ„œλŠ” μ‚¬μš©ν•  수 μ—†λ‹€.

class Parent {
	int x = 10;
}

class Child extends Parent {
	int x = 20;
    
    void method() {
    	System.out.println("x = " + x);
        System.out.println("this.x = " + this.x);
        System.out.println("super.x = " + super.x);
	}
}

public class SuperTest {
	public static void main(String[]args) {
    	Child c = new Child();
        c.method();
	}
}

Output
x = 20
this. x = 20
super.x = 10

this ν‚€μ›Œλ“œλŠ” ν˜„μž¬ 자기 μžμ‹ μ˜ 멀버인 x = 20을 λ°˜ν™˜ν–ˆκ³  super ν‚€μ›Œλ“œλŠ” λΆ€λͺ¨ ν΄λž˜μŠ€μ—μ„œ 상속 받은 x = 10을 λ°˜ν™˜ν–ˆλ‹€.

super() λ©”μ„œλ“œ

super()λŠ” μžμ‹ 클래슀의 μƒμ„±μžμ—μ„œ λΆ€λͺ¨ 클래슀의 μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•œλ‹€. μžμ‹ ν΄λž˜μŠ€κ°€ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λ©΄ μΈμŠ€ν„΄μŠ€ μ•ˆμ—λŠ” μžμ‹ 클래슀의 고유 멀버 뿐만 μ•„λ‹ˆλΌ λΆ€λͺ¨ 클래슀의 λͺ¨λ“  λ©€λ²„κΉŒμ§€ ν¬ν•¨λ˜μ–΄ μžˆλ‹€. ν•˜μ§€λ§Œ μƒμ†μ—μ„œμ˜ μƒμ„±μžλŠ” μƒμ†λ˜μ§€ μ•ŠλŠ” μœ μΌν•œ 멀버 ν•¨μˆ˜μ΄λ‹€. λ”°λΌμ„œ λΆ€λͺ¨ 클래슀의 멀버λ₯Ό μ΄ˆκΈ°ν™” ν•˜κΈ° μœ„ν•΄μ„ , λ‹Ήμ—°νžˆ λΆ€λͺ¨ 클래슀의 μƒμ„±μžλ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•  것이닀. 즉, μžμ‹ 클래슀의 λͺ¨λ“  μƒμ„±μžλŠ” λΆ€λͺ¨ 클래슀의 μƒμ„±μžλ₯Ό ν¬ν•¨ν•˜κ³  μžˆμ–΄μ•Ό ν•œλ‹€. 그런데 λ§Œμ•½ μžμ‹ 클래슀의 μƒμ„±μžμ— λΆ€λͺ¨ 클래슀의 μƒμ„±μžκ°€ μ •μ˜λ˜μ–΄ μžˆμ§€ μ•Šλ‹€λ©΄, μ»΄νŒŒμΌλŸ¬κ°€ μžλ™μœΌλ‘œ λΆ€λͺ¨ 클래슀의 κΈ°λ³Έ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•΄μ€€λ‹€. (μ΄λŸ¬ν•œ 경우, λΆ€λͺ¨ ν΄λž˜μŠ€μ— λ§€κ°œλ³€μˆ˜κ°€ μžˆλŠ” μƒμ„±μžλ§Œ 있고 κΈ°λ³Έ μƒμ„±μžκ°€ μ—†μ–΄ κΈ°λ³Έ μƒμ„±μžλ₯Ό 호좜 ν•  수 μ—†λ‹€λ©΄ ? ➑️ μ—λŸ¬ λ°œμƒ)[https://kadosholy.tistory.com/93

public class Book { // λΆ€λͺ¨ 클래슀
	
    String title = "λ―Έμž…λ ₯";
    int price = -1;
    int code = 100;
    
    public Book() {} // κΈ°λ³Έ μƒμ„±μž
    
    public Book (String title, int price) { //λ§€κ°œλ³€μˆ˜κ°€ 2개인 μƒμ„±μž
    	this.title = title;
        this.price = price;
	}
    
    public void showPrice() {
    	System.out.println(title + " 의 가격은 " + price + "원 μž…λ‹ˆλ‹€.");
	}
}
public class EnglishBook extends Book { // μžμ‹ 클래슀

	int code = 200;
    
    public EnglishBook() {} // κΈ°λ³Έ μƒμ„±μž
    
    public EnglishBook(String title, int price) { //λ§€κ°œλ³€μˆ˜κ°€ 2개인 μƒμ„±μž
    	super(title, price);
	}
    
    public void showPrice() {
    	super.showPrice();
        
		System.out.println("code : " + code);
		System.out.println("this.code : " + this.code);
		System.out.println("super.code : " + super.code); // λΆ€λͺ¨ 클래슀의 code

		System.out.println("price : " + price);
		System.out.println("this.price : " + this.price);
		System.out.println("super.price : " + super.price); // λΆ€λͺ¨ 클래슀의 price
public class HelloWorld { // 객체 생성 및 μ‹€ν–‰
	public static void main(String[]args) {
    	EnglishBook b1 = new EnglishBook("μ˜μ–΄μ±…", 10000);
        b1.showPrice();
	}
}

Output
code : 200
this.code : 200
super.code : 100
price : 10000
this.price : 10000
super.price : 10000

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

μ˜€λ²„λΌμ΄λ”©(overriding)μ΄λž€ λΆ€λͺ¨ ν΄λž˜μŠ€λ‘œλΆ€ν„° 상속받은 λ©”μ„œλ“œλ₯Ό μžμ‹ ν΄λž˜μŠ€μ—μ„œ μž¬μ •μ˜ ν•˜λŠ” 것이닀. 상속받은 λ©”μ„œλ“œλ₯Ό κ·ΈλŒ€λ‘œ μ‚¬μš©ν•  μˆ˜λ„ μžˆμ§€λ§Œ, μžμ‹ ν΄λž˜μŠ€μ—μ„œ 상황에 맞게 λ³€κ²½ν•΄μ•Ό ν•˜λŠ” 경우 μ˜€λ²„λΌμ΄λ”© ν•  ν•„μš”κ°€ 생긴닀.

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

μ˜€λ²„λΌμ΄λ”©μ€ λΆ€λͺ¨ 클래슀의 λ©”μ„œλ“œλ₯Ό μž¬μ •μ˜ ν•˜λŠ”κ²ƒμ΄λ―€λ‘œ, μžμ‹ ν΄λž˜μŠ€μ—μ„œλŠ” μ˜€λ²„λΌμ΄λ”© ν•˜κ³ μž ν•˜λŠ” λ©”μ„œλ“œμ˜ 이름, λ§€κ°œλ³€μˆ˜, 리턴 값이 λͺ¨λ‘ κ°™μ•„μ•Όν•œλ‹€.

public class OverridingTest {
	public static void main(String[]args) {
    	Animal animal = new Animal();
        Dog dog = new Dog();
        Cat cat = new Cat();
        
        animal.cry();
        dog.cry();
        cat.cry();
	}
}

class Animal {
	void cry() {
    	System.out.println("λ™λ¬Όμ˜ μšΈμŒμ†Œλ¦¬");
	}
}

class Dog extends Animal {
	@Override
    public void cry() {
    	System.out.println("멍멍");
	}
}

class Cat extends Animal {
	@Override
    public void cry() {
    	System.out.println("μ•Όμ˜Ή");
	}
}

Output
λ™λ¬Όμ˜ μšΈμŒμ†Œλ¦¬
멍멍
μ•Όμ˜Ή

μ˜€λ²„λ‘œλ”©κ³Ό μ˜€λ²„λΌμ΄λ”© 차이

μ˜€λ²„λ‘œλ”©κ³Ό μ˜€λ²„λΌμ΄λ”©μ€ 이름이 λΉ„μŠ·ν•  뿐 μ „ν˜€ λ‹€λ₯Έ 역할을 ν•œλ‹€.

  • μ˜€λ²„λ‘œλ”© : 기쑴에 μ—†λŠ” μƒˆλ‘œμš΄ λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•˜λŠ” 것.
  • μ˜€λ²„λΌμ΄λ”© : 상속받은 λ©”μ„œλ“œλ₯Ό μž¬μ •μ˜ ν•˜λŠ” 것.
ꡬ뢄OverridingOverloading
μ ‘κ·Όμ œμ–΄μžλΆ€λͺ¨ 클래슀의 λ©”μ„œλ“œμ˜ μ ‘κ·Ό μ œμ–΄μžλ³΄λ‹€ 더 넓은 λ²”μœ„μ˜ μ ‘κ·Ό μ œμ–΄μžλ₯Ό μžμ‹ 클래슀의 λ©”μ„œλ“œμ—μ„œ μ„€μ •ν•  수 μžˆλ‹€.λͺ¨λ“  μ ‘κ·Όμ œμ–΄μžλ₯Ό μ‚¬μš© ν•  수 μžˆλ‹€.
λ¦¬ν„΄ν˜•λ™μΌν•΄μ•Ό ν•œλ‹€λ‹¬λΌλ„ λœλ‹€
λ©”μ„œλ“œλͺ…동일해야 ν•œλ‹€λ™μΌν•΄μ•Ό ν•œλ‹€
λ§€κ°œλ³€μˆ˜λ™μΌν•΄μ•Ό ν•œλ‹€λ‹¬λΌμ•Όλ§Œ ν•œλ‹€
μ μš©λ²”μœ„μƒμ†κ΄€κ³„μ—μ„œ μ μš©λœλ‹€κ°™μ€ 클래슀 λ‚΄μ—μ„œ μ μš©λœλ‹€

λ‹€μ΄λ‚˜λ―Ή λ©”μ„œλ“œ λ””μŠ€νŒ¨μΉ˜ (Dynamic Method Dispatch)

λ‹€μ΄λ‚˜λ―Ή λ©”μ„œλ“œ λ””μŠ€νŒ¨μΉ˜λŠ” μ˜€λ²„λΌμ΄λ“œ 된 λ©”μ„œλ“œμ— λŒ€ν•œ 호좜이 컴파일 νƒ€μž„μ΄ μ•„λ‹Œ, λŸ°νƒ€μž„μ— κ²°μ •λ˜λŠ” λ§€μ»€λ‹ˆμ¦˜ 이닀. μ˜€λ²„λΌμ΄λ“œ 된 λ©”μ„œλ“œκ°€ λΆ€λͺ¨ 클래슀 μ°Έμ‘° 객체에 μ˜ν•΄ 호좜 될 λ•Œ, μžλ°”λŠ” μ°Έμ‘° λ³€μˆ˜μ˜ μœ ν˜•μ΄ μ•„λ‹Œ 호좜 μ‹œ μ°Έμ‘°λ˜λŠ” 객체에 따라 μ‹€ν–‰λ˜λŠ” λ©”μ„œλ“œμ˜ 버전(슈퍼 / μ„œλΈŒ 클래슀)을 κ²°μ •ν•œλ‹€. λ”°λΌμ„œ, 이 결정은 λŸ°νƒ€μž„μ— 이루어진닀. 슈퍼 클래슀 μ°Έμ‘° λ³€μˆ˜λŠ” μ„œλΈŒ 클래슀 객체λ₯Ό μ°Έμ‘°ν•  수 있으며 이λ₯Ό μ—…μΊμŠ€νŒ… 이라고 ν•œλ‹€. 슈퍼 ν΄λž˜μŠ€κ°€ μ„œλΈŒ ν΄λž˜μŠ€μ— μ˜ν•΄ μž¬μ •μ˜λ˜λŠ” λ©”μ„œλ“œλ₯Ό ν¬ν•¨ν•˜λŠ” 경우, 슈퍼 클래슀 μ°Έμ‘° λ³€μˆ˜λ₯Ό 톡해 μ„œλ‘œ λ‹€λ₯Έ μœ ν˜•μ˜ 개체λ₯Ό μ°Έμ‘°ν•  λ•Œ μ„œλ‘œ λ‹€λ₯Έ λ²„μ „μ˜ λ©”μ„œλ“œκ°€ μ‹€ν–‰λœλ‹€.
https://velog.io/@maigumi/Dynamic-Method-Dispatch

μ½”λ“œλ₯Ό 보면 overriding을 톡해 λ©”μ„œλ“œλ₯Ό μž¬μ •μ˜ 해두고, 메인 ν•¨μˆ˜μ—μ„œ λ™μΌν•œ μ΄λ¦„μ˜ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜κ³  μžˆλ‹€. κ²°κ³ΌλŠ”?

static class Super {
	void print() {
    	System.out.println("super's print");
	}
}

static class Sub1 extends Super {
	@Override
    void print() {
    	System.out.println("sub1's print");
	}
}

static class Sub2 extends Super {
	@Override
    void print() {
    	System.out.println("sub2's print");
	}
}

public static void main(String[]args) {
	Super reference = new Super(); // 1)
    reference.print();
    reference = new Sub1(); // 2)
    reference.print();
    reference = new Sub2(); // 3)
    reference.print();
}

Super νƒ€μž…μ˜ 객체인 reference에 μžμ‹ 객체인 Sub1κ³Ό Sub2λ₯Ό λŒ€μž…ν•˜λ©΄ upcasting이 이루어지고, referenceλŠ” λŒ€μž…λ  λ•Œ λ§ˆλ‹€ μžμ‹ 객체의 μ£Όμ†Œλ₯Ό κ°€λ₯΄ν‚€κ²Œ λœλ‹€. ν˜Όλž€μ΄ μžˆμ„κΉŒ μ–ΈκΈ‰ν•˜μžλ©΄, referenceκ°€ 3개의 객체λ₯Ό λͺ¨λ‘ κ°€λ₯΄ν‚€λŠ” 것이 μ•„λ‹ˆλΌ λŒ€μž…λ  λ•Œ λ§ˆλ‹€ μˆœμ„œλŒ€λ‘œ κ°€λ₯΄ν‚€κ²Œ λœλ‹€.
https://velog.io/@maigumi/Dynamic-Method-Dispatch

Output
super's print
sub1's print
sub2's print

좜λ ₯μ—μ„œ μ•Œ 수 μžˆλ“―μ΄, μ‹€ν–‰λ˜λŠ” λ©”μ„œλ“œμ˜ 버전은 호좜 μ‹œ μ°Έμ‘°λ˜λŠ” 객체의 μœ ν˜•μ— 따라 κ²°μ •λœλ‹€. 이처럼 Super νƒ€μž…μ˜ reference μ°Έμ‘° λ³€μˆ˜κ°€ 컴파일 μ‹œ νƒ€μž…(Super)이 μ•„λ‹Œ, λŸ°νƒ€μž„ μ‹œ μ°Έμ‘°λ˜λŠ” 객체의 νƒ€μž…μ— 따라 μ˜€λ²„λΌμ΄λ“œ 된 λ©”μ„œλ“œμ˜ 버전을 κ²°μ •ν•˜λŠ” 것이 λ‹€μ΄λ‚˜λ―Ή λ©”μ„œλ“œ λ””μŠ€νŒ¨μΉ˜ 라고 λΆ€λ₯Έλ‹€. 단 μ£Όμ˜ν•  점이 μžˆλ‹€! μžλ°”μ—μ„œ λ³€μˆ˜κ°€ μ•„λ‹Œ λ©”μ„œλ“œλ§Œ μ˜€λ²„λΌμ΄λ“œκ°€ κ°€λŠ₯ν•œ κ²ƒμ²˜λŸΌ, λŸ°νƒ€μž„ λ‹€ν˜•μ„±μ€ 데이터 멀버 λ³€μˆ˜μ—μ„œλŠ” 보μž₯λ˜μ§€ μ•ŠλŠ”λ‹€.

class A {
	int x = 10;
}

class B extends A {
	int x = 20;
}

public class Test {
	public static void main(String[]args) {
    	A a = new B();
        System.out.println(a.x);
	}
}

Output
10

A νƒ€μž…μ˜ μ°Έμ‘°λ³€μˆ˜ a에, B 객체λ₯Ό ν• λ‹Ήν•œ ν›„ a λ³€μˆ˜μ˜ x 값을 좜λ ₯ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ΄λ‹€. B 객체λ₯Ό ν• λ‹Ή ν•˜μ˜€κΈ° λ•Œλ¬Έμ— 20이 좜λ ₯될 κ²ƒμœΌλ‘œ μ˜ˆμƒν–ˆμ§€λ§Œ, 10이 좜λ ₯λ˜μ—ˆλ‹€ μ™œμΌκΉŒ ? μ΄λŠ” μ•žμ„œ λ§ν•œ λŸ°νƒ€μž„ λ‹€ν˜•μ„±μ€ 데이터 멀버 λ³€μˆ˜μ—λŠ” 보μž₯λ˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ΄λ‹€. λ”°λΌμ„œ a.xλŠ” 항상 슈퍼 클래슀의 데이터 λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜κ²Œ λœλ‹€.

좔상 클래슀

좔상 ν΄λž˜μŠ€λž€ λ¬΄μ—‡μΌκΉŒ ? μ‰½κ²Œ μ„€λͺ…ν•˜μžλ©΄ μ—¬λŸ¬ ν΄λž˜μŠ€λ“€μ—μ„œ κ³΅ν†΅μ μœΌλ‘œ μ‚¬μš©λ˜λŠ” λ©”μ„œλ“œμ˜ λͺ¨μŒμ§‘이라고 생각 ν•  수 μžˆκ² λ‹€. 예λ₯Ό λ“€μ–΄λ³΄μž μ‚¬λžŒ 얼꡴은 λͺ¨λ‘ λ‹€λ₯΄μ§€λ§Œ 눈 λ‘κ°œ, μ½” ν•˜λ‚˜, μž… ν•˜λ‚˜λ₯Ό κ³΅ν†΅μ μœΌλ‘œ 가지고 μžˆλ‹€. μ—¬κΈ°μ„œ AλΌλŠ” μ‚¬λžŒμ€ 눈, μ½”, μž…μ„ κ°€μ§€κ³ μžˆκ³ , λ§ˆμ°¬κ°€μ§€λ‘œ BλΌλŠ” μ‚¬λžŒλ„ 눈, μ½”, μž…μ„ 가지고 μžˆμ„ 것이닀. 이제 A와 BλΌλŠ” μ‚¬λžŒμ„ 클래슀둜 보고 눈, μ½”, μž…μ„ λ³€μˆ˜λ‘œ 보자. A와 BλŠ” λ‘˜λ‹€ μ›ƒλŠ” 행동을 ν•  수 μžˆλ‹€. AλΌλŠ” μ‚¬λžŒμ€ ν•˜ν•˜ μ›ƒμ§€λ§Œ, BλΌλŠ” μ‚¬λžŒμ€ ν—€ν—€ ν•˜κ³  μ›ƒλŠ”λ‹€ λ‘˜μ€ 각자의 μ›ƒμŒ μ†Œλ¦¬λŒ€λ‘œ μ›ƒμ§€λ§Œ, κ³΅ν†΅μ μœΌλ‘œ μ›ƒλŠ”λ‹€ λΌλŠ” μ•‘μ…˜μ„ μ·¨ν•˜κ³ μžˆλ‹€. μ΄λŠ” 곡톡적인 λ©”μ„œλ“œκ°€ λœλ‹€. λ”°λΌμ„œ 좔상 ν΄λž˜μŠ€μ— ν•΄λ‹Ή λ©”μ„œλ“œλ₯Ό 넣을 수 μžˆλ‹€. 정리λ₯Ό 해보면 좔상 ν΄λž˜μŠ€λŠ” 싀체 클래슀의 곡톡적인 뢀뢄을 μΆ”μΆœν•΄ μ–΄λŠμ •λ„ 규격만 μž‘μ•„λ†“λŠ” 좔상적인 ν΄λž˜μŠ€μ΄λ‹€. 좔상 ν΄λž˜μŠ€λŠ” λ©”μ„œλ“œμ™€ λ‚΄μš©μ΄ 좔상적이기 λ•Œλ¬Έμ— 객체λ₯Ό 생성할 수 μ—†λ‹€ 그럼 μ–΄λ–»κ²Œ μ‚¬μš©ν• κΉŒ ? 싀체 ν΄λž˜μŠ€μ—μ„œ 좔상 클래슀λ₯Ό 상속받아 μΆ”μƒμ μ΄μ—ˆλ˜ 클래슀λ₯Ό ꡬ체화 μ‹œν‚€λ©°(μ›ƒμŒ μ†Œλ¦¬ = ν•˜ν•˜, ν—€ν—€..) μ‚¬μš©ν•œλ‹€! μ„œλ‘ μ΄ κΈΈμ—ˆλ‹€,, μ˜ˆμ‹œλ₯Ό μ½”λ“œλ‘œ 보자!

abstract class Person { //좔상 클래슀
	abstract void smile();  //좔상 λ©”μ„œλ“œ -> λ‚΄μš©μ„ μ •μ˜ ν•˜μ§€ μ•ŠλŠ”λ‹€.
}
public class A extends Person { // 좔상 클래슀λ₯Ό 상속받아 싀체 클래슀λ₯Ό λ§Œλ“¦
	
    @Override
    public void smile() {
    	System.out.println("ν•˜ν•˜"); // 좔상 λ©”μ„œλ“œλ₯Ό ꡬ체화 μ‹œν‚¨λ‹€. -> λ‹€ν˜•μ„±
	}
}

public class B extends Person { // 좔상 클래슀λ₯Ό 상속받아 싀체 클래슀λ₯Ό λ§Œλ“¦
	
    @Override
    public void smile() {
    	System.out.println("ν—€ν—€"); // 좔상 λ©”μ„œλ“œλ₯Ό ꡬ체화 μ‹œν‚¨λ‹€. -> λ‹€ν˜•μ„±
	}
}
public class Main {
	public static void main(String[]args) {
    	
        A personA = new A();
        personA.smile();
        
        B personB = new B();
        personB.smile();
	}
}

Output
ν•˜ν•˜
ν—€ν—€

이해가 쑰금 λ˜μ—ˆκΈΈ 바라며 좔상 ν΄λž˜μŠ€μ— λŒ€ν•΄ λ‹€μ‹œ ν•œλ²ˆ 정리λ₯Ό ν•΄λ³΄μž.
μžλ°”μ—μ„œλŠ” ν•˜λ‚˜ μ΄μƒμ˜ 좔상 λ©”μ„œλ“œλ₯Ό ν¬ν•¨ν•˜λŠ” 클래슀λ₯Ό 좔상 클래슀라고 ν•œλ‹€. μ΄λŸ¬ν•œ 좔상 ν΄λž˜μŠ€λŠ” 객체 지ν–₯ ν”„λ‘œκ·Έλž˜λ°μ—μ„œ μ€‘μš”ν•œ νŠΉμ§•μΈ λ‹€ν˜•μ„±μ„ κ°€μ§€λŠ” λ©”μ„œλ“œμ˜ 집합을 μ •μ˜ν•  수 μžˆλ„λ‘ ν•΄μ€€λ‹€. 즉, λ°˜λ“œμ‹œ μ‚¬μš©λ˜μ–΄μ•Ό ν•˜λŠ” λ©”μ„œλ“œλ₯Ό 좔상 ν΄λž˜μŠ€μ— 좔상 λ©”μ„œλ“œλ‘œ μ„ μ–Έν•΄ λ†“μœΌλ©΄, 좔상 클래슀λ₯Ό μƒμ†λ°›λŠ” λͺ¨λ“  ν΄λž˜μŠ€μ—μ„œλŠ” 좔상 λ©”μ„œλ“œλ₯Ό λ°˜λ“œμ‹œ μž¬μ •μ˜ ν•΄μ•Όν•œλ‹€. 좔상 ν΄λž˜μŠ€λŠ” λ™μž‘μ΄ μ •μ˜λ˜μ–΄ μžˆμ§€ μ•Šμ€ 좔상 λ©”μ„œλ“œλ₯Ό 포함 ν•˜κ³  μžˆμœΌλ―€λ‘œ, μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 수 μ—†λ‹€. 좔상 ν΄λž˜μŠ€λŠ” λ¨Όμ € 상속을 톡해 μžμ‹ 클래슀λ₯Ό λ§Œλ“€κ³ , λ§Œλ“  μžμ‹ ν΄λž˜μŠ€μ—μ„œ 좔상 클래슀의 λͺ¨λ“  좔상 λ©”μ„œλ“œλ₯Ό μ˜€λ²„λΌμ΄λ”©ν•˜κ³  λ‚˜μ„œμ•Ό λΉ„λ‘œμ†Œ μžμ‹ 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 수 μžˆλ‹€.

final ν‚€μ›Œλ“œ

final ν‚€μ›Œλ“œλŠ” λ³€μˆ˜(variable), λ©”μ„œλ“œ(Method), λ˜λŠ” 클래슀(class)에 μ‚¬μš©λ  수 μžˆλ‹€. 이 final ν‚€μ›Œλ“œλŠ” μ–΄λ–€ 곳에 μ‚¬μš©λ˜λŠλƒμ— 따라 λ‹€λ₯Έ 의미λ₯Ό 가진닀. ν•˜μ§€λ§Œ final ν‚€μ›Œλ“œλ₯Ό 뢙이면 무언가 μ œν•œν•œλ‹€λŠ” 의미λ₯Ό κ°€μ§€λŠ” 것은 곡톡적인 성격이닀.

1. final λ³€μˆ˜

1.1 μ›μ‹œνƒ€μž…

둜컬 μ›μ‹œ λ³€μˆ˜μ— final둜 μ„ μ–Έν•˜λ©΄ ν•œλ²ˆ μ΄ˆκΈ°ν™”λœ λ³€μˆ˜λŠ” λ³€κ²½ν•  수 μ—†λŠ” μƒμˆ˜κ°’μ΄ λœλ‹€.

public void primitiveVariables() {
	final int x = 1;
    x = 3; // ν•œλ²ˆ assign되면 λ³€κ²½ν•  수 μ—†λ‹€.
}

1.2 κ°μ²΄νƒ€μž…

객체 λ³€μˆ˜μ— final둜 μ„ μ–Έν•˜λ©΄ κ·Έ λ³€μˆ˜μ— λ‹€λ₯Έ μ°Έμ‘° 값을 지정할 수 μ—†λ‹€. μ›μ‹œ νƒ€μž…κ³Ό λ™μΌν•˜κ²Œ ν•œλ²ˆ 쓰여진 λ³€μˆ˜λŠ” μž¬λ³€κ²½μ΄ λΆˆκ°€ν•˜λ‹€. 단 객체 μžμ²΄κ°€ immutableν•˜λ‹€λŠ” μ˜λ―ΈλŠ” μ•„λ‹ˆλ‹€. 객체의 속성은 λ³€κ²½ κ°€λŠ₯ν•˜λ‹€.

public void referenceVariables() {
	final Pet pet = new Pet();
    pet = new Pet(); // λ‹€λ₯Έ 객체둜 λ³€κ²½ν•  수 μ—†μŒ.
    per.setWeight(3); // 객체 ν•„λ“œλŠ” λ³€κ²½ κ°€λŠ₯.
}

1.3 λ©”μ„œλ“œ 인자

λ©”μ„œλ“œ μΈμžμ— final ν‚€μ›Œλ“œλ₯Ό 뢙이면, λ©”μ„œλ“œ μ•ˆμ—μ„œ λ³€μˆ˜ 값을 λ³€κ²½ ν•  수 μ—†λ‹€.

public class Pet {
	int weight;
    public void setWeight(final int weight) {
    	weight = 1; //final μΈμžλŠ” λ©”μ„œλ“œ μ•ˆμ—μ„œ λ³€κ²½ν•  수 μ—†λ‹€.
	}
}

1.4 ν•„λ“œ

클래슀의 ν•„λ“œμ— final둜 μ„ μ–Έν•˜λ©΄ μƒμˆ˜κ°’μ΄ λ˜κ±°λ‚˜ write-once ν•„λ“œλ‘œ ν•œλ²ˆλ§Œ μ“°μ΄κ²Œ λœλ‹€. final둜 μ„ μ–Έν•˜λ©΄ μ΄ˆκΈ°ν™” λ˜λŠ” μ‹œμ μ€ μƒμ„±μž λ©”μ„œλ“œκ°€ λλ‚˜κΈ° 전에 μ΄ˆκΈ°ν™” λœλ‹€. ν•˜μ§€λ§Œ static이냐 μ•„λ‹ˆλƒμ— λ”°λΌμ„œλ„ μ΄ˆκΈ°ν™” μ‹œμ μ΄ 달라진닀.

  • static final ν•„λ“œ (static final int x = 1)
    • κ°’κ³Ό ν•¨κ»˜ μ„ μ–Έ μ‹œ
    • 정적 μ΄ˆκΈ°ν™” λΈ”λŸ­μ—μ„œ (static initialization block)
  • instance final ν•„λ“œ (final int x = 1)
    • κ°’κ³Ό ν•¨κ»˜ μ„ μ–Έ μ‹œ
    • μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™” λΈ”λŸ­μ—μ„œ (instance initialization block)
    • μƒμ„±μž λ©”μ„œλ“œμ—μ„œ

1.4.1 μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™” λΈ”λŸ­ vs 정적 μ΄ˆκΈ°ν™” λΈ”λŸ­

μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™” λΈ”λŸ­μ •μ  μ΄ˆκΈ°ν™” λΈ”λŸ­
객체 생성할 λ•Œλ§ˆλ‹€ λΈ”λŸ­μ΄ μ‹€ν–‰λœλ‹€
λΆ€λͺ¨ μƒμ„±μž 이후에 μ‹€ν–‰λœλ‹€ν΄λž˜μŠ€ λ‘œλ“œμ‹œ ν•œλ²ˆλ§Œ λΈ”λŸ­μ΄ μƒμ„±λœλ‹€
μƒμ„±μžλ³΄λ‹€ λ¨Όμ € μ‹€ν–‰λœλ‹€

2. final λ©”μ„œλ“œ

λ©”μ„œλ“œλ₯Ό final둜 μ„ μ–Έν•˜λ©΄ 상속받은 ν΄λž˜μŠ€μ—μ„œ μ˜€λ²„λΌμ΄λ“œκ°€ λΆˆκ°€λŠ₯ ν•˜κ²Œ λœλ‹€. 예λ₯Όλ“€μ–΄, DogλΌλŠ” κ°μ²΄λŠ” Pet 클래슀 μ•ˆμ˜ final둜 μ„ μ–Έλœ makeSound() λ©”μ„œλ“œλ₯Ό μž¬μ •μ˜ ν•  수 μ—†λ‹€. κ·Έλ ‡λ‹€λ©΄ final λ©”μ„œλ“œλŠ” μ–Έμ œ μ‚¬μš©ν•˜λ©΄ μ’‹μ„κΉŒ ? κ΅¬ν˜„ν•œ μ½”λ“œμ˜ 변경을 μ›μΉ˜ μ•Šμ„ λ•Œ μ‚¬μš©ν•œλ‹€. side-effectκ°€ 있으면 μ•ˆλ˜λŠ” μžλ°” μ½”μ–΄ λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ final둜 μ„ μ–Έλœ 뢀뢄을 많이 찾을 수 μžˆλ‹€.

public class Pet {
	public final void makeSound() {  //final μ‚¬μš©
    	System.out.println("ahaha");
	}
}

public class Dog extends Pet {
	//final둜 μ„ μ–Έλœ λ©”μ„œλ“œλŠ” Override ν•  수 μ—†λ‹€.
    public void makeSound() { }
}

3. final 클래슀

ν΄λž˜μŠ€μ— final을 μ„ μ–Έν•˜λ©΄ 상속 μžμ²΄κ°€ μ•ˆλœλ‹€. κ·Έλƒ₯ 클래슀 κ·ΈλŒ€λ‘œλ§Œ μ‚¬μš©ν•΄μ•Ό ν•œλ‹€. Util ν˜•μ‹μ˜ ν΄λž˜μŠ€λ‚˜ μ—¬λŸ¬ μƒμˆ˜ 값을 λͺ¨μ•„λ‘” Constants 클래슀λ₯Ό final둜 μ„ μ–Έν•œλ‹€.

public final class Constants {
	public static final SIZE = 0;
}

public class SubConstants extends Constants {
	// μƒμˆ˜ 값을 λͺ¨μ•„놓은 클래슀λ₯Ό ꡳ이 μƒμ†ν•΄μ„œ μ“Έ μ΄μœ λŠ” μ—†λ‹€
}

Object 클래슀

μžλ°”μ—μ„œλŠ” μƒμ†μ΄λž€ ν•„μˆ˜μ μ΄λ‹€. μš°λ¦¬κ°€ 상속을 ν•˜κ±΄ ν•˜μ§€ μ•Šμ•˜κ±΄ 기본적으둜 상속을 ν•˜κ²Œλœλ‹€. 무슨말일까 ?

class Obj { }
// μœ„ μ½”λ“œλŠ” μ•„λž˜ μ½”λ“œμ™€ λ™μΌν•˜λ‹€.
class Obj extends Object { }

https://kephilab.tistory.com/92

μžλ°”μ—μ„œ λͺ¨λ“  ν΄λž˜μŠ€λŠ” 사싀 Objectλ₯Ό μ•”μ‹œμ μœΌλ‘œ 상속받고 μžˆλŠ” 것이닀. 그런 μ μ—μ„œ ObjectλŠ” λͺ¨λ“  클래슀의 쑰상이라고 ν•  수 μžˆλ‹€. κ·Έ μ΄μœ λŠ” λͺ¨λ“  ν΄λž˜μŠ€κ°€ κ³΅ν†΅μœΌλ‘œ ν¬ν•¨ν•˜κ³  μžˆμ–΄μ•Ό ν•˜λŠ” κΈ°λŠ₯을 μ œκ³΅ν•˜κΈ° μœ„ν•΄μ„œλ‹€ API λ¬Έμ„œμ— λ©”μ„œλ“œμ˜ λͺ©λ‘μ„ μ‚΄νŽ΄λ³΄μž.
https://opentutorials.org/module/516/6241
μœ„ 그림은 Object ν΄λž˜μŠ€κ°€ 가지고 μžˆλŠ” λ©”μ„œλ“œλ₯Ό 보여쀀닀. λ‹€μ‹œ λ§ν•΄μ„œ μžλ°”μ˜ κ°μ²΄λŠ” μœ„μ˜ λ©”μ„œλ“œλ“€μ„ λ°˜λ“œμ‹œ 가지고 μžˆλ‹€κ³  ν•  수 μžˆλ‹€. 이 μ€‘μ—μ„œ λͺ‡κ°€μ§€ μ€‘μš”ν•œ API 듀을 μ‚΄νŽ΄λ³΄μž.

toString()

class Calculator {
	int right;
    int left;
    
    public void setOprands(int left, int right) {
    	this.left = left;
        this.right = right;
	}
    
	public void sum() {
		System.out.println(this.left + this.right;
	}

public class CalculatorDemo {
	public static void main(String[]args) {
				
		Calculator c1 = new Calculator();
		c1.setOprands(10, 20);
		System.out.println(c1);
	}
}

Output
Calculator@6d06d69c
(@ 뒀에 λ‚΄μš©μ€ 각자 λ‹€λ₯Ό 것이닀.)

μ‹€ν–‰κ²°κ³ΌλŠ” c1이 클래슀 Calculator의 μΈμŠ€ν„΄μŠ€λΌλŠ” μ˜λ―Έλ‹€. @ 뒀에 λ‚΄μš©μ€ μΈμŠ€ν„΄μŠ€μ— λŒ€ν•œ κ³ μœ ν•œ 식별값 μ •λ„λ‘œ μƒκ°ν•˜μž. ν•˜μ§€λ§Œ 이 μ‹€ν–‰κ²°κ³ΌλŠ” μš°λ¦¬κ°€ μ›ν•˜λ˜ κ²°κ³Όκ°€ 아닐것이닀. 그럼 toString을 μ‚¬μš©ν•΄ μœ μš©ν•œ κ²°κ³Όλ₯Ό λ§Œλ“€μ–΄λ³΄μž.

class Calculator {
	int right;
	int left;

	public void setOprands (int left, int right) {
		this.left = left;
		this.right = right;
	}

	public void sum() {
		System.out.println(this.left + this.right;
	}

	public String toString() {
		return "left : " + this.left + ", right : "+ this.right;
	}


public class CalculatorDemo {
	public static void main(String[]args) {
				
	Calculator c1 = new Calculator();
	c1.setOprands(10, 20);
    
	System.out.println(c1);
	System.out.println(c1.toString());
    
	}
}	

Output
left : 10, right : 20
left : 10, right : 20

클래슀 Calculator에 toString()을 μž¬μ •μ˜(overriding)ν–ˆλ‹€. 그리고 System.out.println의 인자둜 μ „λ‹¬ν•˜λ‹ˆκΉŒ toString()을 λͺ…μ‹œμ μœΌλ‘œ ν˜ΈμΆœν•˜μ§€ μ•Šμ•˜μŒμ—λ„ λ™μΌν•œ νš¨κ³Όκ°€ λ‚˜κ³  μžˆλ‹€. toString() λ©”μ„œλ“œλŠ” μžλ°”μ—μ„œ νŠΉλ³„νžˆ μ·¨κΈ‰ν•˜λŠ” λ©”μ„œλ“œλ‹€. toString()을 직접 ν˜ΈμΆœν•˜μ§€ μ•Šμ•„λ„ μ–΄λ–€ 객체λ₯Ό System.out.println둜 ν˜ΈμΆœν•˜λ©΄ μžλ™μœΌλ‘œtoString()이 ν˜ΈμΆœλ˜λ„λ‘ μ•½μ†λ˜μ–΄ μžˆλ‹€. 이λ₯Ό 톡해 μΈμŠ€ν„΄μŠ€ c1의 μƒνƒœλ₯Ό μ‰½κ²Œ νŒŒμ•…ν•  수 있게 λ˜μ—ˆλ‹€.

equals()

equalsλŠ” 객체와 객체가 같은 것인지 λΉ„κ΅ν•˜λŠ” API이닀. 객체 κ°„μ˜ κ°™κ³  닀름은 ν•„μš”μ— 따라 λ‹¬λΌμ§ˆ 수 있기 λ•Œλ¬Έμ΄λ‹€.

class Student {
	String name;

	Student(String name) {
		this.name = name;
	}

	public boolean equals(Object obj) {
		Student _obj = (Student)obj;
		return name == _obj.name;
	}
}

class ObjectDemo {
	public static void main(String[]args) {
		Student s1 = new Student("pie");
		Student s2 = new Student("pie");

		1.	System.out.println(s1==s2);
		2.	System.out.println(s1.equals(s2));
	}
}

Output
false
true

μ—¬κΈ°μ„œ μ£Όλͺ©ν•΄μ•Ό ν•  점은 1.System.out.println(s1==s2)이닀. κ²°κ³ΌλŠ” false. κ·Έ μ΄μœ λŠ” s1κ³Ό s2κ°€ μ„œλ‘œ λ‹€λ₯Έ 객체이기 λ•Œλ¬Έμ΄λ‹€. ν•˜μ§€λ§Œ 두 κ°μ²΄λŠ” λ…Όλ¦¬μ μœΌλ‘œλŠ” pie λΌλŠ” 값을 가지고 있기 λ•Œλ¬Έμ— 객체λ₯Ό λ§Œλ“  κ°œλ°œμžλŠ” μ € λ‘κ°œμ˜ 객체가 같은 객체둜 κ°„μ£Ό λ˜μ—ˆμŒ μ’‹κ² λ‹€. 이럴 λ•Œ 클래슀 Object의 λ©”μ„œλ“œ equals()λ₯Ό overriding ν•˜λ©΄ λ˜μ§€λ§Œ, equalsλ₯Ό μ œλŒ€λ‘œ μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„  hashCodeλΌλŠ” ν΄λž˜μŠ€λ„ ν•¨κ»˜ κ΅¬ν˜„ν•΄μ•Ό ν•˜λŠ”λ° λ„ˆλ¬΄ λ³΅μž‘ν•˜κ³  무거운 λ‚΄μš©μ΄λ‹ˆ λ‹€μŒ λ‚΄μš©λ§Œ 잘 κΈ°μ–΅ν•˜μž.
1. 논리적(μ €μž₯ν•˜κ³  μžˆλŠ” 데이터)으둜 λ™λ“±ν•œμ§€ ν™•μΈν•˜κ³  μ‹ΆμœΌλ©΄ equals()λ₯Ό μ‚¬μš©ν•˜μž.
2. 물리적(같은 객체λ₯Ό μ°Έμ‘°ν•˜κ³  μžˆλŠ”μ§€)으둜 λ™λ“±ν•œμ§€ ν™•μΈν•˜κ³  μ‹ΆμœΌλ©΄ ==λ₯Ό μ‚¬μš©ν•˜μž.

Object λ©”μ„œλ“œ

λ©”μ„œλ“œμ„€ λͺ…
protected Object clone()ν•΄λ‹Ή 객체의 λ³΅μ œλ³Έμ„ μƒμ„±ν•˜μ—¬ λ°˜ν™˜ν•¨.
boolean equals(Object obj)ν•΄λ‹Ή 객체와 전달받은 객체가 같은지 μ—¬λΆ€λ₯Ό λ°˜ν™˜ν•¨.
protected void finalize()ν•΄λ‹Ή 객체λ₯Ό λ”λŠ” 아무도 μ°Έμ‘°ν•˜μ§€ μ•Šμ•„ 가비지 컬렉터가 객체의 λ¦¬μ†ŒμŠ€λ₯Ό μ •λ¦¬ν•˜κΈ° μœ„ν•΄ ν˜ΈμΆœν•¨.
Class getClass()ν•΄λ‹Ή 객체의 클래슀 νƒ€μž…μ„ λ°˜ν™˜ν•¨.
int hashCode()ν•΄λ‹Ή 객체의 ν•΄μ‹œ μ½”λ“œκ°’μ„ λ°˜ν™˜ν•¨.
void notify()ν•΄λ‹Ή 객체의 λŒ€κΈ°(wait)ν•˜κ³  μžˆλŠ” ν•˜λ‚˜μ˜ μŠ€λ ˆλ“œλ₯Ό λ‹€μ‹œ μ‹€ν–‰ν•  λ•Œ ν˜ΈμΆœν•¨.
void notifyAll()ν•΄λ‹Ή 객체의 λŒ€κΈ°(wait)ν•˜κ³  μžˆλŠ” λͺ¨λ“  μŠ€λ ˆλ“œλ₯Ό λ‹€μ‹œ μ‹€ν–‰ν•  λ•Œ ν˜ΈμΆœν•¨.
String toString()ν•΄λ‹Ή 객체의 정보λ₯Ό λ¬Έμžμ—΄λ‘œ λ°˜ν™˜ν•¨.
void wait()ν•΄λ‹Ή 객체의 λ‹€λ₯Έ μŠ€λ ˆλ“œκ°€ notify()λ‚˜ notifyAll() λ©”μ†Œλ“œλ₯Ό μ‹€ν–‰ν•  λ•ŒκΉŒμ§€ ν˜„μž¬ μŠ€λ ˆλ“œλ₯Ό μΌμ‹œμ μœΌλ‘œ λŒ€κΈ°(wait)μ‹œν‚¬ λ•Œ ν˜ΈμΆœν•¨.
void wait(long timeout)ν•΄λ‹Ή 객체의 λ‹€λ₯Έ μŠ€λ ˆλ“œκ°€ notify()λ‚˜ notifyAll() λ©”μ†Œλ“œλ₯Ό μ‹€ν–‰ν•˜κ±°λ‚˜ 전달받은 μ‹œκ°„μ΄ μ§€λ‚ Β λ•ŒκΉŒμ§€ ν˜„μž¬ μŠ€λ ˆλ“œλ₯Ό μΌμ‹œμ μœΌλ‘œ λŒ€κΈ°(wait)μ‹œν‚¬ λ•Œ ν˜ΈμΆœν•¨.
void wait(long timeout, int nanos)ν•΄λ‹Ή 객체의 λ‹€λ₯Έ μŠ€λ ˆλ“œκ°€ notify()λ‚˜ notifyAll() λ©”μ†Œλ“œλ₯Ό μ‹€ν–‰ν•˜κ±°λ‚˜ 전달받은 μ‹œκ°„μ΄ μ§€λ‚˜κ±°λ‚˜ λ‹€λ₯Έ μŠ€λ ˆλ“œκ°€ ν˜„μž¬ μŠ€λ ˆλ“œλ₯Ό μΈν„°λŸ½νŠΈ(interrupt) ν•  λ•ŒκΉŒμ§€ ν˜„μž¬ μŠ€λ ˆλ“œλ₯Ό μΌμ‹œμ μœΌλ‘œ λŒ€κΈ°(wait)μ‹œν‚¬ λ•Œ ν˜ΈμΆœν•¨.

끝!

μ΄λ²ˆμ£Όλ„ μ—΄μ‹¬νžˆ ν•œ λ‚˜,, κ²°κ³ΌλŠ” 체λ ₯ 고갈,,,

[좜처]
https://hyoje420.tistory.com/14
https://velog.io/@sewonkim/Java-μžλ°”μ˜-상속-λ‹€μ΄λ‚˜λ―Ή-λ©”μ†Œλ“œ-λ””μŠ€νŒ¨μΉ˜-Dynamic-Method-Dispatch
http://www.tcpschool.com/java/java_api_object
https://opentutorials.org/module/516/6241
https://kephilab.tistory.com/92

profile
β‹†ο½‘οΎŸβ˜…β‹†βΊβ‚Šβ‹† ゚☾ οΎŸο½‘β‹† β˜οΈŽο½‘β‚Šβ‹†

0개의 λŒ“κΈ€