<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>보근은 참고 있다</title>
    <link>https://hoooooooooooooop.tistory.com/</link>
    <description>후우우우우우우우웁!</description>
    <language>ko</language>
    <pubDate>Sun, 12 Apr 2026 14:13:07 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>보근</managingEditor>
    <item>
      <title>함수 호출과 this</title>
      <link>https://hoooooooooooooop.tistory.com/entry/%ED%95%A8%EC%88%98-%ED%98%B8%EC%B6%9C%EA%B3%BC-this</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JS의 함수 호출은 C/C++ 등의 엄격한 문법 체크를 하는 언어들과 달리 자유롭다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;arguments 객체&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JS는 함수를 호출할 때 함수 형식에 맞춰 인자를 넘기지 않더라도, 에러가 발생하지 않는다.&lt;/p&gt;
&lt;pre id=&quot;code_1629340505361&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function f(arg1, arg2) {
    console.log(arg1, arg2);
}

f();		// undefined undefined
f(1);		// 1 undefined
f(1, 2);	// 1 2
f(1, 2, 3);	// 1 2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수에 정의된 파라미터가 들어오지 않으면 그냥 undefined로 할당해버린다. 반대로 함수에 정의된 인자의 개수보다 더 많은 인자가 들어오면 오류를 내지 않고 그 인자 값을 버려버린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작동이 멈추는 걸 최소화 하기 위한 JS의 특성 때문에 이런식으로 동작을 하지만, 런타임 시에 호출된 인자의 개수를 확인하고 그것에 따라 동작을 다르게 해줘야하는 경우도 있을 수 있다. 그것을 위한 것이 arguments 객체이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;arguments 객체는 함수가 호출될 때, 인수들과 함께 암묵적으로 같이 내부로 전달된다. arguments 객체는 함수를 호출할 때 같이 넘기는 인자들을 배열 형태로 저장한 객체이다. 하지만 실제 배열이 아닌 유사 배열 객치이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629340948216&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function add(arg1, arg2) {
	console.dir(arguments);
    
    return arg1 + arg2;
}

console.log(add());
console.log(add(1));
console.log(add(1, 2));
console.log(add(1, 2, 3));


// result

[Arguments] {}
NaN
[Arguments] { '0': 1 }
NaN
[Arguments] { '0': 1, '1': 2 }
3
[Arguments] { '0': 1, '1': 2, '2': 3 }
3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인자가 제대로 들어가지 않은 함수 호출들은 undefined로 산술 연산을 하려고 했기 때문에 NaN가 뜬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;260&quot; data-origin-height=&quot;106&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bU6Wn8/btrcACs1Roi/hOfy1ztNK3AQF2perTIS30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bU6Wn8/btrcACs1Roi/hOfy1ztNK3AQF2perTIS30/img.png&quot; data-alt=&quot;add();&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bU6Wn8/btrcACs1Roi/hOfy1ztNK3AQF2perTIS30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbU6Wn8%2FbtrcACs1Roi%2FhOfy1ztNK3AQF2perTIS30%2Fimg.png&quot; data-origin-width=&quot;260&quot; data-origin-height=&quot;106&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;add();&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;262&quot; data-origin-height=&quot;115&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZenG6/btrcByYa6lg/2AjF5zVlhWjsvV0Jj4FSU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZenG6/btrcByYa6lg/2AjF5zVlhWjsvV0Jj4FSU0/img.png&quot; data-alt=&quot;add(1);&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZenG6/btrcByYa6lg/2AjF5zVlhWjsvV0Jj4FSU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZenG6%2FbtrcByYa6lg%2F2AjF5zVlhWjsvV0Jj4FSU0%2Fimg.png&quot; data-origin-width=&quot;262&quot; data-origin-height=&quot;115&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;add(1);&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;260&quot; data-origin-height=&quot;134&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8be2M/btrcvw1W0Cc/DdUKZ7nCCn2K4TkGxGsahk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8be2M/btrcvw1W0Cc/DdUKZ7nCCn2K4TkGxGsahk/img.png&quot; data-alt=&quot;add(1, 2);&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8be2M/btrcvw1W0Cc/DdUKZ7nCCn2K4TkGxGsahk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8be2M%2Fbtrcvw1W0Cc%2FDdUKZ7nCCn2K4TkGxGsahk%2Fimg.png&quot; data-origin-width=&quot;260&quot; data-origin-height=&quot;134&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;add(1, 2);&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;261&quot; data-origin-height=&quot;145&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KS2Kh/btrcB3RqyCB/adU3cEuDYsk2b9BZPU31J0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KS2Kh/btrcB3RqyCB/adU3cEuDYsk2b9BZPU31J0/img.png&quot; data-alt=&quot;add(1, 2, 3);&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KS2Kh/btrcB3RqyCB/adU3cEuDYsk2b9BZPU31J0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKS2Kh%2FbtrcB3RqyCB%2FadU3cEuDYsk2b9BZPU31J0%2Fimg.png&quot; data-origin-width=&quot;261&quot; data-origin-height=&quot;145&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;add(1, 2, 3);&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호출 시에 넘긴 인자들을 배열 형태로 저장하고, 그 개수를 length에 저장한다. callee는 현재 실행중인 함수의 참조값이다. 여기서는 당연하게 add(a, b) 함수를 참조하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;arguments 객체는 전달 받은 인자의 개수에 따라 다르게 동작해야 하거나, 매개변수의 개수가 정확히 정해지지 않은 함수를 구현할 때에 사용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1629342189963&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function sum() {
	var result = 0;
    
    for(var i = 0 ; i &amp;lt; arguments.length ; i++) {
    	result += arguments[i];
	}
    
    return result;
}

console.log(sum(1, 2, 3));			// 6
console.log(sum(1, 2, 3, 4, 5, 6, 7, 8, 9));	// 45&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;this 객체&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수가 호출될 때 앞서말한 arguments 객체 외에도 this 객체가 함수 내부로 암묵적으로 전달된다. this는 헷갈릴 수도 있는게 함수가 호출되는 방식에 따라서 this가 다른 객체를 참조하기도 한다. 그래서 함수 호출 패턴과 해당 패턴에 따라 this가 어떤 객체에 바인딩이 되는지를 잘 알아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메서드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체의 프로퍼티로 들어간 함수를 메서드라고 한다. 메서드의 this는 해당 메서드를 호출한 객체로 바인딩된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629350326780&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var myObj = {
    name: 'foo',
    sayName: function () {
        console.log(this.name);
    }
};

var otherObj = {
    name: 'bar'
};

otherObj.sayName = myObj.sayName;

myObj.sayName();		// 'foo'
otherObj.sayName();		// 'bar'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메서드에서의 this는 메서드를 프로퍼티로 갖고 있는 객체를 가리킨다. 따라서 myObj와 otherObj 두 객체가 각각의 프로퍼티인 name을 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 otherObj가 name이란 프로퍼티를 갖고 있지 않다면, undefined가 출력된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;전역 객체&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전역 객체는 전역 범위에 항상 존재하는 객체를 말한다. 브라우저에서 자바스크립트를 실행하는 경우는 window 객체가 전역 객체가 된다. node.js 환경에서는 global 객체가 전역 객체가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;js에서 전역 변수는 전역 객체의 프로퍼티들이다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629353413741&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var foo = 'I`m foo';		// 전역 변수 선언

console.log(foo);		// I`m foo
console.log(window.foo);	// I`m foo&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수에서의 this는 전역 객체에 바인딩된다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629353732112&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var test = 'Test!!!!!!!!!!!!';
console.log(window.test);		// 'Test!!!!!!!!!!!!'

var sayFoo = function () {
    console.log(this.test);		// 'Test!!!!!!!!!!!!'
};

sayFoo();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내부 함수에서도 this 객체가 전역 객체에 바인딩된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629355037495&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var val = 100;

var obj = {
    val: 1,
    func1: function () {
    	console.log(`func1 this.val = ${this.val}`);
    	console.log(`func1 val = ${val}`);
        
        func2: function () {
        	console.log(`func2 this.val = ${this.val}`);
        	console.log(`func2 val = ${val}`);
            
            func3: function () {
            	console.log(`func3 this.val = ${this.val}`);
            	console.log(`func3 val = ${val}`);
            }
            
            func3();
        }
        
        func2();
    }
}

obj.func1();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;142&quot; data-origin-height=&quot;140&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3KOCy/btrcAcvbvPn/XQX13ILCkqw3QbVNpGHtKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3KOCy/btrcAcvbvPn/XQX13ILCkqw3QbVNpGHtKK/img.png&quot; data-alt=&quot;결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3KOCy/btrcAcvbvPn/XQX13ILCkqw3QbVNpGHtKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3KOCy%2FbtrcAcvbvPn%2FXQX13ILCkqw3QbVNpGHtKK%2Fimg.png&quot; data-origin-width=&quot;142&quot; data-origin-height=&quot;140&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;js는 내부 함수 호출 패턴을 정의해 놓지 않는다. 그렇기 때문에, 얘네를 메서드 취급하지 않고 그냥 함수로 취급하여 전역 객체에 바인딩된다. 객체의 내부에 있기 때문에, 내부 함수의 this가 객체에 바인딩 되었다고 착각할 수 있기 때문에 이 부분은 유의한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 만약 내부 함수가 메서드처럼 부모 객체를 참조하길 원한다면, 메서드의 this를 다른 변수에 저장해 참조하는 방법이 있다. this를 저장하는 다른 변수는 관례상 이름을 that으로 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1629361619151&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var val = 100;

var obj = {
    val: 1,
    
    func1: function () {
        var that = this;
    
        console.log('func1 this.val = ' + this.val);

        func2 = function () {
            console.log('func2 that.val = ' + that.val);

            func3 = function () {
                console.log('func3 that.val = ' + that.val);
            };

            func3();
        };

        func2();
    }
};

obj.func1();

// result

func1 this.val = 1
func2 that.val = 1
func3 that.val = 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 방법은 JS에서 제공하는 call과 apply 메서드 등이 있다. 이건 뒤에 나온다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자 함수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JS에서 생성자 함수는 Java와 다르게 기존 함수에 new 연산자를 붙여서 호출하면 해당 함수가 생성자 함수로 동작한다. 일반 함수와 구분하기 위해 관례상 생성자 함수로 정의된 함수는 맨 첫 글자를 대문자로 쓰도록 되어있다. 생성자 함수에서 this를 이해하려면 먼저 생성자 함수의 동작 방식을 이해해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;빈 객체 생성 및 this 바인딩
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생성자 함수가 새로 생성할 객체를 위해 먼저 빈 객체를 하나 만든다.&lt;/li&gt;
&lt;li&gt;this는 이 빈 객체를 바인딩한다.&lt;/li&gt;
&lt;li&gt;새로 생성된 객체는 자신을 생성한 생성자 함수의 prototype 프로퍼티가 가ㄹ키니는 객체를 자신의 프로토타입 객체로 설정한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;this를 통한 프로퍼티 생성
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;this를 통해 빈 객체에 동적으로 프로퍼티나 메서드를 생성한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;생성된 객체 리턴
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;return문이 없다면, this로 바인딩된 새로 생성된 객체가 반환된다. (return this; 와 같다.)&lt;/li&gt;
&lt;li&gt;return문이 있다면, return문이 반환하는 객체가 반환된다. (새로 생성된 객체가 아닐 수도 있다.)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1629362613669&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var Person = function (name) {
	this.name = name;
};

var p = new Person('bogeun');
console.log(p.name);		// 'bogeun'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 생성자 함수에 new를 붙이지 않고 사용하면 어떻게 될까? 결과는 원하는대로 동작해주지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629371159773&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var Person = function (name) {
	this.name = name;
};

var p = Person('bogeun');

console.log(p);			// undefined
console.log(window.name);	// bogeun&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;new 연산자가 붙어야 this가 새로 생성되는 객체에 바인딩되고 또, 리턴문을 따로 명시하지 않아도 this를 리턴 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 그냥 함수로 인식이 되어서 this가 전역 객체인 window에 바인딩 되었고, 따로 리턴 값이 없었기 때문에 p는 undfined로 name 프로퍼티는 애먼 전역 객체에 붙어버렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;new 연산자를 붙이든 붙이지 않든 똑같이 동작하기 위해 이러한 패턴을 쓰기도 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1629372508154&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function A(arg) {
    if(!(this instanceof arguments.callee)) {
        return new A(arg);
    }

    this.value = arg ? arg : 0;
}

var a = new A(100);
var b = A(10);
var c = new A();

console.log(a);		//	100
console.log(b);		//	10
console.log(c);		//	0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;this가 함수의 인스턴스인지 확인을 통해 new 연산자를 썼는지 그냥 호출했는지를 확인하고 그에 맞게 동작하도록 하여서 사용할 때 어떻게 사용해도 결과가 같게끔 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;call과 apply를 이용한 명시적 this 바인딩&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지는 js엔진이 자동으로 this를 바인딩하는 것을 봤다. 하지만, 이러한 내부적인 this 바인딩 외에도 this를 특정 객체에 명시적으로 바인딩 시키는 방법도 있다. call과 apply 메서드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;call과 apply는 Function.prototype 객체의 메서드이므로, 모든 함수는 call과 apply를 통해 명시적인 this 바인딩이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;apply 메서드는 인자를 2개 받는다. 첫 번째 인자는 this에 바인딩 할 객체를 넣고, 두 번째 인자는 원래 함수의 인자를 배열 형태로 넣어준다.&lt;/p&gt;
&lt;pre id=&quot;code_1629422215540&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function Person(name, age, gender) {
    this.name = name;
    this.age = age;
    this.gender = gender;
}

var person1 = {};
var person2 = {};

person1 = Person('bogeun1', 20, 'male');		// this가 전역 객체에 바인딩됨.
Person.apply(person2, ['bogeun2', 21, 'female']);	// this가 person2 객체에 바인딩 됨.

console.log(person1);		// undefined
console.log(window.name);	// 'bogeun1'
console.log(window.age);	// 20
console.log(window.gender);	// 'male'

console.log(person2);		// {name: 'bogeun2', age: 21, gender: 'female'}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;apply 메서드나 new 연산자를 쓰지 않은 person1 객체는 리턴을 아무 것도 받지 못하기 때문에 undefined가 들어갔고, this 객체는 전역 객체에 바인딩 되었기 때문에 전역 변수가 되어버렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면에, apply 메서드를 쓴 person2는 this 객체가 새로 생성되는 객체에 바인딩 되었기 때문에, 원하는 대로 결과가 나왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;call은 apply랑 똑같은 기능을 한다. 차이가 있다면, apply는 인자들을 배열 형태로 한 번에 보냈고, call은 인자들을 하나하나 보낸다.&lt;/p&gt;
&lt;pre id=&quot;code_1629435681468&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function Person(name, age, gender) {
    this.name = name;
    this.age = age;
    this.gender = gender;
}

