본문 바로가기

Javascript

7. javascript 클래스 고급기능(private, getter setter, Static, 오버라이드, toString)

나: 인스턴스

사람: 클래스 (작성양식: 클래스. 작성내용:매개변수)

동물: 추상클래스

 

매개변수: 클래스는 변하지않음. 매개변수가 각 객체를 다르게 만듦. 

생성자: 

 

C는 절차지향. 압도적으로 효율적인 코드가 필요할 때 (ex. 달탐사)

<외울것>

-객체지향패러다임. 

객체지향패러다임: 객체지향 프로그래밍 객체를 만들고 객체들의 상호작용을 중심으로 개발하는 방법론 

-추상화(필요한 요소만을 사용해서 객체를 표현하는 것을 의미)

 복잡한 자료 모듈 시스템 등으로부터 핵심적인 개념을 간추려내는것 

 

-인스턴스:클래스를 기반으로 만든 객체 

 

생성자(constructor): 안쓰면 기본임

클래스를 기반으로 인스턴스를 생성할 때 처음으로 호출되는 메소드 속성을 추가하는 등 객체의 초기화 처리

 

+메소드: 함수로 추가한다.

 

 

클래스 선언하기 

class 클래스이름{

생성자(변수,변수,,,,){

변수정의}}

 

extend 사용하기

