static, private, public 키워드를 개발하면서 정확히 언제 사용하는지 모르고 사용한다는 느낌을 받았다.
분명 용도가 다르니 이름이 다른 것일텐데 그 목적과 쓰임에 대해서 공부한 내용을 정리해보려고 한다!
static은 왜 사용하는걸까?
- 클래스의 변수, 메서드 등을 공유하는데에 쓰인다. 이를 통해 해당 클래스로 만들어지는 객체사이에서 중복되는 메서드, 속성을 효율적으로 정의하기 위해 쓰인다.
- 단, 선언하자마자 메모리(데이터 영역)에 올라가게 된다. 즉, 사용하지 않아도 항상 메모리 공간을 차지하게 됨.
class Person {
name: string;
age: number;
iq: number;
gender: string;
constructor(name = "sunghwan", age = 28, iq = 120, gender = "man") {
this.name = name;
this.age = age;
this.iq = iq;
this.gender = gender;
}
static talk(a: Person, b: Person): void {
console.log(`${b.name}가 ${a.name}에게 대화를 요청했다.`);
return;
}
}
const defaultPerson = new Person();
const artificialPerson = new Person("또 다른 나", 20, 200, "man");
Person.talk(defaultPerson, artificialPerson);
위의 코드처럼 static을 해당 class에 선언을하게 되면 해당 talk메소드를 외부에서 호출할 수 있게 되고 클래스로부터 생성되는 객체마다 해당메소드를 필드값으로 담아둘 필요없이 필요할 때만 클래스에 의해 호출을 하면 된다.
Deep Dive
public, static, private에 대한 특징과 차이점
- public : 클래스 내에서 메소드를 만들 때 기본 값으로 설정되는 값이다. 해당 클래스 뿐만 아니라 외부에서도 자유롭게 접근이 가능하다.
- static : 클래스 내부적으로 접근이 가능하도록 하는 키워드이다. static으로 생성된 정적 필드는 클래스의 인스턴스가 모두 공유하지만 해당 메소드는 클래스의 인스턴스와는 아무런 연관이 없다.
class Person {
name: string;
age: number;
iq: number;
gender: string;
talkCnt: number;
constructor(
name = "sunghwan", age = 28, iq = 120, gender = "man", talkCnt = 0
) {
this.name = name;
this.age = age;
this.iq = iq;
this.gender = gender;
this.talkCnt = talkCnt;
}
static talk(a: Person, b: Person): void {
console.log(`${b.name}가 ${a.name}에게 대화를 요청했다.`);
a.talkCnt++;
b.talkCnt++;
return;
}
}
const defaultPerson = new Person();
console.log("말하기 전 : ", defaultPerson);
const artificialPerson = new Person("또 다른 나", 20, 200, "man");
Person.talk(defaultPerson, artificialPerson); // 클래스를 통해 메소드 호출
console.log("말하기 후 : ", defaultPerson);
static 키워드를 통해 메소드를 정의해주면 해당 메소드는 Person.talk를 통해 호출할 수 있다.
(클래스의 인스턴스로 접근을 하려고하면 에러를 내뱉는다.)
- private : 클래스 자체적으로 접근이 가능하도록 하는 키워드이다. 해당 키워드로 선언된 변수나 메소드는 외부에서 사용할 수 없을 뿐만 아니라, 오직 해당 클래스에서만 쓰이고 하위 클래스에게 상속을 해줄 수 없다.
class Person {
name: string;
age: number;
iq: number;
gender: string;
talkCnt: number;
constructor(
name = "sunghwan", age = 28, iq = 120, gender = "man", talkCnt = 0
) {
this.name = name;
this.age = age;
this.iq = iq;
this.gender = gender;
this.talkCnt = talkCnt;
}
// private키워드로 인한 정보 은닉(오로지 Person에서만 접근 가능함)
private talk(a: Person): void {
console.log(`${this.name}가 ${a.name}에게 대화를 요청했다.`);
a.talkCnt++;
this.talkCnt++;
return;
}
addTalkCnt(a: Person) {
this.talk(a);
}
}
const defaultPerson = new Person();
console.log("말하기 전 : ", defaultPerson);
const artificialPerson = new Person("또 다른 나", 20, 200, "man");
defaultPerson.addTalkCnt(artificialPerson); // 해당 클래스의 인스턴스는 talk 메소드에 직접적으로 접근이 불가능하다.
console.log("말하기 후 : ", defaultPerson);
위 코드의 결과값은 static 키워드를 사용했을 때와 동일하다.
- 그렇다면 언제 static이 쓰이고 언제 private이 쓰이는 걸까??
- static을 사용하는 경우
- 공유 데이터 및 동작 관리: 클래스의 인스턴스와 관련이 없는 데이터를 관리하거나, 인스턴스와 무관한 동작을 수행할 때 사용.
- 전역적인 동작 정의: 클래스 내부에서 전역적으로 동작해야 하는 메서드를 정의할 때 사용.
class Counter {
static count = 0;
constructor() {
// 인스턴스 생성될 때마다 count 증가
Counter.count++;
}
static getCount() {
// 클래스 메서드에서 count 값 반환
return Counter.count;
}
}
// 인스턴스 생성
const counter1 = new Counter();
const counter2 = new Counter();
const counter3 = new Counter();
// count 값 출력
console.log(Counter.getCount()); // 출력: 3
2. private을 사용하는 경우
- 캡슐화 및 정보 은닉: 클래스의 내부 구현 세부사항을 숨기고, 외부에서의 접근을 제한하여 안전성을 유지할 때 사용됩니다.
- 내부 상태 보호: 외부에서 클래스의 내부 상태를 변경하거나 접근하는 것을 방지하기 위해 사용됩니다.
class test {
private add(a: number, b: number) {
return a + b;
}
private multipleFive(a: number) {
return a * 5;
}
private dividedByTwo(a: number) {
return a / 2;
}
secretCalculate(a: number, b: number) {
const resultAdd = this.add(a, b);
const resultMul = this.multipleFive(resultAdd);
const res = this.dividedByTwo(resultMul);
return res;
}
}
const testObj = new test();
//secretCalculate 메소드의 procedure를 숨기고 결과값만을 출력한다.
console.log(testObj.secretCalculate(5, 10));
console.log(testObj.add(5,10));//add 메소드는 test클래스에서만 쓰이는 메소드이므로 해당 클래스의 인스턴스는 접근할 수 없기에 에러를 내뱉는다
Conclusion
정리하자면, private과 static모두 클래스 내부에서만 사용이 가능하다.
그러나 private은 클래스 내에서만 접근할 수 있는 데이터를 보호하기 위해 사용되고 이를 클래스 외부에서 읽거나 조작할 수는 없다. static은 클래스의 모든 인스턴스가 공유할 수 있는 정적인 데이터나 동작을 정의할 때 사용한다.
static으로 선언된 변수나 함수는 프로그램이 동작하는 시점에서부터 메모리의 데이터영역에 적재되어 프로그램의 실행이 끝날 때 까지 사라지지 않는다.
private, public으로 선언된 변수나 함수는 인스턴스들이 각자 다른 데이터를 다루기 때문에 객체가 생성되는 시점에서 메모리의 힙 영역에 적재되고 가비지 컬렉션에 의해 정리된다.
public : 어디에서나 접근가능한 붕어빵.(전시용 붕어빵)
static : 특정 붕어빵에 국한된 것이 아닌 모든 붕어빵에 적용되는 속성. (로고)
private : 붕어빵을 만드는 비밀 레시피
'Things I was curious about' 카테고리의 다른 글
[CS] 컴퓨터 시스템으로의 여행 (0) | 2024.03.27 |
---|---|
[TCP/IP] 개념 및 계층 구조 이해 (0) | 2024.03.25 |
[AWS] VPC구성에서 서버구축까지 (2) | 2024.03.22 |
구글 개발자chorome에서 undefined가 출력되는 이유 (0) | 2024.03.21 |
Node.js의 동작 원리 (feat. 이벤트 루프) (0) | 2024.02.23 |
댓글