var person = {};

Person.call(person, 'bogeun', 22, 'male');	// this가 person 객체에 바인딩 됨.

console.log(person);		// {name: 'bogeun', age: 22, gender: 'male'}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;apply와 call을 이용하면 유사 배열 객체도 배열처럼 사용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1629438319794&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function func() {
	console.log(arguments);		// [Arguments] {'0': 1, '1': 2, '2': 3}
    
    var args = Array.prototype.slice.apply(arguments);
    
    console.log(args);			// [1, 2, 3]
}

func(1, 2, 3);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Array.prototype의 slice 메서드의 this 객체가 유사 배열 객체인 arguments에 바인딩 시킨다. 이러면 유사 배열 객체가 배열인 것 마냥 배열의 메서드를 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;함수 리턴&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JS의 함수는 항상 리턴 값을 반환한다. return 문이 명시되어 있지 않더라도, 어떠한 규칙을 통해 리턴 값을 전달한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;일반 함수나 메서드는 리턴 값을 지정하지 않을 경우, undefined 값이 리턴된다.&lt;/li&gt;
&lt;li&gt;생성자 함수에서 리턴 값을 지정하지 않을 경우, 새로 생성된 객체가 리턴된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1629438858912&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var noReturnFunction = function () {
	// 명시된 return이 없으니 undefined가 리턴됨.
}

var NoReturnConstructor = function () {
	this.name = 'name';
	this.age = 'age';
    
	// 명시된 return이 없으니 생성된 객체가 리턴됨.
}

var YesReturnConstructor = function () {
	this.name = 'name';
	this.age = 'age';
    
	return {name: 'hello', age: 20};	// 명시된 return이 있으니 얘가 리턴됨.
}

var result1 = noReturnFunction();
var result2 = new NoReturnConstructor();
var result3 = new YesReturnConstructor();

console.log(result1);		// undefined
console.log(result2);		// {name: 'name', age: 'age'}
console.log(result3);		// {name: 'hello', age: 20}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Language/JS</category>
      <author>보근</author>
      <guid isPermaLink="true">https://hoooooooooooooop.tistory.com/76</guid>
      <comments>https://hoooooooooooooop.tistory.com/entry/%ED%95%A8%EC%88%98-%ED%98%B8%EC%B6%9C%EA%B3%BC-this#entry76comment</comments>
      <pubDate>Fri, 20 Aug 2021 15:00:45 +0900</pubDate>
    </item>
    <item>
      <title>JS의 함수</title>
      <link>https://hoooooooooooooop.tistory.com/entry/JS%EC%9D%98-%ED%95%A8%EC%88%98</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;함수의 생성&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;함수 선언문&lt;/li&gt;
&lt;li&gt;함수 표현식&lt;/li&gt;
&lt;li&gt;Function() 생성자 함수&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629112859253&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//함수 선언문
function add1(x, y) {
    return x + y;
}

//함수 표현식
var add2 = function (x, y) {
    return x + y;
};

// Function 생성자 함수
var add3 = new Function('x', 'y', 'return x + y');

console.log(add1(1, 2));	// 3
console.log(add2(1, 2));	// 3
console.log(add3(1, 2));	// 3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 세 가지 방법으로 생성한 함수는 모두 똑같이 동작해서 같은 결과를 보여주지만, 동작 방식의 차이가 있다. 그중 하나가 &lt;b&gt;함수의 호이스팅(Function Hoisting)&lt;/b&gt;이다. 호이스팅이란, 코드가 실행되기 전에 메모리에 값을 저장해두는 것을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629113228108&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;add(1, 2)	// 3

function add(x, y) {
	return x + y;
}

add(2, 3)	// 5&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;위의 예제에서 보면, 위의 add()는 add가 함수로 정의되는 코드 전에 있지만, 실행이 잘 된다. 아래의 add() 역시 마찬가지이다. 함수 선언문으로 함수를 선언하면 이렇게 호이스팅이 일어난다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629113391117&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;add(1, 2)	// error

var add = function(x, y) {
	return x + y;
}

add(2, 3)	// 5&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 예제에서는 함수 표현식으로 함수를 선언했기 때문에 호이스팅이 일어나지 않아서 에러가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;객체로써의 함수&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JS에서는 함수도 객체이다. 기본 기능인 코드 실행뿐만 아니라, 프로퍼티를 가질 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1629182611754&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function add(x, y) {
    return x + y;
}

add.result = add(3, 2);	// result 프로퍼티 추가
add.status = &quot;OK&quot;;		// status 프로퍼티 추가

console.dir(add6);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;216&quot; data-origin-height=&quot;129&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXYAbb/btrcs9qQiaJ/KCnnFwTaEKWC6mvzx9Tm0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXYAbb/btrcs9qQiaJ/KCnnFwTaEKWC6mvzx9Tm0K/img.png&quot; data-alt=&quot;console.dir(add6)의 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXYAbb/btrcs9qQiaJ/KCnnFwTaEKWC6mvzx9Tm0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXYAbb%2Fbtrcs9qQiaJ%2FKCnnFwTaEKWC6mvzx9Tm0K%2Fimg.png&quot; data-origin-width=&quot;216&quot; data-origin-height=&quot;129&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;console.dir(add6)의 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JS에서 함수는 &lt;b&gt;일급 객체&lt;/b&gt;이다. Java와 달리 함수가 인자, 배열의 요소, 리턴 값 등 함수도 일반 객체가 들어갈 수 있는 자리에는 다 들어갈 수 있다는 뜻이다. 이러한 특성으로 함수형 프로그래밍이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리터럴에 의한 생성&lt;/li&gt;
&lt;li&gt;변수나 배열의 요소, 객체의 프로퍼티 등에 할당 가능&lt;/li&gt;
&lt;li&gt;함수의 인자로 전달 가능&lt;/li&gt;
&lt;li&gt;함수의 리턴 값으로 리턴 가능&lt;/li&gt;
&lt;li&gt;동적으로 프로퍼티를 생성 및 할당 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;함수의 프로퍼티&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ECMA5 명세서에는 모든 함수가 &lt;b&gt;length&lt;/b&gt;와 &lt;b&gt;prototype&lt;/b&gt; 프로퍼티를 가져야 한다고 기술되어 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;236&quot; data-origin-height=&quot;232&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KmaJ9/btrclIOCp93/xt6rtC6auICxAFyRYWnpP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KmaJ9/btrclIOCp93/xt6rtC6auICxAFyRYWnpP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KmaJ9/btrclIOCp93/xt6rtC6auICxAFyRYWnpP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKmaJ9%2FbtrclIOCp93%2Fxt6rtC6auICxAFyRYWnpP0%2Fimg.png&quot; data-origin-width=&quot;236&quot; data-origin-height=&quot;232&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;name 프로퍼티는 함수의 이름을 나타낸다. 익명 함수는 빈 문자열이 들어간다.&lt;/li&gt;
&lt;li&gt;caller 프로퍼티는 자신을 호출한 함수를 나타낸다. 여기서는 null이고, 이 프로퍼티는 deprecated.&lt;/li&gt;
&lt;li&gt;arguments 프로퍼티는 함수를 호출할 때 전달된 인자 값을 나타낸다. 여기서는 호출되지 않은 상태이기 때문에 null이고, 얘도 deprecated.&lt;/li&gt;
&lt;li&gt;[[Prototype]] 프로퍼티는 객체 자신의 프로토타입을 가리킨다. __prototype__을 쓰기도 하는데 그냥 같은 표현이라고 생각하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 함수들의 프로토타입은 Function.prototype이다. 그렇다면 Function.prototype의 프로토타입은 무엇일까? Function.prototype은 함수이지만, Object.prototype을 프로토타입으로 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수에서 length 프로퍼티는 함수의 파라미터의 개수이다.&lt;/p&gt;
&lt;pre id=&quot;code_1629186696567&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function func0() {

}

function func1(x) {

}

function func2(x, y) {

}

function func3(x, y, z) {

}

console.log(func0.length);	// 0
console.log(func1.length);	// 1
console.log(func2.length);	// 2
console.log(func3.length);	// 3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 객체가 가지는 프로토타입 [[Prototype]]&lt;/li&gt;
&lt;li data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;모든 함수 객체가 가지는 prototype&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;위의 두 프로퍼티들은 프로토타입 객체를 가리킨다는 점에서 공통점이 있지만, 약간의 차이가 있다. [[Prototype]]은 객체 입장에서 자신의 부모 역할을 하는 프로토타입 객체를 가리키고, prototype은 이 함수가 생성자로 사용될 때 이 함수를 통해 생성된 객체의 부모 역할을 하는 프로토타입 객체를 가리킨다. 뭔 말인지 1도 모르겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;prototype 프로퍼티는 함수가 생성될 때 만들어지며, constructor 프로퍼티만을 가지는 객체를 가리킨다. constructor 프로퍼티는 다시 함수 객체를 가리킨다. 서로가 서로를 참조하는 모양이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;JS에서는 함수를 생성할 때, 함수 자신과 연결된 프로토타입 객체를 동시에 생성한다. 그리고 두 객체는 서로 prototype과 constructor 프로퍼티들로 서로를 참조한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;302&quot; data-origin-height=&quot;330&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OGXLS/btrcusjMYOQ/dzVlu4KeHPTJyZKPNS47S0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OGXLS/btrcusjMYOQ/dzVlu4KeHPTJyZKPNS47S0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OGXLS/btrcusjMYOQ/dzVlu4KeHPTJyZKPNS47S0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOGXLS%2FbtrcusjMYOQ%2FdzVlu4KeHPTJyZKPNS47S0%2Fimg.png&quot; data-origin-width=&quot;302&quot; data-origin-height=&quot;330&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;여러 종류의 함수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;콜백 함수&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;콜백 함수란 명시적으로 코드를 기입해 호출하는 것이 아닌, 함수를 등록해두고 어떤 이벤트가 발생하거나, 특정 시점에 도달했을 때 호출되는 함수를 말한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629252231003&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
	window.onload = function() {
		alert('Call Back Function!!!!!!!!!!!!');
	};
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;페이지 로드 시에 콜백 함수가 호출되어 메시지가 출력된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉시 실행 함수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수의 정의와 동시에 바로 실행하는 함수를 즉시 실행 함수라고 한다. 익명 함수를 통해 구현하며, 최초의 한 번 호출 뒤에 재호출이 불가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629269753566&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(function (name) {
	console.log(name);
})('bogeun');

((name, age) =&amp;gt; {
	console.log(name, age);
})('bogeun', 21);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;익명 함수를 소괄호로 감싸고 뒤에 소괄호로 파라미터를 넘겨주는 모양으로 즉시 실행 함수를 작성한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉시 실행 함수는 jQuery같은 라이브러리를 사용할 때 많이 사용하는데, 이는 JS의 함수 유효 범위 특성 때문이다. 함수 외부에서 함수 내부의 변수들에 접근할 수 없기 때문에, 라이브러리 코드를 추가해도 변수 이름 충돌 등이 일어나지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내부 함수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JS는 함수 코드 내부에서 또 함수를 정의할 수 있는데, 내부에 정의된 함수를 내부 함수라고 한다. 내부 함수는 클로저를 생성하거나 부모 함수 코드에서 외부에서의 접근을 막고 독립적인 헬퍼 함수를 구현하는 용도 등으로 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629272446937&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function parent() {
	var a = 100;
	var b = 200;
    
    function child() {
    	var b = 300;
        
        console.log(a);		// 100
        console.log(b);		// 300
    }
    
    child();
}

parent();
child();		// error&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;child 함수는 parent의 변수에 접근이 가능한 것을 볼 수 있다. 이 것은 JS의 스코프 체이닝 때문에 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, parent 함수 밖에서 child 함수가 호출되지 않는 것을 알 수 있다. 내부 함수는 일반적으로 자신이 정의된 부모 함수 내부에서만 호출 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 부모 함수에서 내부 함수를 외부로 리턴하면, 부모 함수 밖에서도 내부 함수를 호출하는 것이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629272879676&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function parent() {
	var a = 100;
    
    function child() {
        console.log(a);
    }
    
    return child;
}

var inner = parent();
inner();		// 100;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;inner가 parent()를 통해 child 함수 객체를 리턴 받았다. inner를 호출하면, parent 함수 내부의 child 함수가 호출이 되고, child에는 a라는 변수가 없으니 스코프 체이닝으로 parent에서 정의된 a 변수를 출력하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 실행이 끝난 parent() 같은 부모 함수 스코프의 변수를 참조하는 inner() 같은 함수를 &lt;b&gt;클로저&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수를 리턴하는 함수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JS에서 함수는 일급 객체이기 때문에, 리턴 값으로 사용할 수 있다. 이러한 특성을 통해 다양한 활용이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1629273353931&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var self = function () {
	console.log('a');
    
	return function () {
		console.log('b');
	}
}

self = self();	// a
self();		// b&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 self()가 호출되었을 때는 a를 찍는 함수가 실행이 되고, 그 리턴 값으로 b를 찍는 함수를 받았기 때문에, 그 다음의 호출에는 b가 찍힌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Language/JS</category>
      <author>보근</author>
      <guid isPermaLink="true">https://hoooooooooooooop.tistory.com/73</guid>
      <comments>https://hoooooooooooooop.tistory.com/entry/JS%EC%9D%98-%ED%95%A8%EC%88%98#entry73comment</comments>
      <pubDate>Mon, 16 Aug 2021 20:48:15 +0900</pubDate>
    </item>
    <item>
      <title>JS의 배열</title>
      <link>https://hoooooooooooooop.tistory.com/entry/JS%EC%9D%98-%EB%B0%B0%EC%97%B4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열은 특별한 형태의 객체이다. C나 Java의 배열과 기능은 비슷하지만, 크기가 가변적이며, 어떤 위치에 어떤 데이터 타입을 저장해도 에러가 생기지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;배열의 생성&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;배열 리터럴&lt;br /&gt;객체의 중괄호처럼 배열의 리터럴은 대괄호 ( [ ] )를 이용하여 생성한다.&lt;/li&gt;
