1.  패키지

🚀  패키지는 클래스와 소스 파일을 관리하기 위한 디렉토리 구조의 저장 공간
      ✓ 현재 클래스가 어떤 패키지(디렉토리)에 있는지 표시
      ✓ 디렉토리가 계층 구조로 만들어져 있으면 점(.)으로 구분해서 각 디렉토리를 모두 나열해 줌

package 메인 디렉토리. 서브 디렉토리
class 클래스 {
}


🚀  이 디렉토리 구조라면 윈도우의 파일 탐색에서 보면 메인 디렉토리 아래에 서브 디렉토리가 있고, 서브 디렉토리 안에 실제 코드가 있는 클래스.kt 파일이 있음

🚀  하나의 패키지에 여러 개의 파일을 생성할 수 있기 때문에 '서로 관계가 있는 파일을 동일한 패키지로 만들어 두면 관리가 용이

 


2.  추상화

🚀  프로그래밍을 하기 전 개념 설계를 하는 단계에서는 클래스의 이름과 클래스 안에 있음 직한 기능을 유추해서 메서드 이름으로 먼저 나열. 이때 명확한 코드는 설계 단계에서 메서드 블록 안에 직접 코드를 작성하는데, 그렇지 않은 경우에는 구현 단계에서 코드를 작성하도록
메서드의 이름만 작성  ▶️ 이것을 추상화 Abstract 라고 하며 abstract 키워드를 사용해서 명시

 

  ✓ 구현 단계에서는 이 추상화된 클래스를 상속받아서 아직 구현되지 않은 부분을 마저 구현
  ✓ 다음과 같이 추상화된 Aniamal 클래스를 만들고 동물이 사용할 것 같은 기능 중 walk()와 move()를 설계한다고 가정

abstract class Animal {
    fun walk() {
        println("Walking")
    }

    abstract fun move()
}

 

  👾 walk는 명확하게 걸어가는 행위이지만 move는 어떤 동물이냐에 따라서 달라진다고 가정
  👾 이렇게 앞으로 상속받을 자식 클래스의 특징에 따라 코드가 결정될 가능성이 있다면 해당 기능도 abstract 키워드로 추상화
        ➡️  실제 구현 클래스는 이 추상 클래스를 상속받아서 아직 구현되지 않은 추상화되어 있는 기능을 모두 구현해 줌
  👾 추상 클래스는 독립적으로 인스턴스화 할 수 없기 때문에 구현 단계가 고려되지 않는다면 잘못된 설계가 될 수 있음

class Bird : Animal() {
    override fun move() {
        println("Bird move")
    }
}

 


3.  인터페이스

🚀 인터페이스 interface는 실행코드 없이 메서드 이름만 가진 추상 클래스. 즉, 누군가 설계해 놓은 개념 클래스 중에 실행 코드가 한 줄이라도 있으면 추상 클래스, 코드 없이 메서드 이름만 나열되어 있으면 인터페이스

🚀 인터페이스는 안드로이드에서는 주로 상속 관계의 설계보다는 외부 모듈에서 내가 만든 모듈을 사용할 수 있도록 메서드의 이름을 나열해둔 일종의 명세서로 제공

🚀 인터페이스는 interface 예약어를 사용해서 정의할 수 있고 인터페이스에 정의된 메서드를 오버라이드해서 구현할 수 있음
    ✓  코틀린은 프로퍼티도 인터페이스 내부에 정의할 수 있고, 추상 클래스와 다르게 class 키워드는 사용되지 않음

interface 인터페이스명 {
    var 변수 : String
    fun 메서드1()
    fun 메서드2()
}

 

 

1) 인터페이스 만들기

 

interface 예약어로 인터페이스를 정의
코틀린은 인터페이스 내부에 프로퍼티도 정의할 수 있음

interface InterfaceKotlin {
    var variable: String
    fun get()
    fun set()
}

 

 

2) 클래스에서 구현하기


인터페이스를 클래스에서 구현할 때는 상속과는 다르게 생성자를 호출하지 않고 인터페이스 이름만 지정해 주면 됨

class KotlinImpl : InterfaceKotlin {
    override var variable: String = "Default"
    override fun get() {

    }
    override fun set() {

    }
}

 

💡  인터페이스를 코틀린의 상속 형태가 아닌 소스 코드에서 직접 구현할 때도 있는데, object 키워드를 사용해서 구현해야 함
       ➡️  안드로이드 프로젝트에서 자주 사용하는 형태

val kotlinImpl = object : InterfaceKotlin {
    override var variable: String = "Default"

    override fun get() {

    }

    override fun set() {

    }
}

 

 

 

