Interface in TS (vs Java)

2023. 3. 19. 18:21ㆍ언어/Javascript(Node, TS...)

νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ μΈν„°νŽ˜μ΄μŠ€μ™€ μžλ°”μ˜ μΈν„°νŽ˜μ΄μŠ€λŠ” μ„œλ‘œ μœ μ‚¬ν•œ ꡬ쑰와 λͺ©ν‘œλ₯Ό κ°–μ§€λ§Œ,

이용 방식과 λ”λΆˆμ–΄ 언어적 μ°¨μ΄μ—μ„œ μ˜€λŠ” μž‘λ™ λ°©μ‹μ—μ„œ 차이가 μ‘΄μž¬ν•˜μ—¬ 이λ₯Ό μ •λ¦¬ν•˜κ³ μž ν•œλ‹€.

 

Interfaceλž€?

좜처: https://coding-factory.tistory.com/867

μΈν„°νŽ˜μ΄μŠ€λŠ” 객체지ν–₯ νŒ¨λŸ¬λ‹€μž„μ—μ„œ λ‘œμ§μ„ ꡬ성할 λ•Œ 좔상화에 μ˜μ‘΄ν•  수 있게 ν•΄μ£Όμ–΄

결과적으둜 μΊ‘μŠν™”, λ‹€ν˜•μ„±μ„ λ‹¬μ„±ν•˜κΈ° μ‰½κ²Œ ν•΄μ£ΌλŠ” 도ꡬ이닀.

ꡬ체적으둜,

μΈν„°νŽ˜μ΄μŠ€λŠ” 이λ₯Ό ꡬ체화할 객체가 κ°€μ Έμ•Ό ν•  λ©”μ„œλ“œ(행동)의 νƒ€μž… 정보λ₯Ό λͺ…μ‹œν•˜λŠ” 역할을 ν•œλ‹€.

μ‹€μ œ κ΅¬ν˜„μ€ ν¬ν•¨μ‹œν‚€μ§€ μ•ŠμœΌλ©°, μ½”λ“œ μƒμ—μ„œλ„ μ‹€μ œ κ΅¬ν˜„μ²΄λ₯Ό 직접 μ˜μ‘΄ν•˜λŠ” 것이 μ•„λ‹Œ 좔상화 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ˜μ‘΄ν•˜κ²Œ λ‘œμ§μ„ μž‘μ„±ν•˜μ—¬

μ˜μ‘΄ν•˜λŠ” 객체둜 ν•˜μ—¬κΈˆ ν•΄λ‹Ή 객체의 μ„ΈλΆ€ κ΅¬ν˜„μ„ μ•Œμ§€ λͺ»ν•΄λ„ ν˜‘λ ₯이 κ°€λŠ₯ν•˜λ„λ‘ λ•λŠ”λ‹€.(μΊ‘μŠν™”)

μΈν„°νŽ˜μ΄μŠ€μ™€ μΈν„°νŽ˜μ΄μŠ€μ˜ κ΅¬ν˜„μ²΄μ˜ 관계λ₯Ό has-A 관계라고 ν•˜λŠ”λ°,

μ΄λŠ” νŠΉμ • κ΅¬ν˜„μ²΄κ°€ λ™μ‹œμ— λ‹€μ–‘ν•œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό 상속할 수 μžˆμŒμ„ λ‚΄ν¬ν•œλ‹€.

 

TS vs Java

컴파일 νƒ€μž„μ˜ νƒ€μž… 검사 방식

// Typescript
interface Human {
  name: string;
  job: string;
  
  setInfo(name: string, job: string): void;
  introduce(): string;
}
// Java
interface Human {
  int MAX_AGE = 100;
  
  void setInfo(String name, String job);
  String introduce();
}

νƒ€μž…μŠ€ν¬λ¦½νŠΈμ™€ μžλ°”μ—μ„œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ„ μ–Έν•˜λŠ” 방식은 μœ„μ™€ κ°™λ‹€.

λ‘˜μ€ λͺ¨λ‘ Human μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•  객체가 κ°€μ Έμ•Ό ν•  λ©”μ„œλ“œλ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ„ μ–Έν•˜κ³  μžˆλ‹€.