class 클래스이름 extends 부모클래스이름 {

생성자(변수, 변수,,,,){

super(변수,변수)}

 

------------------------------------------------

9-2 class 의 고급기능 

1. 상속  

상속은 클래스의 선언 코드를 중복해서 작성하지 않도록 함으로써 코드의 생산효율을 올리는 문법 

class 클래스 이름 extends 부모클래스 이름{}

super 은 부모클래스를 의미함 

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
class Rectangle{
constructor(width,height){
this.width=width
this.height=height
}


//사각형의 둘레를 만드는 메소드
Perimeter(){
return 2*this.width
}

Area(){
return this.width*this.width
}
}

class Square extends Rectangle{
constructor(length){
super(length,length)
}
}

const square=new Square(10)
console.log(`${square.Area()}`)
</script>
</head>
<body>
 
</body>
</html>

+ 여기서는 Area를 함수로 만들었으니 console.log(`${square.Area()}`)가 된다

만약 get Area <<이렇게 get 함수로 만들었다면 console.log(`${square.Area}`) 이렇게 함수형식 아닌 Area 만 써도 출력됨!

 

 

2. private 속성과 메소드 

다른곳에서 날 참조할 수 있느냐 없느냐 

클래스 사용자가 클래스 속성을 의도하지 않은 방향으로 사용하는 것을 막아 클래스의 안전성을 확보하기 위해 나온 문법 

 

getter, setter 써야 쓸 수 있음 ! 

public 은 관리하기 어려움 

private  관리하기 쉬움 .

 

3. 게터와 세터 (getter, setter)

https://inpa.tistory.com/entry/JS-%F0%9F%93%9A-getter-setter-%EB%9E%80

 

📚 자바스크립트 Getter & Setter 완벽 정리

프로그래밍 Getter & Setter 개념 Getter와 Setter는 객체 지향 프로그래밍에서 사용되는 개념이며, 일조의 메서드라고 보면 된다. 즉, 단어 그대로 Getter는 객체의 속성(property) 값을 반환하는 메서드이

inpa.tistory.com

getter, setter : 객체의 속성에 바로 접근하지 않고 메서드를 통해 경유해서 설정

getter  : 객체의 속성값을 반환하는 메서드

setter  : 객체의 속성 값을 설정, 변경하는 메서드 

 

함수 호출 형식이 아닌, 일반 프로퍼티처럼 접근하여 사용 

(getter 와 setter 메서드를 구현하면 객체엔 userName 이라는 가상의 프로퍼티 생김. 읽고 쓸 순 있지만 실제로는 존재하지 X) 

 

사용하는 이유 :

1. 객체 내부 속성에 직접 접근하지 않아 객체의 정보 은닉을 가능 -> 보안 

2. 코드의 안전성과 유지보수성 높일 수 있다

3. 옳지 않은 값을 넣으려할 때 방지 

 

 

함수를 사용하면 내부에서 예외처리 할 수 있음 

 

setter

 
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
class Square{
#length

constructor(length){
this.setLength(length)
}

setLength(value){
if(value<=0){
throw '길이는 0보다 커야합니다.'
}
this.#length=value
}

getLength(value){
return this.#length
}

getPerimeter(){return 4*this.#length}
getArea(){return this.#length*this.#length}
}

//클래스 확인하기
const square=new Square(10)
console.log(`한 변의 길이는 ${square.getLength()}입니다`)

//예외 발생시키기
square.setLength(-5)
console.log(`한 변의 길이는 ${square.getLength()}입니다`)
</script>
</head>
<body>
 
</body>
</html>

 

getter setter 

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// 정사각형 클래스
class Square{
#length

constructor(length){
this.length=length
}

get length(){ //get 으로 설정해놓고 설정값만 불러오면 사용할 수 있음
return this.#length
}
get perimeter(){
return this.#length*4
}
get area (){
return this.#length*this.#length
}

set length(length){ //예외처리
if (length<=0){
throw '길이는 0보다 커야합니다.'
}
this.#length=length
}
}
//클래스 사용하기
const squareA=new Square(10)
console.log(`한 변의 길이: ${squareA.length}`)
console.log(`둘레: ${squareA.perimeter}`)
console.log(`넓이: ${squareA.area}`)
 
//예외발생시키기
const squareB=new Square(-10)
</script>
</head>
<body>
 
</body>
</html>

 

*static 속성과 메소드 : 

접근제한자 . 굳이 이걸 객체로 만들지 않고 필드나 메서드를 사용하고싶음 .

내가 객체를 불러오지않고도 사용할 수 있음  (Ex. console.log 처럼 이미 되어있음)

클래스,메소드로 생성하지 않고도 바로 사용하고 싶을떄 사용 

(static 과 private 특성 한번에 적용할 수 있음 ) 

 

getter, setter, static최종예제

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>

//하고싶은거: 정사각형의 넓이와 둘레 계산하기

//class 선언, 속성 설정한다
//private 으로 선언한다.


class Square{
#length
static #counter=0 //static이랑 private 이랑 같이쓴거임
static get counter(){ // get로 counter 만들었다. 왜냐면 private 이니까 get,set 으로 써야함
return Square.#counter //클래스 Square 에서 counter 라는 속성에 접근하라는 얘기임
}

constructor(length){
this.length=length //생성자가 호출될 때 전달된 length 매개변수의 값을 클래스의 인스턴스 속성인 length에 할당합니다. 이렇게 하면 객체를 생성할 때 매개변수로 전달된 값을 객체 내부에서 사용할 수 있습니다.
Square.#counter+=1
}

static perimeterOf(length){ //perimeterOf 라는 함수를 매개변수 length 를 사용하여 정의한다
return length*4 //static 공부하려고 추가. 없어도 됨!
}

static areaOf(length){ //area 함수를 지정한다
return length*length //static 공부하려고 추가. 없어도 됨!
}

get length(){return this.#length}
get perimeter(){return this.#length*4} //return Square.#perimeterOf(this.#length); 가능! perimeterOf 매개변수 빼먹으면 안됨
get area(){return this.#length*this.#length}
 
//메소드 추가한다.
// 단, 입력값이 0보다 작으면 안된다.
 
set length(length){ //예외 설정
if(length<0){
throw '길이는 0보다 커야합니다' //throw 는 오류발생시 알림, 프로그램 중단하고 예외를 처리할 수 있는 방향으로 제어 이동
}
this.#length=length
}
}

//static 속성 사용해서 출력하기
const squareA=new Square(10)
const squareB=new Square(20)
const squareC=new Square(30)

console.log(`지금까지 생성된 Square 인스턴스는 ${Square.counter} 개 입니다`)


console.log(`한 변의 길이가 20인 정사각형의 둘레는 ${Square.perimeterOf(20)}입니다.`)
console.log(`한 변의 길이가 30인 정사각형의 둘레는 ${Square.perimeterOf(30)}입니다.`)

//getter 메서드를 이용하여 출력하기. 함수형태아닌 property처럼 출력함.
// console.log(`정사각형A의 한 변의 길이: ${squareA.length}`);
// console.log(`정사각형A의 둘레: ${squareA.perimeter}`);
// console.log(`정사각형A의 넓이: ${squareA.area}`);
</script>
</head>
<body>
 
</body>
</html>

 

좀 더 알아보기 

1. 오버라이드 

다른 기능은 원래 있던걸 사용하고싶은데 하나는 아닐때 

LifeCycle 클래스를 상속받는 Child 라는 이름의 클래스를 선언하고 내부에서 부모에 있던 a()라는 이름의 메소드 만들기 

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
class LifeCycle{
call(){
this.a()
this.b()
this.c()
}
a(){ console.log('a()메소드를 호출합니다.')}
b(){ console.log('b()메소드를 호출합니다.')}
c(){ console.log('c()메소드를 호출합니다.')}

}

class Child extends LifeCycle{
a(){
console.log('자식의 a()메소드입니다.')
}
}

//인스턴스를 생성합니다.
new Child().call()
</script>
</head>
<body>
 
</body>
</html>

*Super 

오버라이드 해놨는데 부모내용을 다시 가져오고싶다. 

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
class LifeCycle{
call(){
this.a()
this.b()
this.c()
}
a(){ console.log('a()메소드를 호출합니다.')}
b(){ console.log('b()메소드를 호출합니다.')}
c(){ console.log('c()메소드를 호출합니다.')}

}

class Child extends LifeCycle{
a(){
super.a()
console.log('자식의 a()메소드입니다.')
}
}

//인스턴스를 생성합니다.
new Child().call()
</script>
</head>
<body>
 
</body>
</html>

*toString

자바스크립트는 내부적으로 어떤 객체를 문자열로 만들때 toString() 메소드를 호출

 따라서 toString() 메소드를 오버라이드하면 내부적으로 문자열로 변환되는 형태를 바꿀 수 있음

 

왜 쓰는걸까? -> 문자열을 출력하고싶은데 정보값이 출력되는 등 다른 양식으로 나오는 경우가 있음 !! 

예시>

https://inpa.tistory.com/entry/JAVA-%E2%98%95-toString-%EB%A9%94%EC%84%9C%EB%93%9C-%EC%9E%AC%EC%A0%95%EC%9D%98-%EC%99%84%EB%B2%BD-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0

 

상속은 어떤 클래스가 갖고 있는 유산(속성과 메소드)을 기반으로 새로운 클래스를 만드는것

private 속성/메소드는 클래스 내부에서만 접근할 수 있는 속성/메소드

게터는 getOO() 형태로 값을 확인하는 기능을 가진 메소드를 의미

세터는 getOO() 형태로 값을 지정하는 기능을 

오버라이드는 부모가 갖고있는 메소드와 같은 이름으로 메소드를 선언해서 덮어 쓰는 것을 의미

'Javascript' 카테고리의 다른 글

8.자바스크립트 프로젝트  (0) 2024.03.13
6. javascript 6 (예외처리, Class)  (0) 2024.03.11
5. javascript 5  (0) 2024.03.08
4. javascript4  (0) 2024.03.07
3. javascript3  (0) 2024.03.06