[ 내용 참고 : IT 학원 강의 ]


1.  버스 노선 가져오기

html 코드
<body>
<table>
    <thead>
        <tr>
            <th>버스번호</th>
            <th>버스등급</th>
            <th>평일요금</th>
            <th>평일 시간표</th>
            <th>주말 시간표</th>
        </tr>
    </thead>
    <tbody>

    </tbody>
</table>
<div>
    <input type="button" value="대구">
    <input type="button" value="구미">
    <input type="button" value="경산">
    <input type="button" value="포항">
</div>
</body>

 

css 코드
table, td, th {
    border-collapse: collapse;
    border: 2px solid black;
}

table th {
    height: 50px;
}

table td {
    padding: 15px;
}


table th:first-child {
    width: 200px;
}

table th:nth-child(2) {
    width: 100px;
}

table th:nth-child(3) {
    width: 200px;
}

table th:nth-child(4) {
    width: 550px;
}

table th:last-child {
    width: 550px;
}

div {
    margin: 0 auto;
    padding: 20px;
    text-align: center;
    width: 1000px;
}
div input {
    width: 70px;
    height: 40px;
    background-color: #3a4bb9;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    padding: 5px 10px;
}
div input:hover {
    background-color: white;
    color: #3a4bb9;
}

자바스크립트 코드
document.addEventListener('DOMContentLoaded', function () {

    const btns = document.querySelectorAll('[type=button]');

    btns.forEach(function (item) {
        item.addEventListener('click', function () {
            const cityName = item.getAttribute('value'); // value 값 변수에 담기
            let url = getUrl() // 함수값을 변수에 담기
            printlist(url, cityName); // 함수 호출
        });
    });

    // 1, 2 터미널 각각 분류된 평일 및 주말 시간표를 합치는 함수 만들기
    const sortStr = function (string1, string2) { 
        // 기본 데이터는 문자열. 2개의 문자열을 결합하고, ',' 기준으로 배열로 변환
        let tempList = (string1 + ', ' + string2).split(",");
        tempList = [...new Set(tempList)]; // set으로 중복값 제거
        tempList = tempList.map((item) => item.trim()) // 공백제거
        tempList.sort(); // 오름차순 정렬

        // 현재 시간 구해서 지나간 시간이면 연하게 출력.
        const today = new Date();
        const todayTime = `${today.getHours()}${today.getMinutes()}`;
        // console.log(todayTime)
        tempList = tempList.map((item) => {
            console.log(Number(item))
            return Number(item) < Number(todayTime) ? `<span style="color: #cccccc">${item}</span>` : item;
        });

        return tempList.join(", "); // 배열을 문자열로 변환
    }

    const getUrl = function () {
        const service_key = 'uAhO32pV0qa7BDOmkJLhw2ZyOB9i5bGj7cMN8cuuHmKIwyyf29lHLjym8hBXdIaXyvAI1IyLvQZopk5HW233qQ=='
        const para = `?serviceKey=${service_key}&area=6&numOfRows=100&pageNo=1&type=json`
        return 'http://apis.data.go.kr/B551177/BusInformation/getBusInfo' + para
        // console.log(url)
    }

    const printlist = function (getUrl, cityName) {
        const xhr = new XMLHttpRequest();
        xhr.open('GET', getUrl);
        xhr.onreadystatechange = () => {
            
            if (xhr.readyState !== XMLHttpRequest.DONE) return;

            if (xhr.status === 200) {
                console.log(xhr.response);
                jsonData = JSON.parse(xhr.response);
                //console.log(jsonData);

                const routes = jsonData.response.body.items;
                //console.log(routes)
                const tBody = document.querySelector("tbody");

                while (tBody.firstChild) {
                    tBody.removeChild(tBody.firstChild);
                }

                for (route of routes) {
                    //console.log(route["routeinfo"])

                    if (route["routeinfo"].indexOf(cityName) !== -1) {
                        const trTag = document.createElement('tr');
                        console.log(route)

                        trTag.innerHTML = `
                            <td>${route["busnumber"]}</td>
                            <td>${route["busclass"]}</td>
                            <td>${route["adultfare"]}</td>
                            <td>${sortStr(route["t1wdayt"], route["t2wdayt"])}</td>
                            <td>${sortStr(route["t1wt"], route["t2wt"])}</td>`

                        tBody.appendChild(trTag);
                    }
                }

            } else {
                console.error('Error', xhr.status, xhr.statusText);
            }
        }
        xhr.send();
    }
});

 


2.  항공 출도착 정보 