μœ„ μ½”λ“œλ₯Ό 톡해 μ•Œ 수 μžˆλŠ” 차이점은, 

νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” μΈν„°νŽ˜μ΄μŠ€μ—μ„œ μ™ΈλΆ€λ‘œ λ…ΈμΆœν•  ν”„λ‘œνΌν‹°μ— λŒ€ν•œ 섀정도 κ°€λŠ₯ν•œ 반면, μžλ°”μ—μ„œλŠ” λΆˆκ°€λŠ₯ν•˜λ‹€λŠ” 점과

νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” μΈν„°νŽ˜μ΄μŠ€ λ‚΄μ—μ„œ μΈν„°νŽ˜μ΄μŠ€μ˜ μƒμˆ˜λ₯Ό μ„ μ–Έν•  수 μ—†μ§€λ§Œ, μžλ°”μ—μ„œλŠ” μƒμˆ˜ 선언이 κ°€λŠ₯ν•˜λ‹€λŠ” 점이닀.

(선언이 λ‹¨μˆœ int둜 λ˜μ–΄ μžˆμ§€λ§Œ 컴파일 λ‹¨κ³„μ—μ„œ μ €μ ˆλ‘œ static final이 μΆ”κ°€λ˜μ–΄ μƒμˆ˜κ°€ λœλ‹€.)

 

λ˜ν•œ μœ„ μ½”λ“œ μƒμ—μ„œλŠ” 확인할 수 μ—†λŠ” 차이점도 μ‘΄μž¬ν•œλ‹€.

μ²«λ²ˆμ§ΈλŠ” λ°”λ‘œ 컴파일 μ‹œ νƒ€μž… 검사λ₯Ό μˆ˜ν–‰ν•˜λŠ” λ°©μ‹μ˜ 차이이닀.

κ²°λ‘ λΆ€ν„° λ§ν•˜μžλ©΄

νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” κ΅¬μ‘°μ  타이핑(Structural Typing) λ°©μ‹μœΌλ‘œ 검사λ₯Ό μˆ˜ν–‰ν•˜λŠ” 반면,

μžλ°”λŠ” λͺ…λͺ©μ  타이핑(Nominal Typing) λ°©μ‹μœΌλ‘œ 검사λ₯Ό μˆ˜ν–‰ν•œλ‹€.

λ¨Όμ € νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ κ²½μš°μ΄λ‹€.

// Typescript
interface IHuman {
    name: string;
    job: string;

    setInfo(name: string, job: string):void;
    introduce(): string;
}

class Student {
    name: string = "";
    job: string = "";

    setInfo(name: string, job: string) {
        this.name = name;
        this.job = job;
    }
    introduce() {
        return `my name is ${this.name} and my job is ${this.job}`;
    }
}

// Studentκ°€ μ§μ ‘μ μœΌλ‘œ IHuman을 μƒμ†ν•˜μ§€ μ•Šμ•˜μŒμ—λ„ νƒ€μž… 바인딩에 문제 x
const student: IHuman = new Student();
student.setInfo("Luka", "developer");
console.log(student.introduce());

μ•žμ„œ 보인 Human μΈν„°νŽ˜μ΄μŠ€μ™€

이λ₯Ό μ§μ ‘μ μœΌλ‘œ 상속(implements)ν•˜μ§€λŠ” μ•Šμ•˜μ§€λ§Œ 그에 맞게 λ‚΄λΆ€ κ΅¬ν˜„μ„ κ΅¬μ„±ν•œ Student ν΄λž˜μŠ€κ°€ μžˆλ‹€.

이 λ•Œ μž¬λ°ŒλŠ” 것은 μ½”λ“œ ν•˜λ‹¨μ˜ student λ³€μˆ˜μ˜ 클래슀인 Studentκ°€ IHuman μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ§μ ‘μ μœΌλ‘œ μƒμ†ν•˜μ§€ μ•Šμ•˜μŒμ—λ„, λ‚΄λΆ€ κ΅¬ν˜„μ΄ 이λ₯Ό λ§Œμ‘±ν•œλ‹€λŠ” κ²ƒλ§ŒμœΌλ‘œ νƒ€μž… 바인딩이 κ°€λŠ₯ν•˜λ‹€.

