JAVASCRIPT

JAVASCRIPT ) class

Hweb 2024. 7. 22. 15:39

class문은 설계도 이다.

class는 속성과 메소드로 구성되어있다.

new 에 넘기는 매개변수는 변하지않을 고유의 값만 넘겨야한다.

Class 객체에서 변할수 있는 속성값을 매개변수로 넘기면 안된다.

문법적으로는 constructor를 생략하고 인스턴스를 생성한 이후에 속성을 동적으로 추가할 수도있지만 세상에 속성이 없는 객체는 없기에 의미론적으로는 반드시 constructor를 입력해야한다. 


class(설계도)를 이용하여 생성한 객체를 인스턴스(instance)라고 한다.

 

class humanBeing {
    constructor(name){
    	// 여기 안에 들어가는 속성들을 클래스필드라고 부름
        this._name = name;
    }
    speak(){
    	alert('내 이름은' + this._name);
    }
}

const inyoungHuman = new humanBeing('inyoung');
document.write(inyoungHuman._name);
inyoungHuman.speak();

 

 

getter / setter

class(설계도) 의 속성들은 class(설계도) 밖에서 변경도, 참조도 하면안된다. 물론 문법적으로는 가능하지만 의미론적으로

하지만 식별자같은 고유의 속성값은 class(설계도)안에서도 변경하면 안된다.

만약 밖에서 참조해도 되는 속성을 지정하고싶다면 get 키워드를 사용하여 return값을 밖에서 참조하도록 한다.

get으로 오픈시킨 속성명에는 _를 붙여주는 약속? 같은게 있다.

 

class humanBeing {
	constructor( name, headColor ){
    	this.name = name;
    	this.head =  1;
        this._headColor = headColor;
    }
    get headColor(){
    	return this._headColor;
    } 
  	running(){
    	document.write('달리는중');
  	}
  	singing(){
    	document.write('노래하는중');
  	}
}

const inyoungHuman = new humanBeing('inyoung', '노랑');
const minjiHuman = new humanBeing('minji', '갈색');

inyoungHuman.running();
minjiHuman.singing();
document.write(inyoungHuman.headColor);	// get을 붙여놨기때문에 ()을 붙이지 않아도된다.

 

 

밖에서값을 변경해도되는 속성을 지정하고싶다면 set 키워드를 사용하여 밖에서 값변경을 허용시킨다.

 

class humanBeing {
	constructor( name, headColor ){
    	this.name = name;
    	this.head =  1;
        this._headColor = headColor;
    }
    get headColor(){	//앞에 get과 set이 붙었기때문에 메소드명이 동일에도 무방하다
    	return this._headColor;
    }
    set headColor(){	//앞에 get과 set이 붙었기때문에 메소드명이 동일에도 무방하다
    	this._headColor = headColor;
    }
  	running(){
    	document.write('달리는중');
  	}
  	singing(){
    	document.write('노래하는중');
  	}
}

const inyoungHuman = new humanBeing('inyoung', '노랑');
const minjiHuman = new humanBeing('minji', '갈색');

inyoungHuman.running();
minjiHuman.singing();
inyoungHuman.headColor = '검정';	// set을 시켰기때문에 밖에서 변경해도된다.
document.write(inyoungHuman.headColor);	// get을 시켰기때문에 ()을 붙이지 않아도된다.

 

 

class 안에서 올바른 new 생성

class A{}
class B{}
class C{}

class D{
	constructor(){
    	this.a = new A();
    }
}

 

 

위의 생성방법은 문법적으로는 맞으나 의미상으로는 맞지않다.

constructor에는 class의 고유한 속성만 와야한다.

아래의 방법은 올바른 방법이다.

이유는 메소드를 실행할 때에만 new를 생성하고 메소드를 실행하지않을 때에는 생성하지않기 때문이다.

 

class A{}

class D{
	constructor(){
    	this.a = null;
    }
    method1(){
    	this.a = new A();
    }
}

 

 

추상클래스 Abstract

추상클래스란 클래스의 설계도? 이다.

추상클래스는 new의 대상이 될 수 없다.( Static 메소드가 붙은것도 new의 대상이 될 수 없다. )

추상클래스는 파생클래스를 만드는 용도이고 파생클래스를 통해서만 인스턴스를 만들 수 있다.

 

 

인터페이스

인터페이스란 다른 클래스 사이의 중간 매개 역할까지 담당하는 클래스를 말한다.

클래스간의 연관 관계를 묶은 또다른 클래스이다.

인터페이스는 하나의 단일 클래스로 봐도 무방하며 추상 클래스가 될 수 있다.

자바스크립트에는 없는 개념이다.

 

 

예제1)

 