html 코드
<body>
<table>
    <div>
        <input type="button" id="NRT" value="나리타">
        <input type="button" id="CTS" value="삿포로">
        <input type="button" id="KIX" value="오사카/간사이">
        <input type="button" id="FUK" value="후쿠오카">
        <input type="button" id="HKG" value="홍콩">
    </div>

    <thead>
    <tr>
        <th>항공사</th>
        <th>편명</th>
        <th>예정시간</th>
        <th>도착지 공항</th>
    </tr>
    </thead>
    <tbody>

    </tbody>
</table>
</body>

 

css 코드
table {
    margin: 20px auto;
}

table, td, th {
    border-collapse: collapse;
    border: 2px solid black;
}

table th {
    height: 50px;
}

table td {
    padding: 15px;
    text-align: center;
}


table th:first-child {
    width: 200px;
}
table th:nth-child(2) {
    width: 60px;
}
table th:nth-child(3) {
    width: 150px;
}
table th:nth-child(4) {
    width: 160px;
}

div {
    margin: 0 auto;
    padding: 20px;
    text-align: center;
    width: 1000px;
}
div input {
    width: 100px;
    height: 40px;
    background-color: #3a4bb9;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    padding: 5px 10px;
}
div input:hover {
    background-color: white;
    color: #3a4bb9;
}

자바스크립트 코드
document.addEventListener('DOMContentLoaded', function () {
    const btns = document.querySelectorAll('[type=button]');

    btns.forEach(function (item) {
        item.addEventListener('click', function () {
            const airport = item.getAttribute("id");
            let url = getUrl(airport)
            printList(url);
        });
    });

    const getUrl = function (airportCode) {
        const service_key = 'uAhO32pV0qa7BDOmkJLhw2ZyOB9i5bGj7cMN8cuuHmKIwyyf29lHLjym8hBXdIaXyvAI1IyLvQZopk5HW233qQ=='
        const para = `?type=json&ServiceKey=${service_key}&airport_code=${airportCode}`
        return 'http://apis.data.go.kr/B551177/StatusOfPassengerFlightsDSOdp/getPassengerDeparturesDSOdp' + para
    }
    //console.log(getUrl())

    const printList = function (getUrl) {
        const xhr = new XMLHttpRequest();
        xhr.open('GET', getUrl);
        xhr.onreadystatechange = () => {
            // readyState 프로퍼티의 값이 DONE : 요청한 데이터의 처리가 완료되어 응답할 준비가 완료됨.
            if (xhr.readyState !== XMLHttpRequest.DONE) return;

            if (xhr.status === 200) { // 서버(url)에 문서가 존재함
                //console.log(xhr.response);
                const jsonData = JSON.parse(xhr.response);
                //console.log(jsonData);

                const airlines = jsonData.response.body.items;
                //console.log(airlines)

                const tBody = document.querySelector("tbody");

                while (tBody.firstChild) {
                    tBody.removeChild(tBody.firstChild);
                }

                for (airline of airlines) {

                    const list = document.createElement('tr');

                    list.innerHTML = `
                    <td>${airline['airline']}</td>
                    <td>${airline['flightId']}</td>
                    <td>${airline['estimatedDateTime']}</td>
                    <td>${airline['airport']}</td>`

                    tBody.appendChild(list);
                }

            } else {
                console.error('Error', xhr.status, xhr.statusText);
            }
        }
        xhr.send();
    }
});

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]


1.  회원가입 예제

body 태그
<body>
<div id="container">
    <h1>회원 가입</h1>
    <form action="#" id="register">
        <ul id="user-info">
            <li>
                <label for="user-id" class="field">아이디</label>
                <input type="text" name="user-id" id="user-id" placeholder="4~15자리로 입력" required>
            </li>
            <li>
                <label for="email" class="field">이메일</label>
                <input type="email" name="email" id="email" required>
            </li>
            <li>
                <label for="user-pw1" class="field">비밀번호</label>
                <input type="password" name="user-pw1" id="user-pw1" placeholder="8자리 이상" required>
                <span class="trans">문자로 변환</span>
            </li>
            <li>
                <label for="user-pw2" class="field">비밀번호 확인</label>
                <input type="password" name="user-pw2" id="user-pw2" required>
            </li>
            <li>
                <label class="field">메일링 수신</label>
                <label class="r"><input type="radio" value="yes" name="mailing">예</label>
                <label class="r"><input type="radio" value="no" name="mailing">아니오</label>
            </li>
        </ul>
        <ul id="buttons">
            <li>
                <input type="button" class="btn btnBlack" value="가입하기">
            </li>
            <li>
                <input type="reset" class="btn btnGray" value="취소">
            </li>
        </ul>
    </form>
</div>
</body>

 