&lt;li&gt;생성자 함수&lt;br /&gt;new Array() 생성자 함수를 통해서 배열을 생성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628230839837&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var array1 = new Array();			// 빈 배열 생성.

console.log(array1);				// []
console.log(array1.length);			// 0

var array2 = new Array(3);			// 길이가 3인 빈 배열 생성.

console.log(array2);				// [undefined, undefined, undefined]
console.log(array2.length);			// 3

var array3 = new Array(1, 2, 3);	// 1, 2, 3이 차례대로 들어간 배열 생성.

console.log(array3);				// [1, 2, 3]
console.log(array3.length);			// 3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자 함수를 통해 배열을 만드는 예시.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1628145938762&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var array1 = [];							// 빈 배열을 생성.
var array2 = [1, &quot;2&quot;, {value: 3}, [4]];		// 4개의 요소가 담긴 배열 생성.

console.log(array1.length);					// 배열의 길이는 0.

array1[0] = 1;
array1[1] = &quot;2&quot;;
array1[2] = {value: 3};
array1[3] = [4];

console.log(array1[0]);						// 1
console.log(array1[1]);						// &quot;2&quot;
console.log(array1[2]);						// {value: 3}
console.log(array1[3]);						// [4]
console.log(array2[0]);						// 1
console.log(array2[1]);						// &quot;2&quot;
console.log(array2[2]);						// {value: 3}
console.log(array2[3]);						// [4]

console.log(array1.length);					// 배열의 길이 4.

array1[9] = 0;								// 9번 인덱스에 요소를 추가.

console.log(array1.length);					// 배열의 길이 10.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 예제에서 볼 수 있듯이, 배열도 객체처럼 요소를 동적으로 추가할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, 배열의 프로퍼티 중에 length가 있는데 이 값은 배열의 길이를 나타내는 값이다. 위의 예시처럼 9번 인덱스에 값을 추가하면 배열의 length가 10이 된다. 값을 할당받지 못한 배열의 인덱스는 당연히 undefined로 값이 표시된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1628146510193&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var array = [1, 2, 3];	// array.length = 3

array[5] = 0;			// array.length = 6

// 배열의 값을 undefined로.
array[5] = undefined;	// array.length = 6

// 배열의 length 값을 3으로.
array[5] = 0;
array.length = 3;		// array.length = 3

console.log(array[5]);	// undefined&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이거는 호기심에 해본 건데 배열의 길이보다 큰 인덱스에 값을 할당하는 것이 배열의 길이를 변경시켰는데, 마지막 인덱스 값을 undefined로 해도 배열의 길이는 변하지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로, 배열의 길이를 줄이니 길이보다 큰 배열의 값들은 다 없어져 버렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;배열과 객체&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열은 객체이지만, 그냥 일반 객체와는 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1628228913940&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var array = [ 'red', 'green', 'blue'];
var object = {
    '0': 'red',
    '1': 'green',
    '2': 'blue'
};

console.log(array[0]);		// red
console.log(array[1]);		// green
console.log(array[2]);		// blue

console.log(object[0]);		// red
console.log(object[1]);		// green
console.log(object[2]);		// blue

console.log(typeof array);	// object
console.log(typeof object);	// object

console.log(array.length);	// 3
console.log(object.length);	// undefined&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열 array와 일반 객체 object를 같은 모양으로 만들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체의 프로퍼티에 대괄호로 접근할 경우 프로퍼티 이름을 문자열로 기입하여야 하지만, 숫자의 경우 엔진이 자동으로 문자열로 바꿔주기 때문에 둘이 같은 모양으로 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열 역시 객체이기 때문에 typeof 연산자를 사용하면 object라는 결과를 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 일반 객체인 object는 배열의 프로퍼티를 사용할 수 없다는 다른점이 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;313&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GonbK/btrbrU2IKEU/ZCdvE12vQCycT9KWIk0rQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GonbK/btrbrU2IKEU/ZCdvE12vQCycT9KWIk0rQ0/img.png&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp;https://codedragon.tistory.com/5714&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GonbK/btrbrU2IKEU/ZCdvE12vQCycT9KWIk0rQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGonbK%2FbtrbrU2IKEU%2FZCdvE12vQCycT9KWIk0rQ0%2Fimg.png&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;313&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;nbsp;https://codedragon.tistory.com/5714&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 그림은 일반 객체와 배열 객체의 프로토타입을 보여준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1628229340535&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;console.dir(array.__proto__);				// Array
console.dir(object.__proto__);				// Object
console.dir(array.__proto__.__proto__);			// Object

console.log(object.__proto__ === array.__proto__.__proto__);	// true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 예시로 위위 그림을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;배열의 프로퍼티&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열도 객체이므로 인덱스로 접근하는 배열 요소 외에도 프로퍼티를 가질 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1628229667434&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var array = ['one', 'two', 'three'];

console.log(array.length);		// 3

array.one = 1;					// 배열의 프로퍼티 동적 생성

console.log(array.one);			// 1
console.log(array.length);		// 3 length 값이 변하지 않음

array[3] = 2;					// 배열의 요소 추가

console.log(array[3]);			// 2
console.log(array.length);		// 4 length 값이 변함&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;console.dir()를 통해서 추가된 프로퍼티 one을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열도 객체니까 for in문을 사용할 수 있는데, 위의 예시처럼 프로퍼티를 갖고 있는 배열 객체라면 요소와 그 프로퍼티의 값들도 반환될 것이다. 배열 요소만을 출력하고 싶다면, 그냥 for문을 쓰면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1628230013887&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var array = ['one', 'two', 'three'];
array.hello = 'haha';
array.bye = 'baba';

for(var property in array) {
    console.log(array[property]);
}

console.log('----------------------');

for(var i = 0 ; i &amp;lt; array.length ; i++) {
    console.log(array[i]);
}


// result

one
two
three
haha
baba
----------------------
one
two
three&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;배열 요소의 삭제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열도 객체이기 때문에, delete 연산자를 사용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1628230186308&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var array = ['one', 'two', 'three'];

console.log(array.length);	// 3

delete array[2];			// 3번째 요소를 delete

console.log(array[2]);		// undefined
console.log(array.length);	// 3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열의 마지막 요소를 delete 했지만, 마지막 요소가 undefined가 됐을 뿐 length가 줄어들지는 않았다. 배열의 메서드들은 length 값으로 동작하는 경우가 많기 때문에, 마지막 요소가 없어진 것처럼 배열이 동작하길 원할 때는 배열의 메서드인 splice()를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1628230548152&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var array = ['one', 'two', 'three', 'four'];

array.splice(2, 1);			// 배열의 2번 인덱스부터 1개 삭제
console.log(array);			// ['one', 'two', 'four']
console.log(array.length);		// 3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;유사 배열 객체&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열의 메서드들은 대부분 length를 이용해 동작하는 경우가 많기 때문에, 배열의 length 프로퍼티는 매우 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JS에서 일반 객체에 length 프로퍼티를 추가한 것을 유사 배열 객체라고 한다. 이 것의 특별한 점은 일반 객체임에도 불구하고, 배열의 표준 메서드를 사용할 수 있다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1628231493887&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var array = ['one', 'two'];
var object = {
    name: 'bogeun',
    age: 20,
    length: 3
}

array.push('three');			// 배열 요소에 'three' 추가
console.log(array);				// ['one', 'two', 'three']
console.log(array.length);		// 3

// object.push('hello');		// 에러 뜸.

console.log(object);			// {name: 'bogeun', age: 20, length: 3}
Array.prototype.push.apply(object, ['hello']);		// apply()
console.log(object);			// {'3': 'hello', name: 'bogeun', age: 20, length: 4}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 배열 메서드를 사용하려고 하면 object에는 push라는 메서드가 없다고 에러가 뜬다. 하지만 apply()를 사용하면 length에 따라 3번 인덱스에 요소가 추가되고, length가 3에서 4로 값이 변한다. 배열의 push() 메서드를 정확히 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Language/JS</category>
      <author>보근</author>
      <guid isPermaLink="true">https://hoooooooooooooop.tistory.com/70</guid>
      <comments>https://hoooooooooooooop.tistory.com/entry/JS%EC%9D%98-%EB%B0%B0%EC%97%B4#entry70comment</comments>
      <pubDate>Fri, 6 Aug 2021 16:35:39 +0900</pubDate>
    </item>
    <item>
      <title>JS 데이터 타입과 연산자</title>
      <link>https://hoooooooooooooop.tistory.com/entry/JS-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85%EA%B3%BC-%EC%97%B0%EC%82%B0%EC%9E%90</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;441&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dLvyGT/btraWvRuUkl/VQwnb5s9Z0ACjmRR1Jnbwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dLvyGT/btraWvRuUkl/VQwnb5s9Z0ACjmRR1Jnbwk/img.png&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp;https://kimtaehyun98.tistory.com/58&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dLvyGT/btraWvRuUkl/VQwnb5s9Z0ACjmRR1Jnbwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdLvyGT%2FbtraWvRuUkl%2FVQwnb5s9Z0ACjmRR1Jnbwk%2Fimg.png&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;441&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;nbsp;https://kimtaehyun98.tistory.com/58&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JS는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;동적 타입 체크&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;언어로, 변수를 선언할 때 타입을 따로 지정하지 않으며,&lt;span&gt;&amp;nbsp;&lt;/span&gt;런타임 시점에 변수의 타입이 결정된다. 또, 런타임 시점에 동적으로 변수의 타입이 변경이 가능하기 때문에 변수의 타입을 다른 것으로 변경할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기본 타입&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 타입의 변수들은 그 자체가 하나의 값을 나타낸다. JS에서는 이 기본 타입들만이 유일하게 객체(Object)가 아니지만, 기본 타입에서 숫자, 문자열, 불린은 객체로 사용할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;숫자&lt;/b&gt;&lt;br /&gt;JS에서 정수와 실수 모두를 Number로 표현한다. JS에서는 숫자를 64비트 부동 소수점 형태로 저장하기 때문에, 정수와 실수를 모두 표현할 수 있다.&lt;br /&gt;소수점 아래에 값이 없으면 정수처럼 표기를 하고, 소수점 아래에 값이 있으면 소수처럼 표기를 해준다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;문자열&lt;/b&gt;&lt;br /&gt;문자열은 큰 따옴표와 작은 따옴표로 생성할 수 있다. 둘은 용도와 기능이 그냥 똑같다. Backtick도 있는데, 기능이 좀 다르다.&lt;br /&gt;C나 Java와 다르게 JS는 char형 변수가 없다. 따라서 'a'는 그냥 String이다.&lt;br /&gt;JS의 문자열은 문자 배열처럼 인덱스를 통해 접근할 수도 있고 또, charAt() 메서드로 접근할 수도 있다. 단, JS의 String도 immutable 하기 때문에, 인덱스를 통해 값을 변경한다거나 할 수는 없다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;null&lt;/b&gt;과 &lt;b&gt;undefined&lt;br /&gt;&lt;/b&gt;두 타입 모두 '값이 비어있음'을 나타낸다. 값이 할당되지 않은 변수의 경우 undefined 타입이고, null의 경우는 명시적으로 비어있음을 나타내는 경우 사용된다.&lt;br /&gt;undefined는 타입도 값도 undefined이다.&amp;nbsp;&lt;br /&gt;null은 값은 null이지만, 타입은 object이다. 때문에, 어떤 변수가 null인지 확인하고 싶을 때는 typeof를 사용하면 안된다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1628063408921&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var intNum = 10.00;
var floatNum = 0.1;

var singleQuoteStr = 'single quote string';
var doubleQuoteStr = &quot;double quote string&quot;;
var singleChar = 'a';

var boolTrue = true;
var boolFalse = false;

var emptyVar;

var nullVar = null;


console.log(
    typeof intNum,          // number
    typeof floatNum,        // number
    typeof singleQuoteStr,  // string
    typeof doubleQuoteStr,  // string
    typeof singleChar,      // string
    typeof boolTrue,        // boolean
    typeof boolFalse,       // boolean
    typeof emptyVar,        // undefined
    typeof nullVar          // object
);

console.log(
    emptyVar === undefined  // true
);

console.log(
    nullVar === null,       // true
    typeof nullVar === null // false
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참조 타입&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 기본 타입을 제외한 모든 값은 객체이며, 참조 타입이다. JS에서는 배열, 함수, 정규표현식 등을 모두 객체로 표현한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체는 기본 타입과 달리 여러 개의 프로퍼티를 가질 수 있다. 그 프로퍼티는 기본 자료형의 변수, 객체, 함수 등이 모두 올 수 있다. 객체의 프로퍼티인 함수를 메서드라고 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JS에서 객체를 생성하는 방법은 세 가지가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- new Object()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 객체 리터럴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 생성자 함수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 리터럴은 중괄호( { } )를 이용하여 객체를 생성한다. 중괄호 안에 '프로퍼티 이름 : 프로퍼티 값' 형태로 표기하여 프로퍼티를 추가할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1628063227847&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var o1 = new Object();		// new Object()
var o2 = {};			// 빈 객체 리터럴
var o3 = {			// 프로퍼티가 들어간 객체 리터럴
    name: &quot;Bogeun3&quot;,
    age: 22,
    isMale: true
};

// 빈 객체에 프로퍼티를 추가함.
o1.name = &quot;Bogeun1&quot;;	
o1.age = 20;
o1.isMale = true;

// 빈 객체에 프로퍼티를 추가함.
o2.name = &quot;Bogeun2&quot;;
o2.age = 21;
o2.isMale = false;

console.log(o1);		// { name: 'Bogeun1', age: 20, isMale: true }
console.log(o2);		// { name: 'Bogeun2', age: 21, isMale: false }
console.log(o3);		// { name: 'Bogeun3', age: 22, isMale: true }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프로퍼티&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JS의 객체는 프로퍼티의 생성, 읽기, 수정, 삭제 등이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체의 프로퍼티에 접근하는 방법은 두 가지가 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 대괄호 표기법 ( [ ] )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 마침표 표기법 ( . )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1628063152836&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var bk = {
    name: &quot;Bogeun&quot;,
    age: 20
};

// 프로퍼티 값 읽기.
console.log(bk.name);               // &quot;Bogeun&quot;
console.log(bk['age']);             // 20
console.log(bk.hahaha);             // undefined

// 프로퍼티 값의 수정.
bk.name = &quot;BMK&quot;;
console.log(bk.name);               // &quot;BMK&quot;
console.log(bk['name']);            // &quot;BMK&quot;