μ΄λŸ¬ν•œ νŠΉμ„±μ„ κ΅¬μ‘°μ  타이핑(Strutural Typing)이라고 ν•œλ‹€.

λ‹€μŒμ€ μžλ°”μ˜ κ²½μš°μ΄λ‹€.

// IHuman.java
interface IHuman {
  int MAX_AGE = 100;
  void setInfo(String name, String job);
  String introduce();
}

// Student.java
class Student {
  static final int MAX_AGE = 100;
  String name;
  String job;

  void setInfo(String name, String job) {
    this.name = name;
    this.job = job;
  }
  String introduce() {
    return "my name is " + this.name + " and my job is " + this.job;
  }
}


// Test.java
public class Test {
  public static void main(String[] args) {
    // IHuman νƒ€μž…μ— Student μΈμŠ€ν„΄μŠ€λ₯Ό 바인딩할 수 μ—†λ‹€λŠ” 컴파일 μ—λŸ¬ λ°œμƒ
    IHuman student = new Student();
    student.setInfo("luka","developer");
    System.out.println(student.introduce());
  }
}

μœ„μ™€ λ™μΌν•˜κ²Œ μžλ°”μ˜ κ²½μš°μ—μ„œλ„ IHuman μΈν„°νŽ˜μ΄μŠ€λ₯Ό 직접 μƒμ†ν•˜μ§€λŠ” μ•Šμ§€λ§Œ,

λ‚΄λΆ€ κ΅¬ν˜„μ„ κ·ΈλŒ€λ‘œ λ”°λ₯΄λŠ” Student 클래슀λ₯Ό λ§Œλ“€μ—ˆλ‹€.

이 λ•Œ μžλ°”μ—μ„œλŠ” νƒ€μž…μŠ€ν¬λ¦½νŠΈμ™€λŠ” 달리 컴파일 μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

μžλ°”μ—μ„œλŠ” 컴파일 νƒ€μž„μ—μ„œ νƒ€μž… 검사 μ‹œ μΈν„°νŽ˜μ΄μŠ€μ˜ λ‚΄λΆ€ ꡬ쑰λ₯Ό λ”°λ₯΄λŠ”지 확인을 ν•˜λŠ” 것이 μ•„λ‹Œ, μΈν„°νŽ˜μ΄μŠ€μ˜ 이름 자체λ₯Ό 가지고 검사λ₯Ό μˆ˜ν–‰ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

μ΄λŸ¬ν•œ νŠΉμ„±μ„ λͺ…λͺ©μ  타이핑(Nominal Typing)이라고 ν•œλ‹€.

 

λŸ°νƒ€μž„μ—μ„œμ˜ 쑴재 μ—¬λΆ€

μΈν„°νŽ˜μ΄μŠ€μ— λŒ€ν•΄ μžλ°”μ™€ νƒ€μž…μŠ€ν¬λ¦½νŠΈκ°€ κ°–λŠ” λ‘λ²ˆμ§Έ μ°¨μ΄λŠ” λ°”λ‘œ λŸ°νƒ€μž„μ—μ„œμ˜ 쑴재 여뢀이닀.

νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μž‘μ„±ν•˜μ—¬ μžλ°”μŠ€ν¬λ¦½νŠΈλ‘œ μ»΄νŒŒμΌν•˜λ©΄ μ–΄λ–»κ²Œ 될까?

// human.interface.ts
interface Human {
  name: string;
  job: string;
  
  setInfo(name: string, job: string): void;
  introduce(): string;
}

μœ„ μ½”λ“œλ₯Ό μ»΄νŒŒμΌν•  경우 λ‹€μŒμ˜ 결과물이 λ‚˜νƒ€λ‚œλ‹€.

// human.interface.js
"use_strict"

(아무 것도 μ—†λ‹€!)