stylesheet
#container{
    width:600px;
    margin:0 auto;
}
ul {
    list-style:none;
}
ul li {
    clear:both;
}
.field {
    float:left;
    width:100px;
    font-weight:bold;
    font-size:0.9em;
    line-height: 55px;
    text-align:right;
    margin-right:15px;
}
input[type="text"], input[type="password"], input[type="email"] {
    float:left;
    width:350px;
    height:35px;
    border:1px solid #aaa;
    border-radius:5px;
    padding:5px;
    margin:10px 0;
    float:left;
}

.r {
    line-height:55px;
}

#buttons > li {
    display:inline-block;
}
input[type="button"], input[type="reset"] {
    width:250px;
    height:50px;
    margin-right:10px;
    border:1px solid #ccc;
    background:#eee;
    font-size:0.9em;
}

 


 

script 코드 작성

 회원가입 페이지 입력 값 검증하기
         1. [가입하기] 버튼을 클릭하면 아이디 글자 수 확인하기

         2. 비밀번호 확인하기
           1) 비밀번호 필드에 입력한 내용의 글자 수가 8자리 이상인지 확인
           2) 비밀번호 확인 필드에 입력한 값이 비밀번호의 필드 값과 같은지 확인

         3. 비밀번호 패스워드 변환 <-> 문자 변환
<head>
    <link rel="stylesheet" href="css/register.css">
    <script>
        
        document.addEventListener('DOMContentLoaded', function () {
            const frmRegister = document.getElementById('register'); // 폼태그
            const btnSubmit = document.querySelector('.btnBlack'); // 가입 버튼
            const userName = document.getElementById('user-id'); // id태그
            const pw1 = document.querySelector('#user-pw1'); // 비밀번호1 필드
            const pw2 = document.querySelector('#user-pw2'); // 비밀번호2 필드

            btnSubmit.addEventListener('click', function () {
             // 가입하기 버튼 클릭했을 때
                if (userName.value.length > 15 || userName.value.length < 4) {
                    alert('4~15자리로 입력하세요.'); // 오류 메시지 출력

                    /*
                    select() : 사용자가 기존에 입력한 값을 선택
                    focus() : 사용자가 기존에 입력한 값을 지우고 새로운 값을 입력하도록 텍스트 필드에 커서를 가져다 놓음.
                     */
                    userName.select();
                    return;
                }
                frmRegister.submit();
            });

            pw1.addEventListener('change', function () { 
            // 비번1 입력했을 때 오류 확인
            
                if (pw1.value.length < 8) {
                    alert('비밀번호는 8자리 이상이어야 합니다.'); // 오류 메시지 표시
                    pw1.value='';
                    pw1.focus();
                }
            });

            pw2.addEventListener('change', function () {
             // 비번 2 입력했을 때 오류 확인
             
                if (pw1.value !== pw2.value) {
                    alert('암호가 다릅니다. 다시 입력하세요.'); // 오류 메시지 표시
                    pw2.value = '';
                    pw2.focus();
                }
            });

            const btnTrans = document.querySelector('span.trans'); 
            // 비밀번호 문자열 변환 태그
            
            btnTrans.addEventListener('click', function (e) {

                if (pw1.getAttribute('type') === 'password') {
                    pw1.setAttribute('type', 'text');
                    e.currentTarget.textContent = '패스워드로 변환';

                } else {
                    pw1.setAttribute('type', 'password');
                    e.currentTarget.textContent = '문자로 변환';
                }

            });
        });
    </script>
</head>

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]


1.  주문서

 

body 태그
<body>
<!-- 배송 정보 자동으로 입력하기 1 -->
<div id="container">
    <form name="order">
        <fieldset>
            <legend> 주문 정보</legend>
            <ul>
                <li>
                    <label class="field" for="billingName">이름 : </label>
                    <input type="text" class="input-box" id="billingName" name="billingName">
                </li>
                <li>
                    <label class="field" for="billingTel">연락처 : </label>
                    <input type="text" class="input-box" id="billingTel" name="billingTel">
                </li>
                <li>
                    <label class="field" for="billingAddr">주소 : </label>
                    <input type="text" class="input-box" id="billingAddr" name="billingAddr">
                </li>
            </ul>
        </fieldset>
    </form>
    <form name="shipping">
        <fieldset>
            <legend> 배송 정보</legend>
            <ul>
                <li>
                    <input type="checkbox" id="shippingInfo" name="shippingInfo">
                    <label class="check">주문 정보와 배송 정보가 같습니다</label>
                </li>
                <li>
                    <label class="field" for="shippingName">이름 : </label>
                    <input type="text" class="input-box" id="shippingName" name="shippingName">
                </li>
                <li>
                    <label class="field" for="shippingTel">연락처 : </label>
                    <input type="text" class="input-box" id="shippingTel" name="shippingTel">
                </li>
                <li>
                    <label class="field" for="shippingAddr">주소 : </label>
                    <input type="text" class="input-box" id="shippingAddr" name="shippingAddr">
                </li>
            </ul>
        </fieldset>
    </form>
    <button type="submit" class="order">결제하기</button>