// 새로운 프로퍼티를 추가.
bk.hahaha = &quot;hahaha&quot;;
console.log(bk.hahaha);             // &quot;hahaha&quot;
console.log(bk['hahaha']);          // &quot;hahaha&quot;

// 프로퍼티를 삭제.
delete bk.hahaha;
console.log(bk.hahaha);             // undefined


// 대괄호 표기법으로만 접근할 수 있는 프로퍼티 이름.
bk[&quot;full-name&quot;] = &quot;Bogeun Park&quot;;
console.log(bk['full-name'])        // &quot;Bogeun Park&quot;
console.log(bk.full-name)           // NaN&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NaN은 Not a Number라는 뜻으로, 수치 연산을 해서 정상적인 값을 얻지 못할 때 출력되는 값이다. 위의 예시에서 NaN가 출력된 이유는, full-name의 대시 표시가 마이너스 연산자로 인식돼서 수치 연산으로 인식하여 나온 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체의 프로퍼티를 지우는 delete 연산자는 프로퍼티만을 지울 수 있다. 객체 자체를 지우려고 시도해봤자 지워지지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for in 문을 사용하면, 객체의 모든 프로퍼티에 대해 루프를 수행할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1628063969034&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var bk = {
    name: &quot;Bogeun&quot;,
    age: 20,
    isMale: true
};

for(property in bk) {
    console.log(property, bk[property]);
};

// name Bogeun
// age 20
// isMale true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for in 문의 property 변수는 string 타입으로 프로퍼티의 이름을 가진다. 그 이름을 갖고 객체의 프로퍼티 값에 접근하여 출력하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Language/JS</category>
      <author>보근</author>
      <guid isPermaLink="true">https://hoooooooooooooop.tistory.com/68</guid>
      <comments>https://hoooooooooooooop.tistory.com/entry/JS-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85%EA%B3%BC-%EC%97%B0%EC%82%B0%EC%9E%90#entry68comment</comments>
      <pubDate>Wed, 4 Aug 2021 17:16:47 +0900</pubDate>
    </item>
    <item>
      <title>자바의 Upcasting과 Downcasting</title>
      <link>https://hoooooooooooooop.tistory.com/entry/UpcastingDowncasting</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Upcasting은 하위 클래스의 오브젝트를 상위 클래스 타입으로 선언하는 것이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하위 클래스들은 상위 클래스의 속성들을 상속받기 때문에 상위 클래스의 멤버 변수나 메소드에 접근할 수 있다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;그렇기 때문에 Upcasting은 따로 명시를 하지 않는 &lt;b&gt;암묵적인 형변환&lt;/b&gt;을 &lt;b&gt;허용한다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Downcasting은 상위 클래스의 오브젝트를 하위 클래스 타입으로 선언하는 것이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상위 클래스들은 하위 클래스의 속성들을 상속받지 않을 수도 있기 때문에 멤버 변수나 메소드에 접근할 수 없다.&lt;/li&gt;
&lt;li&gt;그렇기 때문에 Downcasting은 &lt;b&gt;암묵적인 형변환&lt;/b&gt;이 &lt;b&gt;허용되지 않는다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1626584438049&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Parent p = new Child();           //  Upcasting으로 Child 인스턴스가 Parent 타입으로 선언됨.
Child c = (Child) p;              //  Downcasting으로 Child 타입으로 선언됨.

System.out.println(p.pMember);    //  정상 출력.
System.out.println(c.pMember);    //  정상 출력.
System.out.println(c.cMember);    //  정상 출력.
System.out.println(p.cMember);    //  컴파일 에러.

System.out.println((Child p).cMember); // 정상출력.

p.pMethod();                      //  정상 동작.
c.pMethod();                      //  정상 동작.
c.cMethod();                      //  정상 동작.
p.cMethod();                      //  컴파일 에러.

(Child p).cMethod();              //  정상 동작.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 예시를 보면, Child 인스턴스를 갖고 있는 Parent 객체를 다시 Child 타입으로 Downcasting이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1626584564426&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Parent p = new Parent();
Child c = (Child) p;            //  ClassCastException 발생.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Downcasting이 가능한 조건이 아니라면 예외가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1626584754654&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Parent p = new Child(&quot;Hello&quot;, 10);
Child c = (Child) p;

System.out.println(p.pMember);      //  Hello 출력.
System.out.println(c.pMember);      //  Hello 출력.
System.out.println(c.cMember);      //  10 출력.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 인스턴스를 참조하기 때문에 당연하게도, 위와 같은 결과가 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Language/자바</category>
      <author>보근</author>
      <guid isPermaLink="true">https://hoooooooooooooop.tistory.com/55</guid>
      <comments>https://hoooooooooooooop.tistory.com/entry/UpcastingDowncasting#entry55comment</comments>
      <pubDate>Sun, 18 Jul 2021 14:07:29 +0900</pubDate>
    </item>
    <item>
      <title>String  vs  StringBuilder  vs  StringBuffer</title>
      <link>https://hoooooooooooooop.tistory.com/entry/StringStringBuilderStringBuffer</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;String&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바에서 문자열을 나타내기 위한 클래스이다. 자바의 String은 특별한 취급을 받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 문자열 선언&lt;/p&gt;
&lt;pre id=&quot;code_1626518501177&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String s1 = &quot;abc&quot;;
String s2 = new String(&quot;abc&quot;);

s1 = &quot;abcd&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바의 참조 타입은 new 연산자를 통해 초기화하는 것이 원칙이지만, String은 위처럼 바로 문자열을 넣어 초기화할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;String은 immutable하기 때문에 아래처럼 s1 객체에 &quot;abcd&quot;를 할당해주면 기존의 &quot;abc&quot;가 변하는 것이 아닌, 새로운 인스턴스 &quot;abcd&quot;를 만들어 할당해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 주소값 할당&lt;/p&gt;
&lt;pre id=&quot;code_1626518670639&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String s = &quot;a&quot;;

String s1 = &quot;a&quot;;
String s2 = new String(&quot;a&quot;);
String s3 = String.valueOf('a');

System.out.println(s == s1);        // true
System.out.println(s == s2);        // false
System.out.println(s == s3);        // false

System.out.println(s.equals(s1));   // true
System.out.println(s.equals(s2));   // true
System.out.println(s.equals(s3));   // true

System.out.println(s == &quot;a&quot;);                                     // true
System.out.println(new String(&quot;a&quot;) == new String(&quot;a&quot;));           // false
System.out.println(String.valueOf('a') == String.valueOf('a'));   // false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바에서 String을 선언하면 일단 메모리에서 해당 문자열이 있는지 찾아보고, 만약 있다면 해당 주소값을 참조하게 된다. 위의 코드로 예를 들어보면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. s를 &quot;a&quot;로 초기화할 때, 메모리에 &quot;a&quot;를 먼저 찾아본다. =&amp;gt; 없기 때문에 새로 만들어 할당해준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. s1을 &quot;a&quot;로 초기화할 때, 메모리에 &quot;a를 먼저 찾아본다. =&amp;gt; 있기 때문에 그것을 참조한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. s2는 new 연산자로 초기화 해주었다. =&amp;gt; 새로운 인스턴스가 할당된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. s3는 valueOf()로 인자를 String으로 캐스팅 해주었다. =&amp;gt; 새로운 인스턴스가 할당된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 예시에서 보이듯이, new 연산자를 사용하거나, valueOf()를 사용하면 새로운 인스턴스가 만들어 지기 때문에 비교 연산자를 사용하면 서로 다른 것으로 취급한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 더하기 연산&lt;/p&gt;
&lt;pre id=&quot;code_1626519531643&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String s = &quot;a&quot;;
s += &quot;b&quot;;
s += 'c';
s += 1;

System.out.println(s);  //  abc1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바는 String에도 더하기 연산을 사용할 수 있는데, 문자열을 합쳐준다. 또 문자열이 아닌 primitive 타입을 문자열과 더하기 연산을 하면, 문자열로 바꾸어 더해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 문자열끼리 더하기 연산을 하면, 기존 문자열들은 메모리에 남아있고 새로운 문자열들이 메모리에 올라가게 된다. 위의 코드로 예를 들어보면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &quot;a&quot;가 메모리에 올라간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &quot;b&quot;와 &quot;ab&quot;가 메모리에 올라간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. &quot;abc&quot;가 메모리에 올라간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. &quot;abc1&quot;이 메모리에 올라간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 &quot;abc1&quot; 이 하나의 문자열을 만들기 위해 쓰인 &quot;a&quot;, &quot;b&quot;, &quot;ab&quot;, &quot;abc&quot;, &quot;abc1&quot; 등이 메모리에 올라가게 되고 또, 새로운 인스턴스를 계속 만들어야 하기 때문에, 낭비가 발생하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;jdk9~11 중에서부터 String의 value가 char[]에서 byte[] 타입으로 바뀌어 오버헤드가 많이 줄었다고 하던데, 어쨌든 낭비는 낭비이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;StringBuilder&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문자열을 더 효율적이고 쉽게 관리하게 도와주는 클래스이다. StringBuilder는 String과 달리 mutable하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- append()&lt;/p&gt;
&lt;pre id=&quot;code_1626519922611&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;StringBuilder sb = new StringBuilder(&quot;a&quot;);

sb.append(&quot;b&quot;);
sb.append('c');
sb.append(1);

System.out.println(sb);           //  abc1
System.out.println(sb.toString);  //  abc1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;String의 더하기 연산에서의 문제를 보완하기 위해 StringBuilder는 append() 메소드를 지원한다. String과 달리 append()메소드를 사용하면 기존의 문자열의 값을 변환하는 방식으로 동작하게 되어, 쓸데없는 문자열들이 메모리에 남지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1626523582937&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String s = &quot;&quot;;
StringBuilder sb = new StringBuilder();

long start = System.currentTimeMillis();
for (int i = 0; i &amp;lt; 300000; i++) {
	s += i;
}

System.out.println(System.currentTimeMillis() - start);  // 63454

start = System.currentTimeMillis();
for(int i = 300000 ; i &amp;lt; 600000 ; i++) {
	sb.append(i);
}

System.out.println(System.currentTimeMillis() - start);  // 16&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과는 매번 가변적이겠지만, 매우 큰 처리량에서 차이가 확연히 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;StringBuffer&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;StringBuffer는 synchronized가 붙어있어서 멀티 스레드 환경에서 쓰레드 세이프하게 동작한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1626525044000&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;StringBuilder sb = new StringBuilder();
StringBuffer sf = new StringBuffer();

new Thread(() -&amp;gt; {
  for(int i = 0 ; i &amp;lt; 10000 ; i++) {
  sb.append(1);
  sf.append(1);
  }
}).start();

new Thread(() -&amp;gt; {
  for(int i = 0 ; i &amp;lt; 10000 ; i++) {
  sb.append(1);
  sf.append(1);
  }
}).start();

Thread.sleep(2000L);
System.out.println(sb.length());   // 18854
System.out.println(sf.length());   // 20000&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;StringBuilder는 스레드 세이프하지 못해 정신을 못 차리는 모습,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;StringBuffer는 스레드 세이프하기 때문에 멀쩡한 모습을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Language/자바</category>
      <author>보근</author>
      <guid isPermaLink="true">https://hoooooooooooooop.tistory.com/54</guid>
      <comments>https://hoooooooooooooop.tistory.com/entry/StringStringBuilderStringBuffer#entry54comment</comments>
      <pubDate>Sat, 17 Jul 2021 21:31:53 +0900</pubDate>
    </item>
    <item>
      <title>7주차 과제: 패키지</title>
      <link>https://hoooooooooooooop.tistory.com/entry/javahalle7</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;package 키워드&lt;/li&gt;
&lt;li&gt;import 키워드&lt;/li&gt;
&lt;li&gt;클래스패스&lt;/li&gt;
&lt;li&gt;CLASSPATH 환경변수&lt;/li&gt;
&lt;li&gt;-classpath 옵션&lt;/li&gt;
&lt;li&gt;접근 지시자&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;클래스의 이름&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;클래스의 이름은 두 가지가 있다. 클래스 파일 자체의 이름과 패키지+클래스의 이름인 FQCN(Fully Qualified Class Name)이 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;String 클래스를 예시로 들어보면 java.lang.String이 FQCN이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;같은 이름을 가진 서로 다른 클래스가 있다면, 이렇게 사용해야 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1609298967169&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import mypackage.MyClass;