κ²°κ³Όλ¬Όμ—μ„œ μ•Œ 수 μžˆλ“―μ΄ νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œ μΈν„°νŽ˜μ΄μŠ€λŠ” 컴파일 μ‹œ 사라져 버린닀.

즉 컴파일 νƒ€μž„κΉŒμ§€λ§Œ μœ νš¨ν•œ κ°œλ…μ΄κ³ , λŸ°νƒ€μž„μ—μ„œλŠ” μ½”λ“œλ‘œμ„œ μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”λ‹€.

νƒ€μž…μŠ€ν¬λ¦½νŠΈλ₯Ό 톡해 λ‘œμ§μ„ μž‘μ„±ν•΄λ³΄μ•˜λ‹€λ©΄, λˆ„κ΅¬λ‚˜ νƒ€μž… κ°€λ“œλ₯Ό ν•œλ²ˆ 쯀은 μž‘μ„±ν•΄λ³΄μ•˜μ„ 것이닀.

νƒ€μž… κ°€λ“œλž€ λŸ°νƒ€μž„μ—μ„œ νŠΉμ • 객체가 ν•΄λ‹Ή 객체의 νƒ€μž…μ΄ κ°€μ Έμ•Ό ν•  λ©”μ„œλ“œμ™€ ν”„λ‘œνΌν‹°κ°€ λͺ¨λ‘ 잘 μ‘΄μž¬ν•˜λŠ”μ§€ ν™•μΈν•˜κ³ 

κ·Έ 결과에 따라 boolean을 λ°˜ν™˜ν•˜λŠ” μΌμ’…μ˜ λŸ°νƒ€μž„ νƒ€μž… 검사λ₯Ό μˆ˜ν–‰ν•˜λŠ” 둜직이라 μƒκ°ν•˜λ©΄ λœλ‹€.

νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œ νƒ€μž… κ°€λ“œλ₯Ό λ”°λ‘œ μž‘μ„±ν•΄μ£Όμ–΄μ•Ό ν•˜λŠ” κΉŒλ‹­μ€, κ²°κ΅­ λŸ°νƒ€μž„μ—μ„œ μΈν„°νŽ˜μ΄μŠ€μ™€ 같은 νƒ€μž…μ΄ μ‘΄μž¬ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ΄λ‹€.

κ·Έλ ‡λ‹€λ©΄ μžλ°”μ˜ κ²½μš°μ—λŠ” μ–΄λ–¨κΉŒ.

μžλ°”μ˜ 경우, μΈν„°νŽ˜μ΄μŠ€κ°€ λŸ°νƒ€μž„μ—μ„œ λ°”μ΄νŠΈ μ½”λ“œμ˜ ν˜•νƒœλ‘œ μ‘΄μž¬ν•œλ‹€.

λ”°λΌμ„œ μ•„λž˜μ™€ 같은 λ‘œμ§λ„ κ°€λŠ₯ν•˜λ‹€.

// Student ν΄λž˜μŠ€κ°€ Human μΈν„°νŽ˜μ΄μŠ€μ˜ κ΅¬ν˜„μ²΄λΌκ³  κ°€μ •
const student = new Student();

// studentκ°€ Human의 싀체화인지 확인
if(student instanceof Human) { 
  ...
} else {
  ...
}

λ§Œμ•½ νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜€λ‹€λ©΄,

if λ¬Έ λ‚΄μ—μ„œ student μΈμŠ€ν„΄μŠ€κ°€ Humanμ—μ„œ μ •μ˜ν•œ νŠΉμ„±λ“€μ„ λͺ¨λ‘ κ΅¬ν˜„ν•˜κ³  μžˆλŠ”μ§€ 일일이 ν™•μΈν–ˆμ–΄μ•Ό ν•  것이닀.

'μ–Έμ–΄ > Javascript(Node, TS...)' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

Interface vs Abstract Class (in Typescript)  (0) 2023.03.19
TypeScript νƒ€μž…: any, unknown, never  (0) 2023.03.09
NodeJS Child_process의 spawn(), exec(), fork()  (0) 2023.03.05