</div>
</body>

 

order.css
* {
    margin:0;
    padding:0;
    box-sizing: border-box;
}
ul {
    list-style: none;
}
legend {
    font-size:1.2em;
    font-weight:bold;
    margin-left:20px;
}

form {
    width:520px;
    height:auto;
    padding-left:10px;
    margin:50px auto;
}
fieldset {
    border:1px solid #c0c0c0;
    padding:30px 20px 30px 30px;
    margin-bottom:35px;
}

.field {
    float:left;
    width:60px;
    font-weight:bold;
    font-size:0.9em;
    line-height: 55px;
    text-align:right;
    margin-right:15px;
}

.input-box {
    width:350px;
    height:35px;
    border:1px solid #aaa;
    border-radius:5px;
    padding:5px;
    margin:10px 0;
    float:left;
}

.order {
    width:100%;
    padding:20px;
    border:1px solid #aaa;
    background:#e9e9e9;
    font-size:1em;
    font-weight:bold;
}

 

stylesheet와 body 요소만 적용했을 때


'주문 정보와 배송 정보가 같습니다' 클릭 시 주문 정보 가지고 오고, 클릭 해제시 정보 지우는 코드
<head>
    <link rel="stylesheet" href="css/order.css">
    <script>
  
        document.addEventListener('DOMContentLoaded', function () {
            const check = document.querySelector('#shippingInfo'); 
            // 체크박스의 id는 shippingInfo

            check.addEventListener('click', function () { 
            // check 요소에 click 이벤트가 발생했을 때 실행할 함수
            
                if (this.checked) { // 체크 되었을 때
                    document.querySelector('#shippingName').value = document.getElementById('billingName').value;
                    document.querySelector('#shippingTel').value = document.getElementById('billingTel').value;
                    document.querySelector('#shippingAddr').value = document.getElementById('billingAddr').value;
                } else { // 체크 해제되었을 때 배송정보 지움
                    document.querySelector('#shippingName').value = "";
                    document.querySelector('#shippingTel').value = "";
                    document.querySelector('#shippingAddr').value = "";
                }

            });
        });
    </script>
</head>

 


💡  폼 요소 접근 방법 3가지 

    1. id 값이나 class 값을 사용해 폼 요소에 접근하기
        👾  id 값이나 class 값을 사용해 폼 요소에 접근하는 방법은 DOM의 다른 요소에 접근하는 것과 같음
        👾  querySelector() 함수나 querySelectorAll() 함수를 사용
        👾  텍스트 필드에 있는 값을 가져오기 위해서는 텍스트 필드에 접근하는 소스 뒤에 value 속성을 붙임
console.log(document.getElementById('billingName').value)
console.log(document.querySelector('[name=billingName]').value);

    2. name 값을 사용해 폼 요소에 접근하기
       👾  폼 요소에 id나 class 속성이 없고 name 속성만 있는 경우 name 식별자를 사용해 폼 요소에 접근
       👾  이 방법을 사용하려면 <form> 태그에 name 속성이 지정되어 있어야 하고,
             <form> 태그안에 포함된 폼 요소에도 name 속성이 있어야
       👾  폼 안에 있는 텍스트 필드에 접근하려면 <form>의 name 값과 텍스트 필드의 name 값을 사용
       👾  submit시에 input의 name은 서버로 전송. 하지만 form의 name은 서버로 전송되지 않음
console.log(document.order.billingName.value);

    3. 폼 배열을 사용해 폼 요소에 접근하기
        👾  document의 속성 중 forms 속성은 문서 안에 있는 <form> 태그를 모두 가져와 배열 형태로 반환
        👾  이 방법은 폼 요소에 id나 class 속성도 없고 name 속성도 없을 때 유용
        👾  <form> 태그 안에 포함된 요소에 접근하려면 elements 속성을 사용
                 ➡️  해당 폼 안에 있는 모든 폼 요소를 가져오는 속성, 인덱스 번호로 접근
console.log(document.forms[0].elements[1].value);

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]


1.  자료형 변환