<body>
    <div id="newProduct"></div>
    <script>
        class newProduct {
            constructor(id, proName){
                this.id = id;
                this.proName = proName;
            }
            displayProduct(displayArea){
                const targetArea = document.getElementById(displayArea);
                targetArea.innerHTML += `<div id="item${this.id}">${this.proName}</div>`;
            }
        }
        const newProductName = ['pro 1', 'pro 2', 'pro 3', 'pro 4', 'pro 5', 'pro 6', 'pro 7', 'pro 8'];
        const newProductList = [];
        for(let i=0; i<newProductName.length; i++){
            newProductList[i] = new newProduct(i+1, newProductName[i]);
        }
        newProductList[0].displayProduct('newProduct');
        newProductList[1].displayProduct('newProduct');
        newProductList[5].displayProduct('newProduct');
    </script>
</body>

 

 

 

예제2)

 

 

<input id="input01" type="text">
    <input id="input02" type="text">
    <button id="btn">더하기</button>
    <p id="textArea"></p>
    <script>
        
        class Plus {
            constructor(inputV1, inputV2){
                this.inputV1 = inputV1;
                this.inputV2 = inputV2;
                this.resultV = 0;
            }
            plusAction(){
                this.resultV = Number(this.inputV1) + Number(this.inputV2);
                document.getElementById("textArea").innerHTML = String(this.resultV);
            }
        }

        document.getElementById("btn").addEventListener(
            'click',
            function(){
                let inputV1 = document.getElementById("input01").value;
                let inputV2 = document.getElementById("input02").value;
                const calculation = new Plus(inputV1, inputV2);
                calculation.plusAction();
            }
        )
    </script>

 

 

 

상속 class / 파생 class

//상속 클래스
class Circle {
    constructor(radius){
        this.radius = radius;
    }

    // 원의 지름
    getDiameter(){
        return 2 * this.radius;
    }

    // 원의 둘레
    getPerimeter(){
        return 2* Math.PI * this.radius;
    }

    // 원의 넓이
    getArea(){
        return Math.PI * Math.pow(this.radius, 2);
    }
}

// 파생 클래스
class Cyliner extends Circle {
    constructor(radius, height){
        super(radius);
        this.height = height;
    }

    // 원통의 넓이 : 상속 클래스의 getArea 메소드를 오버라이딩하였다.
    getArea(){
        // (원통의 높이 * 원의 둘레)  + (2 * 원의 넓이)
        return (this.height * super.getPerimeter()) + (2 * super.getArea());
    }

    // 원통의 부피
    getVolume(){
        return super.getArea() * this.height;
    }
}

// 반지름이 2, 높이가 10인 원통
const cylinder =  new Cyliner(2, 10);

// 원의 지름
document.write(cylinder.getDiameter() + "<br>");

// 원의 둘레
document.write(cylinder.getPerimeter() + "<br>");

// 원통의 넓이
document.write(cylinder.getArea() + "<br>");

// 원통의 부피
document.write(cylinder.getVolume() + "<br>");

// cylinder는 Cylinder 클래스의 인스턴스이다.
console.log(cylinder instanceof Cyliner);

// cylinder는 Circle 클래스의 인스턴스이다.
console.log(cylinder instanceof Circle);

 

 

중첩 class

중첩 class는 메소드 안에만 위치할 수 있다.

<body>
    <div id="resultArea"></div>
<script>
    class Palin {
        constructor(id){
            this.id = id;
            this.string = '';
            this.resultPalin = null;
        }
        checkPalin(tempString){
            // 중첩 class는 메소드 안에만 위치할 수 있다.
            class Stack {
                constructor(id){
                    this.id = id;
                    this.storage = [];
                }
                push(item){
                    this.storage.push(item);
                }
                pop(){
                    return this.storage.pop();
                }
                lengthV(){
                    return this.storage.length;
                }
            }
            const tempStack = new Stack('tempStack');
            let revString = '';
            
            this.string = tempString;

            // 문자열을 하나씩 스택에 넣어주기
            for(let i=0; i<this.string.length; i++){
                tempStack.push(this.string[i]);
            }

            // 하나씩 꺼내서 revString에 넣기
            const compLength = tempStack.lengthV();
            for(let i=0; i<compLength; i++){
                revString += tempStack.pop();
            }

            // 비교
            if(this.string == revString){
                this.resultPalin = true;
            } else {
                this.resultPalin = false;
            }
        }
        printResult(targetDom){
            const palinResult = this.resultPalin ? "Palin" : "No Palin";
            targetDom.innerHTML = palinResult;
        }
        run(item, targetDom){
            this.checkPalin(item);
            this.printResult(targetDom);
        }
    }

    const myPalin = new Palin('myPalin');
    myPalin.run('기러기', document.getElementById('resultArea'));
</script>
</body>

 

반응형