class Main {
    public static void main(String[] args) {
        MyCalss m1 = new MyClass(); // mypackage.MyClass
        yourpackage.MyClass m2 = new yourpackage.MyClass();  //  yourpackage.MyClass
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;package 키워드&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;패키지란, 클래스나 인터페이스 같은 &lt;span style=&quot;color: #333333;&quot;&gt;(파일의 디렉토리처럼)&lt;/span&gt;참조 타입의 묶음 단위이다.&lt;/li&gt;
&lt;li&gt;패키지로 관련 클래스를 그룹화한다. (java.util, java.lang처럼)&lt;/li&gt;
&lt;li&gt;패키지는 같은 이름의 클래스들을 헷갈리지 않도록 해준다.&lt;/li&gt;
&lt;li&gt;패키지 하위에 존재하는 패키지를 서브 패키지(sub package)라고 한다. (java.util은 java의 서브 패키지)&lt;/li&gt;
&lt;li&gt;package 키워드는 해당 클래스의 패키지를 명명하는 키워드이다.&lt;/li&gt;
&lt;li&gt;package는 소스 코드의 최상단에 기입해야 한다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;패키지의 가장 최상단인 default package는 이름이 없으며, package 키워드로 명시하지 않아도 된다. (하지만 이름이 같은 클래스 등이 헷갈릴 수 있으므로 사용하지 않는 걸 추천한다.)&lt;/li&gt;
&lt;li&gt;패키지에 기입된 것과 실제 클래스들의 디렉토리 구조가 같아야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1609299737443&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package mypackage.my; // A 클래스는 mypackage의 서브 패키지인 my에 위치.
                      // 실제 디렉토리 구조도 이렇게 되어야 한다.
class A {
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;import 키워드&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;패키지로 구분된 클래스나 인터페이스들을 다른 패키지의 클래스에서 사용하기 위해선 해당 클래스의 패키지 정보를 알아야 한다.&lt;/li&gt;
&lt;li&gt;그 패키지 정보는 import 키워드를 통해 기입한다.&lt;/li&gt;
&lt;li&gt;import 키워드는 package 키워드와 클래스 정의 사이에 기입해야 한다.&lt;/li&gt;
&lt;li&gt;import 키워드에는 원하는 클래스나 인터페이스, 원하는 패키지의 모든 클래스와 인터페이스, 원하는 클래스의 스태틱 멤버들을 기입할 수 있다.&lt;/li&gt;
&lt;li&gt;java.lang 패키지의 경우 따로 import 해주지 않아도 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;package.png&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;300&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/be0EWk/btqRXG230jZ/eYLm7ZNkSK39Yt0NYYGL4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/be0EWk/btqRXG230jZ/eYLm7ZNkSK39Yt0NYYGL4K/img.png&quot; data-alt=&quot;대략적인 패키지와 클래스 구조(네모 : 패키지, 동그라미 : 클래스)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/be0EWk/btqRXG230jZ/eYLm7ZNkSK39Yt0NYYGL4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbe0EWk%2FbtqRXG230jZ%2FeYLm7ZNkSK39Yt0NYYGL4K%2Fimg.png&quot; data-filename=&quot;package.png&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;300&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;대략적인 패키지와 클래스 구조(네모 : 패키지, 동그라미 : 클래스)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1609303086656&quot; class=&quot;java&quot; style=&quot;display: block; overflow: auto; padding: 15px; color: #383a42; background: #f6f7f8; font-size: 14px; border-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import my.*; // my의 모든 클래스들을 import
import your.C; // your.C your의 C 클래스만 import

import static static.Static.staticMethod; // static.Static 클래스의 staticMethod()만 import

class Main {
    public static void main(String[] args) {
        A a = new A(); // my.A
        B b = new B(); // my.B  
        C c = new C();
        D d = new D(); // 기본 패키지의 클래스라 import X
        String s = &quot;hello&quot; // java.lang의 클래스들은 자동으로 import
        
        staticMethod(s);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;클래스패스&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클래스패스란, JVM이나 컴파일러가 클래스를 사용할 수 있도록 위치, 경로를 알려주는 매개 변수이다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;세부적인 경로는 각각의 클래스에서 import 키워드로 알려주기 때문에, 클래스패스는 가장 최상단의 디렉토리나 zip, jar 파일을 지정한다.&lt;/li&gt;
&lt;li&gt;JVM이 지정된 클래스패스를 바탕으로 import에 기입된 세부적인 경로를 통해 클래스를 찾는다.&lt;/li&gt;
&lt;li&gt;클래스패스를 지정하는 방법에는 두 가지가 있는데, 하나는 시스템 환경 변수로 설정하는 것과 -classpath(-cp) 옵션을 사용하는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;CLASSPATH 환경 변수&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dNtXDW/btqR1EFtogM/jc53kGNUGt5SUE2N0Nc520/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dNtXDW/btqR1EFtogM/jc53kGNUGt5SUE2N0Nc520/img.png&quot; data-alt=&quot;시스템의 고급 시스템 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dNtXDW/btqR1EFtogM/jc53kGNUGt5SUE2N0Nc520/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdNtXDW%2FbtqR1EFtogM%2Fjc53kGNUGt5SUE2N0Nc520%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;시스템의 고급 시스템 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brPPJH/btqSbaiYkO3/2lu15uWqhAlY805GkoNskK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brPPJH/btqSbaiYkO3/2lu15uWqhAlY805GkoNskK/img.png&quot; data-alt=&quot;고급 탭의 환경 변수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brPPJH/btqSbaiYkO3/2lu15uWqhAlY805GkoNskK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrPPJH%2FbtqSbaiYkO3%2F2lu15uWqhAlY805GkoNskK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;고급 탭의 환경 변수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpN6xe/btqR1D7xP1p/uuE9sWnI8pWQiVX3SSp190/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpN6xe/btqR1D7xP1p/uuE9sWnI8pWQiVX3SSp190/img.png&quot; data-alt=&quot;JAVA_HOME은 자바의 절대 경로&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpN6xe/btqR1D7xP1p/uuE9sWnI8pWQiVX3SSp190/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpN6xe%2FbtqR1D7xP1p%2FuuE9sWnI8pWQiVX3SSp190%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;JAVA_HOME은 자바의 절대 경로&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;-classpath 옵션&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;-classpath 또는 -cp으로 줄여서 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;java -cp &amp;lt;경로&amp;gt; &amp;lt;소스파일&amp;gt;의 모양으로 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;ex)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;package.png&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;300&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/be0EWk/btqRXG230jZ/eYLm7ZNkSK39Yt0NYYGL4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/be0EWk/btqRXG230jZ/eYLm7ZNkSK39Yt0NYYGL4K/img.png&quot; data-alt=&quot;대략적인 패키지와 클래스 구조(네모 : 패키지, 동그라미 : 클래스, / : dev 디렉토리)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/be0EWk/btqRXG230jZ/eYLm7ZNkSK39Yt0NYYGL4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbe0EWk%2FbtqRXG230jZ%2FeYLm7ZNkSK39Yt0NYYGL4K%2Fimg.png&quot; data-filename=&quot;package.png&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;300&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;대략적인 패키지와 클래스 구조(네모 : 패키지, 동그라미 : 클래스, / : dev 디렉토리)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Main 클래스&lt;/p&gt;
&lt;pre id=&quot;code_1609558886930&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import my.*;
import your.C;

class Main {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        C c = new C();
        D d = new D();

        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
        System.out.println(d);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tMVJT/btqSmAuzerv/0CfEndmpxEPYcaWcpqJfi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tMVJT/btqSmAuzerv/0CfEndmpxEPYcaWcpqJfi0/img.png&quot; data-alt=&quot;실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tMVJT/btqSmAuzerv/0CfEndmpxEPYcaWcpqJfi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtMVJT%2FbtqSmAuzerv%2F0CfEndmpxEPYcaWcpqJfi0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;접근 지시자&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자바의 객체 지향 언어로써의 정보 은닉을 위한 기능이다.&lt;/li&gt;
&lt;li&gt;클래스와 멤버 필드나 메서드의 접근을 제어한다.&lt;/li&gt;
&lt;li&gt;그 종류는 4가지가 있다. (public, protected, default, private)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;접근 지시자의 종류&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;public - 모든 곳에서 접근이 가능하다.&lt;/li&gt;
&lt;li&gt;protected - 클래스, 같은 패키지 내에서, 서브 클래스에서 접근이 가능하다.&lt;/li&gt;
&lt;li&gt;default(package-private) - 따로 기입하지 않는다. 클래스, 같은 패키지 내에서만 접근이 가능하다.&lt;/li&gt;
&lt;li&gt;private - 같은 클래스 내에서만 접근이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;같은 클래스 내&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;같은 패키지 내&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;서브 클래스&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;다른 패키지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;public&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;O&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;O&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;O&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;O&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;protected&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;O&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;O&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;O&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;X&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;default&lt;br /&gt;(package-private)&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;O&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;O&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;X&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;X&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;private&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;O&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;X&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;X&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;X&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;참고 : &lt;a href=&quot;https://ko.wikipedia.org/wiki/%ED%81%B4%EB%9E%98%EC%8A%A4%ED%8C%A8%EC%8A%A4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;ko.wikipedia.org/wiki/%ED%81%B4%EB%9E%98%EC%8A%A4%ED%8C%A8%EC%8A%A4&lt;/a&gt;, &lt;a href=&quot;https://idratherbewriting.com/java-access-modifiers/#quick-summary&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;idratherbewriting.com/java-access-modifiers/#quick-summary&lt;/a&gt;, &lt;a href=&quot;https://stackoverflow.com/questions/2396493/what-is-a-classpath-and-how-do-i-set-it&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;stackoverflow.com/questions/2396493/what-is-a-classpath-and-how-do-i-set-it&lt;/a&gt;&lt;/p&gt;</description>
      <category>Language/자바 정리 할래</category>
      <author>보근</author>
      <guid isPermaLink="true">https://hoooooooooooooop.tistory.com/45</guid>
      <comments>https://hoooooooooooooop.tistory.com/entry/javahalle7#entry45comment</comments>
      <pubDate>Wed, 30 Dec 2020 13:43:54 +0900</pubDate>
    </item>
    <item>
      <title>6주차 과제: 상속</title>
      <link>https://hoooooooooooooop.tistory.com/entry/javahalle6</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;자바 상속의 특징&lt;/li&gt;
&lt;li&gt;super 키워드&lt;/li&gt;
&lt;li&gt;메서드 오버 라이딩&lt;/li&gt;
&lt;li&gt;다이내믹 메서드 디스패치 (Dynamic Method Dispatch)&lt;/li&gt;
&lt;li&gt;추상 클래스&lt;/li&gt;
&lt;li&gt;final 키워드&lt;/li&gt;
&lt;li&gt;Object 클래스&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;상속&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;상속이란? 한 클래스가 다른 클래스의 속성들을 획득하는 것. 상속을 통해 자식 클래스는 부모 클래스의 필드와 메서드를 재사용할 수 있다. OOP의 주요 개념이다. 아주 합리적이고 똑똑한 거 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;Single_Inheritance.png&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3Cy7K/btqQKvinOAY/hbRztMnr5DhSwIDdPXii81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3Cy7K/btqQKvinOAY/hbRztMnr5DhSwIDdPXii81/img.png&quot; data-alt=&quot;단일 상속(Single Inheritance)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3Cy7K/btqQKvinOAY/hbRztMnr5DhSwIDdPXii81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3Cy7K%2FbtqQKvinOAY%2FhbRztMnr5DhSwIDdPXii81%2Fimg.png&quot; data-filename=&quot;Single_Inheritance.png&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;단일 상속(Single Inheritance)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;단일 상속 : 한 클래스가 하나의 클래스만을 상속받는다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;Multilevel_Inheritance.png&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;450&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HxiWq/btqQR6WatW8/2degWMzTZG0UedmTmh6H40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HxiWq/btqQR6WatW8/2degWMzTZG0UedmTmh6H40/img.png&quot; data-alt=&quot;다단계 상속(Multilevel Inheritance)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HxiWq/btqQR6WatW8/2degWMzTZG0UedmTmh6H40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHxiWq%2FbtqQR6WatW8%2F2degWMzTZG0UedmTmh6H40%2Fimg.png&quot; data-filename=&quot;Multilevel_Inheritance.png&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;450&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;다단계 상속(Multilevel Inheritance)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다단계 상속 : 클래스가 기본 클래스가 아닌 기본 클래스의 파생 클래스를 상속받는다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;300&quot; data-filename=&quot;Hierarchical_Inheritance.png&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4b1jg/btqQR6WaxO0/KvOxPvzv2pTmKBkllOkjP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4b1jg/btqQR6WaxO0/KvOxPvzv2pTmKBkllOkjP1/img.png&quot; data-alt=&quot;계층적 상속(Hierarchical Inheritance)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4b1jg/btqQR6WaxO0/KvOxPvzv2pTmKBkllOkjP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4b1jg%2FbtqQR6WaxO0%2FKvOxPvzv2pTmKBkllOkjP1%2Fimg.png&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;300&quot; data-filename=&quot;Hierarchical_Inheritance.png&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;계층적 상속(Hierarchical Inheritance)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;계층적 상속 : 한 클래스가 여러 하위 클래스에 상속을 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;Multiple_Inheritance.png&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cb6FL3/btqQJEGEwsd/CUw7jVbWo08PBlSH3qfjN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cb6FL3/btqQJEGEwsd/CUw7jVbWo08PBlSH3qfjN1/img.png&quot; data-alt=&quot;다중 상속(Multiple Inheritance)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cb6FL3/btqQJEGEwsd/CUw7jVbWo08PBlSH3qfjN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcb6FL3%2FbtqQJEGEwsd%2FCUw7jVbWo08PBlSH3qfjN1%2Fimg.png&quot; data-filename=&quot;Multiple_Inheritance.png&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;300&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;다중 상속(Multiple Inheritance)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다중 상속 : 한 클래스가 여러 개의 클래스를 상속받는다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;450&quot; data-filename=&quot;Hyprid_Inheritance.png&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzOfmY/btqQNqOorWO/RIqFk1KR1v86KSfXWupRnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzOfmY/btqQNqOorWO/RIqFk1KR1v86KSfXWupRnK/img.png&quot; data-alt=&quot;하이브리드 상속(Hybrid Inheritance)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzOfmY/btqQNqOorWO/RIqFk1KR1v86KSfXWupRnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzOfmY%2FbtqQNqOorWO%2FRIqFk1KR1v86KSfXWupRnK%2Fimg.png&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;450&quot; data-filename=&quot;Hyprid_Inheritance.png&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;하이브리드 상속(Hybrid Inheritance)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;자바 상속의 특징&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상속을 해주는 상위 클래스를 부모 클래스(Parent Class, Super Class)라고 부른다.&lt;/li&gt;
&lt;li&gt;상속을 받는 하위 클래스를 자식 클래스(Child Class, Sub Class)라고 부른다.&lt;/li&gt;
&lt;li&gt;다단계 상속이 가능하고, 다중 상속을 지원하지 않는다.&lt;/li&gt;
&lt;li&gt;모든 클래스는 Object 클래스의 자식 클래스이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608460815883&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Parent {
    int a;
    String b;

    public void print() {
        System.out.println(&quot;a = &quot;+a+&quot; b = &quot;+b);
    }
}


class Child extends Parent { // Parent 클래스를 상속 받아 Parent 클래스의 필드와 메서드를 가진다.
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;- 다중 상속의 문제점&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상속받은 복수의 부모 클래스에 중복되는 필드나 메서드가 존재할 수도 있다.&lt;/li&gt;
&lt;li&gt;같은 클래스를 두 번 이상 상속받을 수 있다.&lt;/li&gt;
&lt;li&gt;부모 클래스에 접근할 방법이 애매해진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;super 키워드&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;super 키워드는 자식 클래스에서 부모 클래스를 가리키는 키워드이다. super 키워드를 통해 자식 클래스는 부모 클래스의 필드나 메서드를 호출할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;super 키워드와 헷갈릴 수도 있는 super() 메서드는 부모 클래스의 생성자 함수를 호출하는 메서드이다. 자식 클래스의 생성자 함수에는 기본적으로 super()를 호출해야 한다. 기입하지 않는 경우엔 컴파일러가 슬쩍 끼워 넣어 준다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608470536368&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Parent {
    String name;
    int age;
    
    public Parent() {
    }
    
    public Parent(String name, int age) {
        this.name = name;
        this.age = age;
    }   
}

class Child extends Parent {
    boolean isMale;
    
    public Child() {
    }
    
    public Child(boolean isMale) {
        this.isMale = isMale;
    }
    
    public setName(String name) {
        super.name = name; // 부모 클래스의 필드
    }
    
    public setAge(int age) {
        super.age = age;  // 부모 클래스의 필드
    }
    
    @Override
    public String toString() {
    	return &quot;name = &quot;+name+&quot;, age = &quot;+age+&quot;, isMale = &quot;+isMale;
    }
}

class Main {
    public static void main(String[] args) {
        Child child = new Child(true);
        child.setName(&quot;bogeun&quot;);
        child.setAge(20);
        
        System.out.println(child);
    }    
}



// result

name = bogeun, age = 20, isMale = true&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;super()는 부모 클래스의 기본 생성자이며, 인자가 추가되면 그에 맞는 생성자가 호출된다. 만약 부모 클래스에 기본 생성자가 없다면, 컴파일러가 자동으로 끼워 넣어주던 혜택은 받지 못하고, 정의된 생성자 함수를 자식 클래스의 생성자 함수마다 일일이 찾아가며 호출해줘야 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608468484949&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Parent {
	
    public Parent() {
    	System.out.println(&quot;나는 부모 클래스의 생성자다.&quot;);
    }
    
}

class Child extends Parent {

    public Child() {
    //  super();
    	System.out.println(&quot;나는 자식 클래스의 생성자다.&quot;);
    }
}

class Main {
    public static void main(String[] args) {
        Parent p = new Parent();
        
        System.out.println(&quot;------------------------------&quot;);
        
        Child c = new Child();
    }
}


// result

나는 부모 클래스의 생성자다.  // 얘도 알고보면 앞에 Object의 생성자가 호출 되겠지.
------------------------------
나는 부모 클래스의 생성자다.  // 부모 클래스의 기본 생성자가 호출 되고,
나는 자식 클래스의 생성자다.  // 그 다음 자식 클래스의 기본 생성자가 호출됨.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;위처럼 자식 클래스의 생성자 함수에 super()가 기입되지 않아도 컴파일러가 스리슬쩍 넣어준다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608468670940&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Parent {  //  기본 생성자가 없는 부모 클래스

    String name;
    
    public Parent(String name) {
        this.name = name;
    }
    
}

class Child extends Parent {
    
    public Child() {    // 이 경우 부모 클래스에 기본 생성자가 없기 때문에
    // super();         // 컴파일 에러가 난다.
    }
    
    public Child() {   
        super(&quot;bogeun&quot;); // 부모 클래스의 생성자가 정확히 호출 되므로 에러가 없다.
    }
    
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;메서드 오버 라이딩&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;오버 라이딩(Overriding)은 부모 클래스로부터 상속받은 메서드를 자식 클래스에서 재정의하는 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608471053287&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Parent {
    public void go() {
        System.out.println(&quot;I`m parent.&quot;);
    }
}

class Child extends Parent {
    
    @Override
    public void go() {
        System.out.println(&quot;I`m child.&quot;);
    }
}

class Main {
	public static void main(String[] args) {
        Parent parent = new Parent();
        Child child = new Child();
        
        parent.go();
        child.go();
    }
}




// result

I`m parent.
I`m child.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;위처럼 부모 클래스의 메소드를 자식 클래스가 새로 재정의하여 사용한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;@Override 어노테이션은 개발자에게 '얘야 이거 오버 라이딩된 메서드란다.'라고 알려주는 역할과 부모 클래스에 없는 메서드를 착각하고 어노테이션을 붙인 경우 착각하고 있다고 알려주는 역할을 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608471476655&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Parent {
}

class Child extends Parent {
 
    @Override  //  컴파일 에러남. '수퍼 클래스엔 그런 거 없는데?'
    public void go() {
    }
    
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;다이내믹 메서드 디스패치 (Dynamic Method Dispatch)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;메서드 디스패치란, 메소드를 어떻게 호출할 지를 정해서 호출하는 것이다. 여기에는 대표적으로 static과 dynamic이 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;먼저 정적 메소드 디스패치(static method dispatch)는 메서드가 어떻게 실행될지가 &lt;b&gt;컴파일 타임&lt;/b&gt;에 결정된다. private, static, final의 메서드들은 static으로 결정되며, 컴파일 타임에 메서드가 결정된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608520109243&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Parent {
    void run() {
        System.out.println(&quot;Parent.run()&quot;);
    }
    
    static void runStatic() {
        System.out.println(&quot;Parent.runStatic()&quot;);
    }
}

class Child extends Parent {
    @Override
    void run() {
        System.out.println(&quot;Child.run()&quot;);
    }
    
    static void runStatic() {
        System.out.println(&quot;Child.runStatic()&quot;);
    }
}

class Main {
    public static void main(String[] args) {
        Parent parent = new Parent();
        Child child = new Child();

        parent.run();
        child.run();
        parent.runStatic();
        child.runStatic();
    }
}



// result

Parent.run()
Child.run()
Parent.runStatic()
Child.runStatic()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;위의 예에서 parent나 child 두 경우 모두 컴파일 시점에 어떤 메서드를 실행할 지가 결정이 끝나고 그대로 실행을 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;동적 메서드 디스패치(dynamic method dispatch)는 어떤 메소드가 사용될 지 &lt;b&gt;런 타임&lt;/b&gt;에 결정된다. 동적 메소드 디스패치는 객체 지향 프로그래밍의 &lt;b&gt;다형성&lt;/b&gt;을 지원하기 위한 핵심 메커니즘이다. 동적 메소드 디스패치에 의해 같은 타입의 서로 다른 구현을 가진 객체들이 각각 자신이 어떤 메서드를 어떻게 동작시켜야 하는지 알게 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608521287356&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Parent {
    void run() {
        System.out.println(&quot;Parent.run()&quot;);
    }
}

class Child1 extends Parent {
    @Override
    void run() {
        System.out.println(&quot;Child1.run()&quot;);
    }
}

class Child2 extends Parent {
    @Override
    void run() {
        System.out.println(&quot;Child2.run()&quot;);
    }
}

class Main {
    public void main(String[] args) {
        Parent child1 = new Child1();
        Parent child2 = new Child2();
        
        child1.run();
        child2.run();
    }
}




// result

Child1.run()
Child2.run()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;child1과 child2 모두 컴파일 시점엔 그냥 대충 Parent 클래스의 run()을 호출하면 되겠거니 하고 있다. 그러나, 런 타임에 컴파일러가 가지고 있는 타입의 정보를 가지고 자기가 어떤 메서드를 실행해야 하는 지가 결정된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;부가적인 내용으로, 자바에서는 멤버 변수의 다형성을 허용하지 않는다. 이것은 멤버 변수는 컴파일 시점에 정해져서 런 타임에는 변화가 없다는 뜻이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608522687045&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Parent {
    int x = 1;
}

class Child extends Parent {
    int x = 10;
}

class Main {
    public static void main(String[] args) {
        Parent parent = new Parent();
        Child child = new Child();
        Parent paild = new Child();
        
        System.out.println(parent.x);
        System.out.println(child.x);
        System.out.println(paild.x);
    }
}




// result

1
10
1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;추상 클래스&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;추상 클래스는 클래스인데 추상적인 클래스이다. 추상 메서드를 가질 수 있고, 온전한 메소드도 가질 수 있는 클래스이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;제일 많이 쓰는 예시로 Shape이라는 추상 클래스를 정의 해본다고 하면, Shape은 calArea(), printName() 등의 추상 메서드를 가진다. Shape은 String color의 멤버 변수를 가지고, getColor(), setColor()의 메서드를 가진다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Shape의 하위 클래스로는 Triangle, Circle, &lt;span&gt;Rectangle들을 정의하면, 추상 메서드에 해당하는 각각의 클래스에 맞는 메서드를 정의해줘야 한다. 온전한 형태의 메서드는 그대로 상속받아 똑같이 사용할 수도, 오버 라이딩해서 재정의할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608534975214&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;abstract class Shape {
    String color;
    
    abstract double calArea();
    abstract void printName();
    
    String getColor() {
        return color;
    }
    
    void setColor(String color) {
        this.color = color;
    }
}

class Circle {
	double radius;
    
    double calArea() {
        double area = 0;
        
        area = 3.14 * radius * radius;
        
        return area;
    }
    
    void printName() {
        System.out.println(&quot;I`m Circle.&quot;);
    }   
}

class Rectangle {
    double width;
    double height;
    
    double calArea() {
        double area = 0;
        
        area = width * height;
        
        return area;
    }
    
    void printName() {
        System.out.println(&quot;I`m Rectangle.&quot;);
    }   
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;final 키워드&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;final 키워드는 변수나 메소드 등을 immutable 하게 만들어 준다. final이 붙을 수 있는 곳은 클래스, 변수, 메서드가 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;변수의 경우&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608533030693&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Main {

//  멤버 변수에 붙는 경우.
    final int age = 10;

    public static void main(String[] args) {
    
    //  참조 변수에 final이 붙는 경우.
        final MyClass myClass = new MyClass();
        
        myClass = new MyClass(); // 컴파일 에러.
        
    //  프리미티브 타입 변수에 final이 붙는 경우.
    	final int MAX_SIZE = 100; // 상수가 되어버림.
        
    }
    
    // 메소드의 파라미터에 붙는 경우.
    void run(final int number) {
        number++;  // 컴파일 에러.
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;메서드에 붙는 경우&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608533178513&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Parent {

    final void run() { // 메소드에 final이 붙는 경우.
        System.out.println(&quot;run&quot;);
    }
    
}

class Child extends Parent {

    @Override  //  오버라이딩을 못함, 컴파일 에러.
    void run() {
    }
    
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;final이 붙는 메서드는 static method dispatch로 컴파일 타임에 결정이 나버림.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;클래스에 붙는 경우&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608533287496&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;final class Parent { // 클래스에 final이 붙는 경우.
}


class Child extends Parent { // 상속받을 수 없음, 컴파일 에러.
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Object 클래스&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;자바에서 모든 클래스들의 상위 클래스이다. 내가 임의로 만든 클래스도 Object 클래스를 상속받고 있다. extends Object를 써넣지 않았는데도 어떻게 이게 되는 걸까? 이것은 컴파일러가 컴파일 타임에 쓱 끼워 넣어 준다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;내가 만든 클래스는 다른 클래스를 상속받고 있는데, 다중 상속이 되지 않는 자바인데 어떻게 Object 상속 부분을 끼워 넣어줄까? 이것은 컴파일러가 똑똑하게 가상 상위 클래스를 찾아 거기에 Object 상속을 슥 끼워넣어 준다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이렇게 해서 직접적으로나 간접적으로나 모든 클래스는 Object 클래스를 상속받는다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;참고 : &lt;a href=&quot;https://www.guru99.com/java-class-inheritance.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.guru99.com/java-class-inheritance.html&lt;/a&gt;, &lt;a href=&quot;http://www.tcpschool.com/cpp/cpp_inheritance_multiple&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.tcpschool.com/cpp/cpp_inheritance_multiple&lt;/a&gt;, &lt;a href=&quot;https://medium.com/ingeniouslysimple/static-and-dynamic-dispatch-324d3dc890a3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;medium.com/ingeniouslysimple/static-and-dynamic-dispatch-324d3dc890a3&lt;/a&gt;, &lt;a href=&quot;https://www.geeksforgeeks.org/dynamic-method-dispatch-runtime-polymorphism-java/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.geeksforgeeks.org/dynamic-method-dispatch-runtime-polymorphism-java/&lt;/a&gt;&lt;/p&gt;</description>
      <category>Language/자바 정리 할래</category>
      <author>보근</author>
      <guid isPermaLink="true">https://hoooooooooooooop.tistory.com/44</guid>
      <comments>https://hoooooooooooooop.tistory.com/entry/javahalle6#entry44comment</comments>
      <pubDate>Mon, 21 Dec 2020 12:53:07 +0900</pubDate>
    </item>
    <item>
      <title>5주차 과제: 클래스</title>
      <link>https://hoooooooooooooop.tistory.com/entry/javahalle5</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;클래스 정의하는 방법&lt;/li&gt;
&lt;li&gt;객체 만드는 방법 (new 키워드 이해하기)&lt;/li&gt;
&lt;li&gt;메소드 정의하는 방법&lt;/li&gt;
&lt;li&gt;생성자 정의하는 방법&lt;/li&gt;
&lt;li&gt;this 키워드 이해하기&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;클래스 정의하는 방법&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;클래스란, 모든 Java 프로그램의 가장 기본적인 구조를 이루는 요소이다. 클래스는 필드와 메소드를 포함하며 새로운 참조 타입을 정의하기도 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;클래스의 기본 구성&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;필드 변수(멤버 변수)&lt;/li&gt;
&lt;li&gt;메소드&lt;/li&gt;
&lt;li&gt;생성자&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608342225869&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class MyClass {

    String name;  //  멤버 변수들
    int age;
    
    public MyClass() {  // Default 생성자
    }
    
    public MyClass(String name, int age) {  // AllArgs 생성자
        this.name = name;
        this.age = age;
    }
    
    public void print() {  // 메소드
        System.out.println(&quot;name = &quot;+name+&quot; age = &quot;+age);
    }
    
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;객체 만드는 방법 (new 키워드 이해하기)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;객체를 만드는 방법은, 클래스 타입의 변수를 정의 후 인스턴스로 초기화 시켜주는 방법이 제일 기본적이다. 인스턴스를 만드는 방법은 new 키워드와 생성자 함수를 이용하는 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;생성자 함수의 작동 방식&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;new 키워드로 인해 새로운 인스턴스를 만든다고 알림.&lt;/li&gt;
&lt;li&gt;새로운 인스턴스를 보유할 수 있도록 메모리가 할당됨.&lt;/li&gt;
&lt;li&gt;생성자 함수의 내용대로 생성자가 호출됨. (Default or 지정된 인자로 이뤄진 생성자)&lt;/li&gt;
&lt;li&gt;정의된 생성자 함수를 따라 만들어진 인스턴스가 생성됨.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608342877451&quot; class=&quot;java&quot; style=&quot;display: block; overflow: auto; padding: 15px; color: #383a42; background: #f6f7f8; font-size: 14px; border-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class MyClass {

    String name;
    int age;
    
    public MyClass() {
    }
    
    public MyClass(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
}

class Main {
   public static void main(String[] args) {
       
       MyClass myClass1 = new MyClass();  //  기본 생성자로 생성된 객체
       MyClass myClass2 = new MyClass(&quot;bogeun&quot;, 20);  //  모든 인자를 받는 생성자로 생성된 객체&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;메소드 정의하는 방법&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;메소드는 접근 제한자, 반환 타입, 메서드 명, 파라미터, 메소드 블럭으로 이뤄져 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608347925604&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public void myPrint(String text) {
	System.out.println(&quot;text is &quot;+text);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;접근 제한자&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;public : 모든 클래스의 접근을 허용한다.&lt;/li&gt;
&lt;li&gt;private : 자기 자신(객체)만 접근을 허용한다.&lt;/li&gt;
&lt;li&gt;protected : 같은 패키지의 클래스 + 자식 클래스에만 접근을 허용한다.&lt;/li&gt;
&lt;li&gt;default : 같은 패키지의 클래스만 접근을 허용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;반환 타입&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;반환 타입은 프리미티브 타입부터 참조 타입까지 전부 올 수 있으며, return으로 결과를 반환한다. void는 반환 타입이 없다는 의미로 return되는 값이 없다. void에서 return을 호출하면 메소드 호출 위치로 제어가 넘어간다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;생성자 정의하는 방법&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;생성자 함수는 클래스의 인스턴스를 생성하는 함수이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Default 생성자&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;인자를 아무것도 받지 않는 생성자 함수로, 아무런 생성자 함수도 정의하지 않으면 기본적으로 사용할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608348567106&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class MyClass {

    public MyClass() {
    }
    
}


class MyClass {  //  기본 생성자 정의가 없어도 위와 같이 동작한다.
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;필드에 따라 여러가지 생성자 함수를 정의할 수도 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608348791942&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class MyClass { 

    String name;
    int age;
    boolean isMale;
    
    public MyClass(String name) {  // name 필드만 받는 생성자
        this.name = name;
        this.isMale = true;  // default 값처럼 설정할 수도 있다.
    }
    
    public MyClass(String name, int age, boolean isMale) {  // 모든 인자를 다 받는 생성자
        this.name = name;
        this.age = age;
        this.isMale = isMale;
    }
    
}  // 기본 생성자를 정의하지 않은채 다른 생성자 함수를 정의했기 때문에 기본 생성자는 사용 불가하다.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;this 키워드 이해하기&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;this 키워드는 자기 자신의 객체를 가리키는 키워드이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608348927117&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class MyClass {

    String name;
    int age;
    
    public MyClass(String name, int age) {
        
        this.name = name;  //  this.name은 이 객체의 필드 변수 name을 가리킨다.
        this.age = age;    //  반면에 오른쪽의 name은 파라미터로 받은 name을 가리킨다.
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;this와 비슷한 super는 상속받은 부모의 객체를 가리키는 지시자이다.&lt;/li&gt;
&lt;li&gt;this()는 같은 클래스의 다른 생성자를 호출한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608349261426&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MyClass {

    String name;
    int age;

    public MyClass() {
        this(&quot;bogeun&quot;, 15);  //  아래에 있는 생성자 함수를 호출한 경우.
    }
    
    public MyClass(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;과제&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;int 값을 가지고 있는 이진 트리를 나타내는 Node 라는 클래스를 정의하세요.&lt;/li&gt;
&lt;li&gt;int value, Node left, right를 가지고 있어야 합니다.&lt;/li&gt;
&lt;li&gt;BinrayTree라는 클래스를 정의하고 주어진 노드를 기준으로 출력하는 bfs(Node node)와 dfs(Node node) 메소드를 구현하세요.&lt;/li&gt;
&lt;li&gt;DFS는 왼쪽, 루트, 오른쪽 순으로 순회하세요.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;binaryTree_base.png&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;500&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cX6nhV/btqQIbqLFWq/aa1BYVXKXFOerCFSYyYIKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cX6nhV/btqQIbqLFWq/aa1BYVXKXFOerCFSYyYIKK/img.png&quot; data-alt=&quot;아래 예시의 이진 트리 모양&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cX6nhV/btqQIbqLFWq/aa1BYVXKXFOerCFSYyYIKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcX6nhV%2FbtqQIbqLFWq%2Faa1BYVXKXFOerCFSYyYIKK%2Fimg.png&quot; data-filename=&quot;binaryTree_base.png&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;500&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;아래 예시의 이진 트리 모양&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Node 클래스&lt;/p&gt;
&lt;pre id=&quot;code_1608351151148&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Node {
    int value;
    Node left;
    Node right;

    public Node(int value) {
        this.value = value;
    }

    public Node(int value, Node left, Node right) {
        this.value = value;
        this.left = left;
        this.right = right;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;BinaryTree 클래스&lt;/p&gt;
&lt;pre id=&quot;code_1608351203611&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class BinaryTree {

    Queue&amp;lt;Node&amp;gt; queue = new LinkedList&amp;lt;&amp;gt;();

    public void bfs(Node node) {
        if(node.left != null) {
            queue.add(node.left);
        }
        if(node.right != null) {
            queue.add(node.right);
        }

        System.out.print(node.value+&quot; &quot;);

        if(queue.size() != 0) {
            bfs(queue.remove());
        }
    }
    
    public void dfs(Node node) {  // 중위 순회 좌 탐 우
        if(node.left != null) {
            dfs(node.left);
        }

        System.out.print(node.value+&quot; &quot;);

        if(node.right != null) {
            dfs(node.right);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;결과 출력&lt;/p&gt;
&lt;pre id=&quot;code_1608351473373&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Main {
	
    public static void main(String[] args) {
        
        Node node = new Node(1, new Node(2, new Node(4), new Node(5))
                  , new Node(3, new Node(6), new Node(7)));
                  
        BinaryTree bt = new BinaryTree();
        
        bt.bfs(node);  // 1 2 3 4 5 6 7
        bt.dfs(node);  // 4 2 5 1 6 3 7
    
    }
    
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Language/자바 정리 할래</category>
      <author>보근</author>
      <guid isPermaLink="true">https://hoooooooooooooop.tistory.com/42</guid>
      <comments>https://hoooooooooooooop.tistory.com/entry/javahalle5#entry42comment</comments>
      <pubDate>Sat, 19 Dec 2020 12:43:33 +0900</pubDate>
    </item>
    <item>
      <title>4주차 과제: 제어문</title>
      <link>https://hoooooooooooooop.tistory.com/entry/javahalle4</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;선택문&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;반복문&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;과제 0 : JUnit 5 학습하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;과제 1 : live-study 대시 보드를 만드는 코드를 작성하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;과제 2 : LinkedList를 구현하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;과제 3 : Stack을 구현하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;과제 4 : 앞서 만든 ListNode를 사용해서 Stack을 구현하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;과제 5 : Queue를 구현하세요.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;선택문&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;switch는 if처럼 프로그램 내에서 분기를 만들어 준다. switch가 하는 일을 if와 else if, else로 충분히 할 수 있지만 단일 변수에 의존하는 분기 상황의 경우 switch문이 더 뛰어난 가독성을 보여준다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;switch의 분기를 나타낼 변수는 char, byte, short, int와 이들의 wrapper class, String과 enum이 올 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1606996268283&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int a = 5;
int b = 10;

switch(a) {
	
    case 3 :
    	System.out.println(&quot;Hi&quot;);
        break;
        
    case 4 :
    	System.out.println(&quot;Bye&quot;);
        break;
        
    default :
        System.out.println(a);
        break;
        
}

switch(b) { // break가 없는 경우.

	case 9 :
    	System.out.println(&quot;Hello&quot;);

    case 10 :
        System.out.println(&quot;I`m&quot;);
        
    case 11 : 
    	System.out.println(&quot;Bogeun&quot;);
        
    default :
    	System.out.println(&quot;HaHa&quot;);
        
}
        
	&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;위의 예시를 보면 switch 예약어 뒤에 분기를 결정할 변수가 들어간다. 각각의 분기는 case 예약어로 나뉘어 있다. 각각의 case는 실행할 구문과 switch문을 종료할 break가 온다. 모든 case에 해당되지 않으면 default를 수행한다. default마저 없으면 아무런 동작도 없이 넘어간다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;각 case마다 break가 없다면, 해당하는 case를 실행 후 종료되지 않고 다음 case의 동작까지 수행해버린다. 의도하고 사용할 수도 있지만, 예상과 다르게 수행될 수도 있으니 알아두는게 좋을 거 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;변수에 맞는 case를 수행한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;수행하는 case에 break가 없으면 뒤에 작성된 case를 조건에 상관없이 수행한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;뒤에 작성된 case에도 break가 없으면 또 다시 뒤의 case를 수행하길 반복한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;break가 있는 case를 만나면 종료한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;마지막까지도 break를 만나지 못하면 끝까지 수행한다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;반복문&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;반복문은 조건에 해당하는 상태를 가지고 있으면 같은 동작을 반복한다. 반복문은 for와 while이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;- while&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1606998766934&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int n = 10;

while(n &amp;gt; 5) {
	
    System.out.println(n--);
    
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;while 문은 위의 예시처럼 예약어 뒤에 조건식이 들어오고, 뒤에 수행할 동작의 블럭이 들어온다.&lt;/span&gt;&lt;span&gt;&amp;nbsp;조건식이 true라면 수행되고, false라면 수행을 멈춘다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;간단하게 쓸 수 있지만, while문을 빠져나올 길을 필수적으로 만들어줘야 한다. 위의 예시처럼 조건식의 변수에 증감을 넣어서 적절한 반복 후에 멈추게 할 수도 있고, 동작 블럭 내에 break를 넣어 멈춰줄 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;do-while 문을 작성하면 while의 조건식과 상관없이 딱 한 번의 동작은 필수적으로 수행하게 할 수도 있다. 원래 조건식을 만족하지 못하던 상태에서 do 예약어로 한 번 실행 후에 조건식을 만족하게 되어도 while문이 실행된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1606999235798&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int n = 6;

while(n &amp;lt; 6 &amp;amp;&amp;amp; n &amp;gt; 0) {
	
    System.out.println(n--);

}


do {

	System.out.println(n--);
    if(n == 0) {
    	break;    
    }

} while(n &amp;lt; 6);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;do-while 문은 위처럼 작성을 한다. 위의 while 문은 조건식을 만족하지 못해 동작이 되지 않지만, 뒤의 do-while 문은 첫 번째의 수행에서 조건식을 만족하는 상태가 되었기 때문에 반복문이 수행된다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;아래의 경우는 while의 조건식에는 해당되지만 코드 블럭 내에서 break로 반복을 멈춰준 경우로 6부터 1까지 반복 출력 후에 종료된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;-for&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1606999437889&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for(int i = 0 ; i &amp;lt; 10 ; i++) {
	System.out.println(&quot;i&quot;);
}

for(int i = 0 ; true ; i++) {
	if(i &amp;gt; 10) {
    	break;
    }
    if(i % 2 == 0) {
    	continue;
    }
        
	System.out.println(&quot;i&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;for 문은 위처럼 for( 초기화식 ; 조건식 ; 증감식 ) 과 그 뒤에 수행할 블럭의 구조로 이뤄진다. while 문과 마찬가지로 조건식이 true이면 반복된다. 위의 예시는 1부터 9까지 반복 출력 후 종료된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;아래의 예시처럼 조건식이 true인 경우는 무한정 반복한다. 하지만 break문으로 반복문을 종료하도록 작성하였다. continue 예약어는 아래의 동작을 수행하지 않고 다시 반복문의 첫 줄로 실행을 옮긴다. 예시에선 짝수인 경우 continue 예약어를 호출 했으니, 결과적으로 1, 3, 5, 7, 9 의 홀수들만 찍힌다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;- 이름을 가지는 for문&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1607002890626&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;hello : // hello란 이름을 붙여줌.
for(int i = 0 ; i &amp;lt; 10 ; i++) {
	for(int j = 0 ; j &amp;lt; 5 ; j++) {
		if(i == 3) 
			break; // 현재의 반복문을 종료.
		else if(i == 5) 
			break hello; // hello 반복문의 종료.

		System.out.println(&quot;i = &quot;+i+&quot; j = &quot;+j);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;위의 예시처럼 for문에 이름을 붙여줄 수 있다. 위는 이중 for문으로 i가 3일 때 if문에 걸려 i가 3인 경우는 아래의 문장이 찍히지 않는다. i가 4인 경우를 돌고 5가 되었을 때는 hello라는 이름이 붙은 반복문이 종료하게 된다. 결과적으론 이중 for문이 종료된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;-forEach&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1607002372962&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int[] arr = { 1, 2, 3, 4 ,5 };

for(int i : arr) {
	System.out.println(i);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;위는 forEach 문의 예시로 Collection의 객체들이나 배열의 요소들을 순차적으로 다루는 반복문이다. Colletion의 객체를 전부 한 번씩 다루거나 배열의 모든 요소를 한 번씩 다 다룬 후에 종료된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;과제 0 : JUnit 5 학습하세요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;^_^&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;과제 1 : live-study 대시 보드를 만드는 코드를 작성하세요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1607581234413&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.kohsuke.github.*;

import java.io.IOException;
import java.util.*;

public class Main {
    private static final int WEEKS_CNT = 18;

    public static void main(String[] args) throws IOException {

        GitHub gitHub = new GitHubBuilder().withOAuthToken(&quot;personalAccessToken&quot;).build();
        GHRepository repository = gitHub.getRepository(&quot;whiteship/live-study&quot;);

        List&amp;lt;String&amp;gt; studentNames = new ArrayList&amp;lt;&amp;gt;();
        Map&amp;lt;String, boolean[]&amp;gt; studyCheck = new HashMap&amp;lt;&amp;gt;();

        for (int i = 1; i &amp;lt;= WEEKS_CNT; i++) {
            GHIssue issue = repository.getIssue(i);
            List&amp;lt;GHIssueComment&amp;gt; comments = issue.getComments();

            for (GHIssueComment comment : comments) {
                String studentName = comment.getUser().getLogin();

                if (studentNames.contains(studentName)) {
                    boolean[] check = studyCheck.get(studentName);
                    check[i] = true;
                } else {
                    studentNames.add(studentName);
                    boolean[] b = new boolean[WEEKS_CNT+1];
                    b[i] = true;
                    studyCheck.put(studentName, b);
                }
            }
        }

        String[] students = studentNames.toArray(new String[0]);
        Arrays.sort(students);

        StringBuilder sb = new StringBuilder(&quot;|참여자|1주차|2주차|3주차|4주차|5주차|6주차|7주차|8주차|9주차|10주차|11주차|12주차|13주차|14주차|15주차|16주차|17주차|18주차|참석율|\n&quot; +
                &quot;|----------|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|-----|\n&quot;);
        for (String student : students) {
            boolean[] check = studyCheck.get(student);
            int cnt = countTrue(check);
            String rate = String.format(&quot;%.2f&quot;, (double) cnt / WEEKS_CNT * 100);

            sb.append(&quot;|&quot; + student + &quot;|&quot;);
            for (int i = 1 ; i &amp;lt;= WEEKS_CNT ; i++) {
                if (check[i]) {
                    sb.append(&quot;✅|&quot;);
                } else {
                    sb.append(&quot;|&quot;);
                }
            }
            sb.append(rate + &quot;%|\n&quot;);
        }

        System.out.println(sb.toString());
    }

    private static int countTrue(boolean[] check) {
        int cnt = 0;

        for (boolean b : check) {
            if(b) {
                cnt++;
            }
        }

        return cnt;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;결과 : &lt;span&gt;&lt;a href=&quot;https://github.com/idiot2222/practice-github_api/blob/main/README.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;github.com/idiot2222/practice-github_api/blob/main/README.md&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;과제 2 : LinkedList를 구현하세요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;리스트는 배열과 같은 선형 자료구조이다. 데이터의 순서가 있고, 중복이 허용된다. 초기화 시에 정해진 길이가 변하지 않는 배열과 달리 리스트는 길이가 유동적으로 바뀐다. 배열은 메모리에서 데이터들이 길게 이어져 붙어 있다. 리스트는 구현에 따라 다른데, 배열 리스트의 경우 배열과 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;연결 리스트는 배열과 다르게 데이터를 갖고 있는 노드들이 메모리 상에 흩어져 있는 자료 구조이다. 각 노드들은 데이터와 자신과 연결된 다음 노드의 주소를 갖고 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;배열 리스트의 경우, 인덱스를 통해 데이터에 랜덤 엑세스가 가능해 데이터에 대한 접근이 빠르다. 반면에, 연결 리스트의 경우에는 어떠한 데이터에 접근하기 위해서는 리스트의 가장 첫 번째 노드인 head에서부터 목적지까지 순차 탐색을 해야한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;배열 리스트의 경우, 새로운 데이터를 추가하는데 비용이 많이 든다. 배열 리스트에 데이터를 추가하려고 하면, 추가하려는 위치부터 그 뒤의 데이터들은 전부 한 칸씩 뒤로 밀어줘야 한다. 만약에 배열에 빈 공간이 없다면, 크기가 더 큰 새로운 배열을 만들어 데이터들을 다 옮겨줘야 한다. 반면에, 연결 리스트의 경우에는 추가하려는 위치의 직후 노드를 참조하고, 직전 노드가 새로운 노드를 참조하도록 해주면 끝이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;linkedList.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;400&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0hBgI/btqPTDBShz6/KQK64j4eQnjRPOJcLbGCCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0hBgI/btqPTDBShz6/KQK64j4eQnjRPOJcLbGCCk/img.png&quot; data-alt=&quot;연결 리스트에서 새로운 데이터를 추가하는 방식&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0hBgI/btqPTDBShz6/KQK64j4eQnjRPOJcLbGCCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0hBgI%2FbtqPTDBShz6%2FKQK64j4eQnjRPOJcLbGCCk%2Fimg.png&quot; data-filename=&quot;linkedList.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;400&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;연결 리스트에서 새로운 데이터를 추가하는 방식&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;-ListNode 구현&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1607744312292&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class ListNode {

    int data;
    ListNode next;

    public ListNode(int data) {
        this.data = data;
        this.next = null;
    }












    public ListNode add(ListNode head, ListNode nodeToAdd, int position) {
        ListNode p = head;

        if(position == 0) {
            nodeToAdd.next = p;
            return nodeToAdd;
        }

        while(--position &amp;gt; 0) {
            p = p.next;
        }

        if(p.next != null) {
            nodeToAdd.next = p.next;
        }
        p.next = nodeToAdd;

        return head;
    }

    public ListNode remove(ListNode head, int positionToRemove) {
        ListNode p = head;

        if(positionToRemove == 0) {
            return p.next;
        }

        while(--positionToRemove &amp;gt; 0) {
            p = p.next;
        }

        p.next = p.next.next;

        return head;
    }

    public boolean contains(ListNode head, ListNode nodeToCheck) {
        ListNode p = head;

        while(p != null) {
            if(p.data == nodeToCheck.data) {
                return true;
            }
            p = p.next;
        }

        return false;
    }












    /**
     *  테스트용 메서드
     */
    public void printAll() {
        ListNode head = this;

        System.out.print(data+&quot; &quot;);
        while (head.next != null) {
            head = head.next;
            System.out.print(head.data+&quot; &quot;);
        }
    }

    public int size() {
        ListNode p = this;
        int cnt = 1;

        while(p.next != null) {
            p = p.next;
            cnt++;
        }

        return cnt;
    }

    public int get(int idx) {
        ListNode p = this;

        while(idx-- &amp;gt; 0) {
            p = p.next;
        }

        return p.data;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;- ListNodeTest&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1607744346772&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class ListNodeTest {



    @Test
    void add() {
        ListNode list = new ListNode(1);
        list = list.add(list, new ListNode(0), 0);
        list.add(list, new ListNode(3), 2);
        list.add(list, new ListNode(2), 2);

        assertEquals(list.size(), 4);
        assertEquals(list.get(0), 0);
        assertEquals(list.get(1), 1);
        assertEquals(list.get(2), 2);
        assertEquals(list.get(3), 3);

        list.printAll();
    }



    @Test
    void remove() {
        ListNode list = new ListNode(-1);
        list.add(list, new ListNode(1), 1);
        list.add(list, new ListNode(-1), 2);
        list.add(list, new ListNode(2), 3);
        list.add(list, new ListNode(-1), 4);

        list = list.remove(list, 0);
        list.remove(list, 1);
        list.remove(list, 2);

        assertEquals(list.size(), 2);
        assertEquals(list.get(0), 1);
        assertEquals(list.get(1), 2);

        list.printAll();
    }



    @Test
    void contains() {
        ListNode list = new ListNode(1);
        list.add(list, new ListNode(2), 1);
        list.add(list, new ListNode(3), 2);
        list.add(list, new ListNode(4), 3);

        assertTrue(list.contains(list, new ListNode(1)));
        assertTrue(list.contains(list, new ListNode(2)));
        assertTrue(list.contains(list, new ListNode(4)));
        assertFalse(list.contains(list, new ListNode(5)));

        list.printAll();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;과제 3 : Stack을 구현하세요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;스택은 먼저 들어간 데이터가 나중에 나오고, 가장 나중에 들어간 데이터가 가장 먼저 나오는 후입 선출(Last In-First out)의 입출력 형태를 가지는 자료 구조이다. 창고에 겹겹이 쌓여있는 짐들이 있고, 밑에 있는 짐을 꺼내기 위해선 위에 쌓여있는 짐들부터 꺼내야하는 것을 상상하면 비슷한 거 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;스택의 가장 상단의 데이터를 top, 가장 아래의 데이터를 bottom이라 부른다. 스택에 들어간 데이터는 요소(element)라고 부른다. 요소가 하나도 없는 스택 즉, 비어있는 스택을 empty stack이라 부른다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;스택에 요소를 추가하는 것을 push, top의 요소를 꺼내는 것을 pop이라고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;stack.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;600&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l9uwK/btqPTEU8Hhs/oDmHdZbBKaXsbjv1L0aRw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l9uwK/btqPTEU8Hhs/oDmHdZbBKaXsbjv1L0aRw0/img.png&quot; data-alt=&quot;동그라미 찍힌 애들이 top, 네모가 찍힌 애들이 bottom&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l9uwK/btqPTEU8Hhs/oDmHdZbBKaXsbjv1L0aRw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl9uwK%2FbtqPTEU8Hhs%2FoDmHdZbBKaXsbjv1L0aRw0%2Fimg.png&quot; data-filename=&quot;stack.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;600&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;동그라미 찍힌 애들이 top, 네모가 찍힌 애들이 bottom&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;-Stack 구현&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1607747780502&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Stack {

    int[] stack = new int[5];
    int top = -1;

    public Stack() {
    }






    public void push(int data) {
        stack[++top] = data;
    }

    public int pop() {
        return stack[top--];
    }







    /**
     * 테스트용 메소드
     */

    public void printAll() {
        for(int i = 0 ; i &amp;lt;= top ; i++) {
            System.out.print(stack[i]+&quot; &quot;);
        }
        System.out.println();
    }

    public int size() {
        return top+1;
    }

    public int get(int idx) {
        if(idx &amp;gt; top) {
            throw new ArrayIndexOutOfBoundsException(&quot;top = &quot;+top);
        }
        return stack[idx];
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;-StackTest&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1607747798694&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class StackTest {



    @Test
    void push() {
        Stack stack = new Stack();

        stack.push(1);
        stack.push(2);
        stack.push(3);

        assertEquals(stack.size(), 3);
        assertEquals(stack.get(0), 1);
        assertEquals(stack.get(1), 2);
        assertEquals(stack.get(2), 3);
        stack.printAll();
    }



    @Test
    void pop() {
        Stack stack = new Stack();
        stack.push(1);
        stack.push(2);
        stack.push(3);

        assertEquals(stack.pop(), 3);
        assertEquals(stack.pop(), 2);
        assertEquals(stack.pop(), 1);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;과제 4 : 앞서 만든 ListNode를 사용해서 Stack을 구현하세요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;-Stack 구현&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1607748667869&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Stack {

    ListNode head = new ListNode();
    int top = -1;

    public Stack() {
    }



    public void push(int data) {
        ListNode p = this.head;
        int cnt = this.top;

        while(cnt-- &amp;gt; -1) {
            p = p.next;
        }

        p.next = new ListNode(data);
        top++;
    }

    public int pop() {
        ListNode p = head;
        int cnt = top;

        while(cnt-- &amp;gt; 0) {
            p = p.next;
        }

        int temp = p.next.data;
        p.next = null;
        top--;

        return temp;
    }







    /**
     * 테스트용 메서드
     */

    public void printAll() {
        ListNode p = head;
        int cnt = top;

        while(cnt-- &amp;gt; -1) {
            p = p.next;
            System.out.print(p.data+&quot; &quot;);
        }
        System.out.println();
    }

    public int size() {
        return top+1;
    }

    public int get(int idx) {
        ListNode p = head;

        while(idx-- &amp;gt; -1) {
            p = p.next;
        }

        return p.data;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;Test는 위의 Stack과 같습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;과제 5 : Queue를 구현하세요.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;큐는 스택과 다르게 먼저 들어온 데이터가 먼저 나가는 선입 선출(First In-First Out)의 입출력 형태를 가지는 자료 구조이다. 터널과 같은 모양을 상상하면 될 거 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;queue.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;600&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b73xiU/btqP10oO72Z/ksiOAH1NVw0cYfD5l3EkLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b73xiU/btqP10oO72Z/ksiOAH1NVw0cYfD5l3EkLK/img.png&quot; data-alt=&quot;FIFO의 입출력 형태를 가지는 Queue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b73xiU/btqP10oO72Z/ksiOAH1NVw0cYfD5l3EkLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb73xiU%2FbtqP10oO72Z%2FksiOAH1NVw0cYfD5l3EkLK%2Fimg.png&quot; data-filename=&quot;queue.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;600&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;FIFO의 입출력 형태를 가지는 Queue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;- 배열을 이용한 Queue&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1607749603037&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.NoSuchElementException;

public class ArrayQueue {

    int[] queue = new int[5];
    int top = -1;
    int bottom = 0;

    public ArrayQueue() {
    }







    public void push(int data) {
        queue[++top] = data;
    }

    public int pop() {
        if(top &amp;lt; bottom) {
            throw new NoSuchElementException(&quot;queue is empty.&quot;);
        }

        return queue[bottom++];
    }








    /**
     * 테스트용 메서드
     */

    public void printAll() {
        for(int i = bottom ; i &amp;lt;= top ; i++) {
            System.out.print(queue[i]+&quot; &quot;);
        }
        System.out.println();
    }

    public int size() {
        return top - bottom + 1;
    }

    public int get(int idx) {
        return queue[idx+bottom];
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;- ListNode를 이용한 Queue&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1607750367400&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.NoSuchElementException;

public class ListQueue {

    ListNode head = new ListNode();
    int top = -1;

    public ListQueue() {
    }






    public void push(int data) {
        ListNode p = head;
        int cnt = top;

        while (cnt-- &amp;gt; -1) {
            p = p.next;
        }

        p.next = new ListNode(data);
        top++;
    }

    public int pop() {
        if (top &amp;lt; 0) {
            throw new NoSuchElementException(&quot;queue is empty.&quot;);
        }

        ListNode p = head;

        int temp = p.next.data;
        p.next = p.next.next;
        top--;

        return temp;
    }






    /**
     * 테스트용 메서드
     */

    public void printAll() {
        ListNode p = head;
        int cnt = top;

        while(cnt-- &amp;gt; 0) {
            p = p.next;

            System.out.print(p.data+&quot; &quot;);
        }
        System.out.println();
    }

    public int size() {
        return top+1;
    }

    public int get(int idx) {
        if(idx &amp;gt; top) {
            throw new IndexOutOfBoundsException(&quot;top = &quot;+top);
        }

        ListNode p = head;

        while (idx-- &amp;gt; -1) {
            p = p.next;
        }

        return p.data;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;- QueueTest&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1607749623761&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class QueueTest {

    @Test
    void push() {
        Queue queue = new Queue();

        queue.push(1);
        queue.push(2);
        queue.push(3);

        assertEquals(queue.size(), 3);
        assertEquals(queue.get(0), 1);
        assertEquals(queue.get(1), 2);
        assertEquals(queue.get(2), 3);
        queue.printAll();
    }

    @Test
    void pop() {
        Queue queue = new Queue();
        queue.push(1);
        queue.push(2);
        queue.push(3);

        assertEquals(queue.pop(), 1);
        assertEquals(queue.pop(), 2);
        assertEquals(queue.pop(), 3);
        queue.printAll();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Language/자바 정리 할래</category>
      <author>보근</author>
      <guid isPermaLink="true">https://hoooooooooooooop.tistory.com/40</guid>
      <comments>https://hoooooooooooooop.tistory.com/entry/javahalle4#entry40comment</comments>
      <pubDate>Sat, 12 Dec 2020 14:27:41 +0900</pubDate>
    </item>
  </channel>
</rss>