🐝  코틀린에서는 자료형이 다른 변수에 재할당하면 자동 형 변환이 되지 않고 자료형 불일치 오류 Type Mismatch 발생
        ➡️  의도하지 않게 자료형이 변하는 것을 방지하기 위한 것

fun main() {
    val a: Int = 1
    // val b: Double = a // 자료형 불일치 오류 발생. 자바와 차이점.
    // val c: Int = 1.1 // 자료형 불일치 오류 발생
}

 

    🍯  변수 a는 Int 형이므로 Double 형 변수 b에 다시 할당할 수 없음
    🍯  만일 자료형을 변환해 할당하고 싶다면 코틀린에서는 자료형 변환 메서드를 이용
            ex. Int ▶️ Double :  toDouble() 메서드를 이용

fun main() {
    val b: Double = a.toDouble()
    println("a=$a, b=$b") // a = 1, b = 1.0
}

자료형이 서로 다른 값을 연산하면, 자료형이 표현할 수 있는 범위가 큰 자료형으로 자동 형변환하여 연산
fun main() {

    val result = b + a
    println("result = $result") // result = 2.0

}

 


2.  기본형과 참조형의 비교 원리

🐝   자료형을 비교할 때는 단순히 값만 비교하는 방법 vs 참조 주소까지 비교하는 방법
🐝   단순히 값만 비교할 때는 이중 등호(==)를 사용하고, 참조 주소를 비교하려면 삼중 등호(===)를 사용

이중 등호는 참조와 상관없이 값이 동일하면 true를, 값이 다르면 false를 반환
삼중 등호값과 상관없이 참조가 동일하면 true를 반환, 값이 동일하더라도 참조 주소가 다르면 false를 반환

 

다음은 Int 형으로 선언한 변수 a, b에 128을 대입하고 이중 등호와 삼중 등호로 비교한 것
    비교 결과는 모두 true. 이 때 참조형으로 선언된 a와 b는 코틀린 컴파일러가 기본형으로 변환하여 저장
    즉, 여기서는 삼중 등호가 비교하는 값도 저장된 값인 128.
fun main() {

    val a: Int = 128
    val b: Int = 128
    println(a == b) // true
    println(a === b) // true

}

참조 주소가 달라지는 경우는 null을 허용한 변수
    null을 허용한 변수는 같은 값을 저장해도 이중 등호와 삼중 등호를 사용한 결과값이 다름 
fun main() {  

    val c: Int? = 128
    val d: Int? = 128
    println(c == d) // true
    println(c === d)  // false
    
}

3.  스마트 캐스트 알아보기

🐝  만약 어떤 값이 정수일 수도 있고, 실수일 수도 있는 경우에는 그때마다 자료형을 변환해도 되지만
     '스마트 캐스트'를 사용할 수 있음
🐝  스마트 캐스트 Smart Cast컴파일러가 자동으로 형 변환

    ⚡️  대표적으로 스마트 캐스트가 적용되는 자료형은 Number형이 있음
    ⚡️  Number형을 사용하면 숫자를 저장하기 위한 특수한 자료형 객체를 만듦
    ⚡️  Number형으로 정의된 변수에는 저장되는 값에 따라 정수형이나 실수형 등으로 자료형이 변환됨

fun main() {

    var test: Number = 12.2 // 12.2에 의해 test는 Float형으로 스마트 캐스트
    println("$test") // 12.2

    test = 12 // Int 형으로 스마트 캐스트
    println("$test") // 12

    test = 120L // Long형으로 스마트 캐스트
    println("$test") // 120

    test += 12.0f // Float형으로 스마트 캐스트
    println("$test") // 132.0
    
}

4.  자료형 검사하기

🐝  변수의 자료형을 알아낼떄는 is 키워드를 사용
🐝   is는 왼쪽 항의 변수가 오른쪽 항의 자료형과 같으면 true를, 아니면 false를 반환
🐝   is는 변수의 자료형을 검사한 다음 그 변수를 해당 자료형으로 변환하는 기능도 있음

   

    ⚡️ Any형을 사용하면 자료형을 결정하지 않은 채로 변수를 선언할 수 있음
    ⚡️ Any형은 코틀린의 최상위 기본 클래스로 어떤 자료형이라도 될 수 있는 특수한 자료형
    ⚡️ 이때 is를 사용하여 자료형을 검사하면 검사한 자료형으로 스마트 캐스트

fun main() {

    var num = 256

    if (num is Int) { // num의 자료형이 Int라면 실행.
        println(num) // 256
    } else if (num !is Int) {
        println("No an Int")
    }

    val x: Any
    x = "Hello"
    if (x is String) {
        println(x.length) // 5
    }
    /*
    변수 x는 Any형으로 선언. 그 후에 "Hello"라는 값을 대입. 아직 x의 자료형은 Any형.
    이후 if문으로 is로 x의 자료형을 검사할 때 String으로 스마트 캐스트되어 조건문이 실행.
     */

}

 


5.  묵시적 형변환

🐝  코틀린의 모든 클래스는 Any형이라는 슈퍼클래스(Superclass)를 가짐
🐝  Any는 자바의 최상위 클래스인 Object와 비슷하지만 서로 다른 유형
🐝  Any 형은 무엇이든 될 수 있기 때문에 언제든 필요한 자료형으로 자동변환할 수 있음
        ➡️  이것을 묵시적 변환이라고 함

fun main() {

    var a: Any = 1  // Any형 a는 1로 초기화 될 때 Int형이 됨.
    a = "one" // Int형이었던 a는 변경된 값에 의해 String이 됨.
    println("a: $a type: ${a.javaClass}") // 자바의 기본형을 출력하면 String이 나옴
    // 띄어씌기가 있으면 중괄호 생략 가능
    // a: one type: class java.lang.String

    checkArg("Hello") // x is String: Hello
    checkArg(5) // x is Int: 5
}

fun checkArg(x: Any) { // 인자를 Any형으로 받음
    if (x is String) {
        println("x is String: $x")
    }

    if (x is Int) {
        println("x is Int: $x")
    }

}

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]


1.  키보드 이벤트

이벤트 설명
keydown 키가 눌릴 때 실행. 키보드를 꾹 누르고 있을 때도, 입력될 때도 실행
keypress 키가 입력되었을 때 실행. 공백이 들어가기 전까지 글자수를 세지 x
웹 브라우저에 따라서 아시아권의 문자를 제대로 처리 못하는 문제가 있음
keyup 키보드에서 키가 떨어질 때 실행

 

<head>
    <script>
        // 남은 글자수 출력하기
        document.addEventListener('DOMContentLoaded', () => {
            const textarea = document.querySelector('textarea');
            const h1 = document.querySelector('h1');

            textarea.addEventListener('keyup', () => { // 키보드에서 키가 떨어질 때 실행
                // value 속성으로 입력양식(form 태그)의 글자(문자열)을 읽을 수 있음.
                const length = textarea.value.length
                h1.textContent = `글자 수: ${length}`;
            })

            textarea.focus();
        });
    </script>
</head>
<body>
    <h1>글자 수: 0</h1>
    <textarea></textarea>
</body>


2.  키보드 키 코드 사용하기

키보드 이벤트 관련 속성
이벤트 속성 이름 설명
code 입력한 키
keyCode 입력한 키를 나타내는 숫자
altKey Alt 키를 눌렀는지
ctrlKey Ctrl 키를 눌렀는지
shiftKey Shift 키를 눌렀는지 


   👩🏻‍💻  code 속성은 입력한 키를 나타내는 문자열이 들어있고
         altKey, ctrlKey, shiftKey 속성은 해당 키를 눌렀는지 불 자료형이 들어 있음

<head>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const h1 = document.querySelector('h1');
            const print = (event) => {
                let output = '';
                output += `alt: ${event.altKey}<br>`; 
                // 이벤트가 발생하면 불 값을 반환
                output += `ctrl: ${event.ctrlKey}<br>`;
                output += `shift: ${event.shiftKey}<br>`;
                // event.code가 있으면 event.code를 출력하고, 
                // undefined라면 event.keyCode를 출력
                output += `code: ${typeof(event.code) !== 'undefined' ? 
                                   event.code : event.keyCode}<br>`;
                h1.innerHTML = output;
            }

            document.addEventListener('keydown', print); // 키가 눌릴 때 출력
            document.addEventListener('keyup', print); // 키가 떨어질 때 출력
        });
    </script>
</head>
<body>
    <h1></h1>
</body>

 


keyCode 속성 활용 

 

    keyCode 속성은 입력한 키를 숫자로 나타냄. 37, 38, 39, 40이 방향키 왼쪽, 위, 오른쪽, 아래를 나타냄

<head>
    <script>       
        document.addEventListener('DOMContentLoaded', () => {
            // 별의 초기 설정
            const star = document.querySelector('h1');
            star.style.position = 'absolute'; // style 속성을 조작하여 position 값을 설정
            star.style.transitionDuration = '1s';

            // 별의 이동을 출력하는 기능
            let [x, y] = [5, 5];
            const block = 20;
            const print = () => {
                star.style.left = `${x * block}px`;
                star.style.top = `${y * block}px`;
            }
            print();

            // 별을 이동하는 기능
            const [left, up, right, down] = [37, 38, 39, 40]; // 방향키 keyCode를 쉽게 사용하기 위해 변수를 사용해 이름을 붙임.
            document.body.addEventListener('keydown', (event) => { // 키보드 눌릴 때 실행

                switch (event.keyCode) {
                    case left:
                        x -= 1;
                        break;
                    case up:
                        y -= 1;
                        break;
                    case right:
                        x += 1;
                        break;
                    case down:
                        y += 1;
                        break;
                }
                print();
            })

            const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'];
            const size = [10, 20, 30, 40, 50];
            let index = 0;
            setInterval(() => {
                star.style.color= colors[index++ % colors.length];
                star.style.fontSize = String(size[index++ % size.length]) + 'px'
            }, 500)

        });
    </script>
</head>
<body>
    <h1>★</h1>
</body>

 


3.  이벤트 발생 객체

(1) 이벤트 리스너를 외부로 빼낸 경우

<script>
const listener = (event) => {
    const length = textarea.value.length
    h1.textContent = `글자 수: ${length}`
}

document.addEventListener('DOMContentLoaded', () => { // 외부로 분리
    const textarea = document.querySelector('textarea')
    const h1 = document.querySelector('h1')
    textarea.addEventListener('keyup', listener)
})    
</script>

 

  👩🏻‍💻  코드의 규모가 커지면 위와 같이 이벤트 리스너를 외부로 분리하는 경우가 많아짐

 

이벤트를 발생시킨 객체에 접근하는 방법

 

    📌  event.currentTarget 속성을 사용

         - () => {} 와 function () {} 형태 모두 사용 가능

    📌  this 키워드를 사용

         - 화살표 함수가 아닌 function () {} 형태로 함수를 선언한 경우에 사용

 

currentTarget 속성 사용
<script>
const listener = (event) => {
    const length = event.currentTarget.value.length
    // event.currentTarget이 textarea
    h1.textContent = `글자 수: ${length}`
}

document.addEventListener('DOMContentLoaded', () => { // 외부로 분리
    const textarea = document.querySelector('textarea')
    const h1 = document.querySelector('h1')
    textarea.addEventListener('keyup', listener)
})    
</script>

 

this 키워드 사용
<script>
const listener = function (event) {
    const length = this.value.length
    // this가 textarea
    h1.textContent = `글자 수: ${length}`
}

document.addEventListener('DOMContentLoaded', () => { // 외부로 분리
    const textarea = document.querySelector('textarea')
    const h1 = document.querySelector('h1')
    textarea.addEventListener('keyup', listener)
})    
</script>

 


 

(2) 글자 입력 양식 이벤트

 

  👩🏻‍💻  입력 양식 form : 사용자로부터 어떠한 입력을 받을 때 사용하는 요소

            ex. input, textarea, button, select

 

입력 양식을 기반으로 inch를 cm 단위로 변환하는 프로그램
<head>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const input = document.querySelector('input');
            const btn = document.querySelector('button');
            const p = document.querySelector('p');

            btn.addEventListener('click', () => {
               const inch = Number(input.value); // 입력한 값을 숫자로 변환.

                if (isNaN(inch)) { // 숫자가 아니라면 바로 리턴. isNaN()함수 : 숫자인지 확인. not a number
                    p.textContent = '숫자를 입력해주세요.';
                    return;
                }
               // 변환해서 출력
               const cm = inch * 2.54;
               p.textContent = `${cm}cm`;
            });
        });
    </script>
</head>
<body>
    <input type="text">inch<br>
    <button>계산</button>
    <p></p>
</body>

 


 

이메일 형식 확인하기
<head>
    <script>

        document.addEventListener('DOMContentLoaded', () => {
           const input = document.querySelector('input');
           const p = document.querySelector('p');

           const isEmail = (value) => { // 이메일인지 검사하는 함수
               // 골뱅이를 갖고 있고 && 골뱅이 뒤에 점이 있다면
               return (value.indexOf('@' > 1) && (value.split('@')[1].indexOf('.') > 1));
           };

           input.addEventListener('keyup', function (event) {
               const value = event.currentTarget.value;
               // const value = input.value; 가능
               // console.log(value);

               if (isEmail(value)) {
                   p.style.color = 'green';
                   p.textContent = `이메일 형식입니다: ${value}`;
               }
               else {
                   p.style.color = 'red';
                   p.textContent = `이메일 형식이 아닙니다: ${value}`;
               }
           });
        });
    </script>
</head>
<body>
    <input type="text">
    <p></p>
</body>

 

 

[ 내용참고 : IT 학원 강의 및 책 '혼자 공부하는 자바스크립트' ]

+ Recent posts