<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>migratory_bird.log</title>
        <link>https://velog.io/</link>
        <description>효율성을 추구하며 세상을 떠도는 철새입니다.</description>
        <lastBuildDate>Sat, 05 Mar 2022 16:48:59 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>migratory_bird.log</title>
            <url>https://images.velog.io/images/migratory_bird/profile/1cb97d58-7b48-4656-b89f-e86f43edc4fa/social.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. migratory_bird.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/migratory_bird" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[29강. 인터페이스와 다형성 구현(2)]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-28-ykvjx3v9</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-28-ykvjx3v9</guid>
            <pubDate>Sat, 05 Mar 2022 16:48:59 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>29강 &quot;인터페이스와 다형성 구현(2)&quot;</li>
<li>인터페이스와 다형성</li>
</ul>
<h1 id="인터페이스와-다형성">인터페이스와 다형성</h1>
<ul>
<li>인터페이스는 &quot;Client Code&quot;와 서비스를 제공하는 &quot;객체&quot; 사이의 약속이다.</li>
<li>어떤 객체가 어떤 interface 타입이라 함은 그 interface가 제공하는 메서드를 구현했다는 의미이다.</li>
<li>Client는 어떻게 구현되었는지 상관없이 interface의 정의만을 보고 사용할 수 있다.(ex. JDBC)</li>
<li>다양한 구현이 필요한 인터페이스를 설계하는 일은 매우 중요한 일이다.</li>
</ul>
<p><img src="https://images.velog.io/images/migratory_bird/post/42aabf9e-61d1-4547-a3a7-b0d348f39f13/image.png" alt="">
UserInfoWeb은 IUserInfoDao에 정의된 메소드 명세만 보고 Dao를 사용할 수 있고, Dao 클래스들은 IUserInfoDao에 정의된 메소드를 구현할 책임이 있다.</p>
<h3 id="scheduler-예제">Scheduler 예제</h3>
<pre><code class="language-java">public interface Scheduler {
    void getNextCall();
    void sendCallToAgent();
}</code></pre>
<p>Scheduler 클래스를 interface로 정의하여 getNextCall(), sendCallToAgent() 메서드를 선언만 했다.</p>
<pre><code class="language-java">public class RoundRobin implements Scheduler{
    @Override
    public void getNextCall() {
        System.out.println(&quot;상담 전화를 순서대로 대기열에거 가져옵니다.&quot;);
    }
    @Override
    public void sendCallToAgent() {
        System.out.println(&quot;다음 순서 상담원에게 배분합니다.&quot;);
    }
}</code></pre>
<pre><code class="language-java">public class LeastJob implements Scheduler{
    @Override
    public void getNextCall() {
        System.out.println(&quot;상담 전화를 순서대로 대기열에거 가져옵니다.&quot;);
    }
    @Override
    public void sendCallToAgent() {
        System.out.println(&quot;현재 상담 업무가 없거나 상담 대기가 가장 적은 상담원에게 할당합니다.&quot;);
    }
}</code></pre>
<pre><code class="language-java">public class PriorityAllocation implements Scheduler{
    @Override
    public void getNextCall() {
        System.out.println(&quot;고객의 등급이 높은 고객의 전화를 먼저 가져옵니다.&quot;);
    }
    @Override
    public void sendCallToAgent() {
        System.out.println(&quot;업무 skill이 가장 높은 상담원의 대기열에 앞에 우선 배분합니다.&quot;);
    }
}</code></pre>
<p>RoundRobin, LeastJob, PriorityAllocation 클래스에서 Scheduler 클래스를 implements하고 메서드를 구현하였다.</p>
<pre><code class="language-java">import java.io.IOException;

public class SchedulerTest {
    public static void main(String[] args) throws IOException {
        System.out.println(&quot;전화 상담 배분방식을 선택하세요. (R, L, P)&quot;);

        int ch = System.in.read();
        Scheduler scheduler = null;

        if(ch == &#39;R&#39; || ch == &#39;r&#39;) {
            scheduler = new RoundRobin();
        }else if(ch == &#39;L&#39; || ch == &#39;l&#39;) {
            scheduler = new LeastJob();
        }else if(ch == &#39;P&#39; || ch == &#39;p&#39;) {
            scheduler = new PriorityAllocation();
        }else {
            System.out.println(&quot;지원하지 않는 기능입니다.&quot;);
            return;
        }

        scheduler.getNextCall();
        scheduler.sendCallToAgent();
    }
}</code></pre>
<p>main함수가 있는 SchedulerTest 클래스에서 다형성을 구현하였다.
System.in.read(); 는 사용자 입력을 받는 함수이고, IOException은 예외 처리 하는 문법이다. (추후 배울 예정)</p>
<p><img src="https://images.velog.io/images/migratory_bird/post/d9681517-ab7e-48b1-b64a-a49dec9820a3/image.png" alt="">
<img src="https://images.velog.io/images/migratory_bird/post/62dbeb2e-9f05-484f-a3ae-a689af82d936/image.png" alt="">
<img src="https://images.velog.io/images/migratory_bird/post/ceabd2a5-00be-4270-8705-faaa36393134/image.png" alt="">
<img src="https://images.velog.io/images/migratory_bird/post/74d69d9f-9fa2-4c90-a060-1d4ada7aa274/image.png" alt=""></p>
<p>각각의 경우에서 정상 출력되는 것을 확인할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[28강. 인터페이스 선언과 구현하기(1)]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-28</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-28</guid>
            <pubDate>Fri, 04 Mar 2022 16:05:43 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>28강 &quot;인터페이스 선언과 구현하기(1)&quot;</li>
<li>인터페이스(interface) &gt; 클래스에서 인터페이스 구현하기 &gt; 인터페이스 구현과 형변환</li>
</ul>
<h1 id="인터페이스interface">인터페이스(interface)</h1>
<ul>
<li>모든 메서드가 추상 메서드(abstract method)로 이루어진 클래스</li>
<li>형식적인 선언만 있고 구현은 없음</li>
<li>인터페이스에 선언된 모든 메서드는 public abstract로 추상 메서드임</li>
<li>인터페이스에 선언된 모든 변수는 public static final로 상수임</li>
<li>인터페이스를 상속받는 클래스는 implements 키워드를 사용함
(추상 클래스를 상속받는 클래스는 extends 키워드 사용)</li>
<li>인터페이스는 추상 클래스와 다르게 여러 클래스를 상속받을 수 있다.
(선언만 있고 구현은 없기 때문)</li>
</ul>
<pre><code class="language-java">public interface Calc {

    double PI = 3.14;
    int ERROR = -999999999;

    int add(int num1, int num2);
    int substract(int num1, int num2);
    int times(int num1, int num2);
    int divide(int num1, int num2);
}</code></pre>
<p>interface 클래스는 컴파일 과정에서 변수는 상수(public static final)로, 메서드는 추상 메서드(public abstract)로 자동으로 변환된다.</p>
<h1 id="클래스에서-인터페이스-구현하기">클래스에서 인터페이스 구현하기</h1>
<ul>
<li>Calc 인터페이스를 Calculator 클래스에서 구현
(Calc의 모든 추상 메서드를 구현하지 않으면 Calculator는 추상 클래스가 됨)</li>
<li>CompleteCalc 클래스가 Calculator 클래스를 상속받은 후 모든 메서드를 구현
(CompleteCalc는 생성 가능한 클래스)</li>
</ul>
<p><img src="https://images.velog.io/images/migratory_bird/post/dcaa46d8-d1de-46db-a851-20a857f55265/image.png" alt=""></p>
<pre><code class="language-java">public abstract class Calculator implements Calc{
    @Override
    public int add(int num1, int num2) {
        return num1 + num2;
    }
    @Override
    public int substract(int num1, int num2) {
        return num1 - num2;
    }
}</code></pre>
<pre><code class="language-java">public class CompleteCalc extends Calculator{
    @Override
    public int times(int num1, int num2) {
        return num1 * num2;
    }
    @Override
    public int divide(int num1, int num2) {
        if(num2 != 0) {
            return num1 / num2;
        }
        return ERROR;
    }
    public void showInfo() {
        System.out.println(&quot;Calc 인터페이스를 구현하였습니다.&quot;);
    }
}</code></pre>
<p>interface implements 는 type 상속, class extends 는 구현 상속이라고 한다.
implements도 상속이기 때문에 아래와 같은 코드가 가능하다.</p>
<pre><code class="language-java">Calc calc = new CompleteCalc();</code></pre>
<p>가장 하위 클래스인 CompleteCalc의 인스턴스를 생성해서 가장 상위 클래스인 인터페이스 타입으로 선언할 수 있다.
Calc 타입이기 때문에 CompleteCalc 클래스에 선언한 showInfo() 메서드는 사용할 수 없다.
(사용하기 위해서는 다운캐스팅 해야함)</p>
<p>interface와 abstract 클래스는 인스턴스를 생성할 수 없다.</p>
<pre><code class="language-java">Calc calc1 = new Calc();    //불가
Calc calc2 = new Calculator();    //불가</code></pre>
<h1 id="인터페이스-구현과-형변환">인터페이스 구현과 형변환</h1>
<ul>
<li>인터페이스를 구현한 클래스는 인터페이스 형으로 선언한 변수로 형변환 할 수 있음</li>
<li>상속에서의 형변환과 동일한 의미</li>
<li>단, 클래스 상속과 달리 구현코드가 없기 때문에 여러 인터페이스를 구현할 수 있음</li>
<li>형변환 시 사용할 수 있는 메서드는 인터페이스에 선언된 메서드만 사용할 수 있음</li>
</ul>
<p><img src="https://images.velog.io/images/migratory_bird/post/b85a03dc-af87-46c9-86e4-f893f0740eb0/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[27강. 추상클래스와 템플릿 메서드 활용(2)]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-27</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-27</guid>
            <pubDate>Thu, 03 Mar 2022 15:52:05 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>27강 &quot;추상클래스와 템플릿 메서드 활용(2)&quot;</li>
<li>추상 클래스와 템플릿 메서드 &gt; final 예약어 &gt; 템플릿 메서드 구현 예</li>
</ul>
<h1 id="추상-클래스와-템플릿-메서드">추상 클래스와 템플릿 메서드</h1>
<ul>
<li>템플릿 메서드 : 추상 메서드나 구현된 메서드를 활용하여 전체 기능의 흐름(시나리오)을 정의하는 메서드. (final로 선언하면 하위 클래스에서 재정의할 수 없음)</li>
<li>프레임워크에서 많이 사용되는 설계 패턴</li>
<li>추상 클래스로 선언된 상위 클래스에 템플릿 메서드를 활용하여 전체적인 흐름을 정의하고, 하위 클래스에서 다르게 구현되어야 하는 부분은 추상 메서드로 선언해서 하위 클래스가 구현하도록 함.</li>
</ul>
<p>예시를 위해 Car 클래스를 추상 클래스로 만들고 하위 클래스로 ManualCar, AICar 클래스를 만들어주겠다.</p>
<pre><code class="language-java">public abstract class Car {
    public abstract void drive();
    public abstract void stop();

    public void startCar() {
        System.out.println(&quot;시동을 켭니다.&quot;);
    }
    public void turnOff() {
        System.out.println(&quot;시동을 끕니다.&quot;);
    }
    public final void run() {
        startCar();
        drive();
        stop();
        turnOff();
    }
}</code></pre>
<p>시동을 키고 끄는 메서드는 모든 차량이 동일하고, 운전과 정지 메서드는 차량마다 다른 동작을 하기 위해 추상 메서드로 만들어주었다.
여기서 run() 메서드를 통해 시동을 키고, 운전 하고, 멈추고, 시동을 끄는 과정을 모든 차량이 그대로(수정 불가하게) 동작하게 만들기 위해 final 키워드를 이용하여 정의하였다.
이것을 템플릿 메서드라고 한다.</p>
<pre><code class="language-java">public class ManualCar extends Car{
    @Override
    public void drive() {
        System.out.println(&quot;사람이 운전합니다.&quot;);
        System.out.println(&quot;사람이 핸들을 조작합니다.&quot;);
    }
    @Override
    public void stop() {
        System.out.println(&quot;사람이 브레이크로 정지합니다.&quot;);
    }
}</code></pre>
<p>ManualCar 클래스는 Car 클래스를 상속받고 drive()와 stop() 메서드는 사람이 운전, 정지한다고 출력한다.</p>
<pre><code class="language-java">public class AICar extends Car{
    @Override
    public void drive() {
        System.out.println(&quot;자율 주행합니다.&quot;);
        System.out.println(&quot;자동차가 스스로 방향을 전환합니다.&quot;);
    }
    @Override
    public void stop() {
        System.out.println(&quot;자동차가 스스로 멈춥니다.&quot;);
    }
}</code></pre>
<p>AICar 클래스는 Car 클래스를 상속받고 drive()와 stop() 메서드는 자동차 스스로 한다고 출력한다.</p>
<pre><code class="language-java">public class CarTest {
    public static void main(String[] args) {
        Car myCar = new ManualCar();
        myCar.run();
        System.out.println(&quot;====================&quot;);
        Car yourCar = new AICar();
        yourCar.run();
    }
}</code></pre>
<p>ManualCar와 AICar 인스턴스를 생성하고 run() 메서드를 실행하면 정상 출력되는 것을 확인할 수 있다.</p>
<p><img src="https://images.velog.io/images/migratory_bird/post/63627ffa-7978-4c06-9e3d-3b41a6f482fc/image.png" alt=""></p>
<h1 id="final-예약어">final 예약어</h1>
<ul>
<li>final 변수는 값이 변경될 수 없는 상수임</li>
<li>final 변수는 오직 한 번만 값을 할당할 수 있음</li>
<li>final 메서드는 하위 클래스에서 재정의(overriding)할 수 없음</li>
<li>final 클래스는 더이상 상속되지 않음 (ex. java의 String 클래스)<pre><code class="language-java">public static final double PI = 3.14;</code></pre>
여러 자바 파일에서 공유하는 상수 값을 정의할 때 하나의 파일에 선언하여 사용하면 편리함<pre><code class="language-java">public class Define{
  public static final int MIN = 1;
  public static final int MAX = 99999;
  public static final int ENG = 1001;
  public static final int MATH = 2001;
}
public class UsingDefine{
  public static void main(String[] args){
      System.out.println(&quot;수학 과목 코드 값은 &quot; + Define.MATH + &quot; 입니다.&quot;);
  }
}</code></pre>
</li>
</ul>
<h1 id="템플릿-메서드-구현-예">템플릿 메서드 구현 예</h1>
<p><img src="https://images.velog.io/images/migratory_bird/post/4d6a9af0-9cb8-4cbb-bded-6fb47e292547/image.png" alt=""></p>
<ul>
<li>각 PlayerLevel 별 가능한 기능은 다름</li>
<li>단, 기능의 순서는 run(), jump(), turn() 의 순서임</li>
<li>기능의 순서와 반복에 대한 구현은 go(int) 메서드에서 구현되어 있음(템플릿 메서드)</li>
</ul>
<pre><code class="language-java">public abstract class PlayerLevel {
    public abstract void run();
    public abstract void jump();
    public abstract void turn();
    public abstract void showLevelMessage();

    final public void go(int count) {
        run();
        for(int i=0; i&lt;count; i++) {
            jump();
        }
        turn();
    }
}</code></pre>
<p>PlayerLevel 클래스는 추상 클래스로, 각각의 레벨에서 run(), jump(), turn() 메서드를 다르게 활용하기 위해 추상 메서드로 만들어주었다.
go(int) 메서드는 모든 클래스에서 동일하게 작동하기 위해 final로 선언하였다.</p>
<pre><code class="language-java">public class BeginnerLevel extends PlayerLevel {
    @Override
    public void run() {
        System.out.println(&quot;천천히 달립니다.&quot;);
    }
    @Override
    public void jump() {
        System.out.println(&quot;jump 할 줄 모르지롱~&quot;);
    }
    @Override
    public void turn() {
        System.out.println(&quot;turn 할 줄 모르지롱~&quot;);
    }
    @Override
    public void showLevelMessage() {
        System.out.println(&quot;***** 초보자 레벨입니다. *****&quot;);
    }
}</code></pre>
<pre><code class="language-java">public class AdvancedLevel extends PlayerLevel {
    @Override
    public void run() {
        System.out.println(&quot;빨리 달립니다.&quot;);
    }
    @Override
    public void jump() {
        System.out.println(&quot;높이 jump 합니다.&quot;);
    }
    @Override
    public void turn() {
        System.out.println(&quot;turn 할 줄 모르지롱~&quot;);
    }
    @Override
    public void showLevelMessage() {
        System.out.println(&quot;***** 중급자 레벨입니다. *****&quot;);
    }
}</code></pre>
<pre><code class="language-java">public class SuperLevel extends PlayerLevel {
    @Override
    public void run() {
        System.out.println(&quot;엄청 빨리 달립니다.&quot;);
    }
    @Override
    public void jump() {
        System.out.println(&quot;엄청 높이 jump 합니다.&quot;);
    }
    @Override
    public void turn() {
        System.out.println(&quot;한 바퀴 돕니다.&quot;);
    }
    @Override
    public void showLevelMessage() {
        System.out.println(&quot;***** 고급 레벨입니다. *****&quot;);
    }
}</code></pre>
<p>BeginnerLevel, AdvancedLevel, SuperLevel 클래스는 PlayerLevel 클래스를 상속받아 추상 메서드를 각각 작성하였다.</p>
<pre><code class="language-java">public class Player {
    private PlayerLevel level;
    public Player() {
        level = new BeginnerLevel();
        level.showLevelMessage();
    }
    public PlayerLevel getLevel() {
        return level;
    }
    public void upgradeLevel(PlayerLevel level) {
        this.level = level;
        level.showLevelMessage();
    }
    public void play(int count) {
        level.go(count);
    }
}</code></pre>
<p>Player 클래스는 PlayerLevel 자료형의 level 변수를 선언하였고, upgradeLevel() 메서드를 통해 레벨을 변화시킬 수 있다.</p>
<pre><code class="language-java">public class MainBoard {
    public static void main(String[] args) {
        Player player = new Player();
        player.play(1);

        AdvancedLevel aLevel = new AdvancedLevel();
        player.upgradeLevel(aLevel);
        player.play(2);

        SuperLevel sLevel = new SuperLevel();
        player.upgradeLevel(sLevel);
        player.play(3);
    }
}</code></pre>
<p>main 함수에서 player의 레벨을 변화시키고 play() 메서드를 실행하면 정상 출력된다.</p>
<p><img src="https://images.velog.io/images/migratory_bird/post/c46e97ea-48c8-4ae2-829e-41f535508f4f/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[26강. 추상클래스 활용하기(1)]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-26</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-26</guid>
            <pubDate>Wed, 02 Mar 2022 15:44:11 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>26강 &quot;추상클래스 활용하기(1)&quot;</li>
<li>추상 클래스란? (abstract class) &gt; 추상 클래스와 템플릿 메서드 &gt; 추상 클래스의 사용 &gt; 추상 클래스 구현하기</li>
</ul>
<h1 id="추상-클래스란-abstract-class">추상 클래스란? (abstract class)</h1>
<ul>
<li>추상 메서드를 포함한 클래스</li>
<li>추상 메서드는 구현코드 없이 메서드의 선언만 있음</li>
<li>abstract 예약어 사용</li>
<li>추상 클래스는 new (인스턴스화) 할 수 없음</li>
</ul>
<h1 id="추상-클래스와-템플릿-메서드">추상 클래스와 템플릿 메서드</h1>
<ul>
<li>템플릿 메서드 : 추상 메서드나 구현된 메서드를 활용하여 전체 기능의 흐름(시나리오)을 정의하는 메서드. (final로 선언하면 하위 클래스에서 재정의할 수 없음)</li>
<li>프레임워크에서 많이 사용되는 설계 패턴</li>
<li>추상 클래스로 선언된 상위 클래스에 템플릿 메서드를 활용하여 전체적인 흐름을 정의하고, 하위 클래스에서 다르게 구현되어야 하는 부분은 추상 메서드로 선언해서 하위 클래스가 구현하도록 함.</li>
</ul>
<h1 id="추상-클래스의-사용">추상 클래스의 사용</h1>
<ul>
<li>추상 클래스는 상속을 위한 클래스</li>
<li>추상 메서드 : 하위 클래스가 구현해야 할 메서드로, 각 하위 클래스마다 다르게 구현되어야 하는 기능</li>
<li>구현된 메서드 : 하위 클래스가 공통으로 사용할 수 있는 기능 구현. 경우에 따라서는 하위 클래스가 재정의(overriding) 할 수 있음</li>
</ul>
<h1 id="추상-클래스-구현하기">추상 클래스 구현하기</h1>
<ul>
<li>메서드에 구현 코드가 없으면 abstract로 선언해야 함</li>
<li>abstract로 선언된 메서드를 가진 클래스는 abstract로 선언함</li>
<li>모든 메서드가 구현코드가 있지만 클래스가 abstract로 선언된 경우에도 추상 클래스가 된다.
(new 할 수 없음)</li>
<li>추상 클래스의 추상 메서드는 하위 클래스에서 반드시 구현되어야 함.</li>
</ul>
<pre><code class="language-java">//추상 메서드를 포함하므로 추상 클래스임. (abstract 예약어 사용)
public abstract class Computer {
    //추상 메서드 (상속받는 class에서 구현해야 함)
    public abstract void display();
    public abstract void typing();

    // 구현 내용이 있으므로 추상 메서드가 아님
    public void turnOn() {
        System.out.println(&quot;전원을 켭니다.&quot;);
    }
    public void turnOff() {
        System.out.println(&quot;전원을 끕니다.&quot;);
    }
}</code></pre>
<pre><code class="language-java">//Computer(abstract 클래스)를 상속받으므로 추상 메서드를 모두 구현해야 함
public class DeskTop extends Computer{
    @Override
    public void display() {
        System.out.println(&quot;DeskTop display()&quot;);
    }
    @Override
    public void typing() {
        System.out.println(&quot;DeskTop typing()&quot;);
    }
}</code></pre>
<pre><code class="language-java">//추상 메서드를 모두 구현하지 않으면 자기 자신이 추상 클래스가 되어야 함
public abstract class NoteBook extends Computer {
    @Override
    public void display() {
        System.out.println(&quot;NoteBook display()&quot;);
    }
}</code></pre>
<pre><code class="language-java">//NoteBook 클래스에서 구현한 추상 메서드는 다시 구현할 필요 없음
public class MyNoteBook extends NoteBook{
    @Override
    public void typing() {
        System.out.println(&quot;MyNoteBook typing()&quot;);
    }
}</code></pre>
<p>예시로 작성하지는 않았지만 추상 클래스의 추상 메서드를 하위 클래스가 overriding 하여 재정의 할 수 있다.</p>
<pre><code class="language-java">Computer c1 = new Computer();    //error! 추상 클래스는 new(인스턴스화) 불가
Computer c2 = new DeskTop();    //DeskTop 클래스는 인스턴스화 가능하며, 업캐스팅 가능
Computer c3 = new MyNoteBook();    //MyNoteBook 클래스는 인스턴스화 가능
NoteBook c4 = new MyNoteBook();    //MyNoteBook 클래스는 Computer와 NoteBook으로 업캐스팅 가능</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[25강. 다형성 활용과 다운캐스팅(4)]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-25</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-25</guid>
            <pubDate>Tue, 01 Mar 2022 12:39:54 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>25강 &quot;다형성 활용과 다운캐스팅(4)&quot;</li>
<li>다형성 활용하기 &gt; 상속은 언제 사용할까? &gt; 다운 캐스팅 - instanceof</li>
</ul>
<p>지난 강의에서 다형성을 활용해보기 위해 GoldCustomer 클래스를 만들어주었다.
이번 시간에는 교재에 있는 내용대로 만들어보겠다.</p>
<h1 id="다형성-활용하기">다형성 활용하기</h1>
<pre><code class="language-java">public class Customer {
    protected int customerID;
    protected String customerName;
    protected String customerGrade;
    int bonusPoint;
    double bonusRatio;

    public Customer(int customerID, String customerName) {
        this.customerID = customerID;
        this.customerName = customerName;
        customerGrade = &quot;SILVER&quot;;
        bonusRatio = 0.01;
    }

    public int calcPrice(int price) {
        bonusPoint += price * bonusRatio;
        return price;
    }
    public String showCustomerInfo() {
        return (customerName + &quot;님의 등급은 &quot; + customerGrade + &quot;이며, 보너스 포인트는 &quot; + bonusPoint + &quot;입니다.&quot;);
    }

    public int getCustomerID() {
        return customerID;
    }

    public void setCustomerID(int customerID) {
        this.customerID = customerID;
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

    public String getCustomerGrade() {
        return customerGrade;
    }

    public void setCustomerGrade(String customerGrade) {
        this.customerGrade = customerGrade;
    }
}</code></pre>
<pre><code class="language-java">public class VIPCustomer extends Customer{
    private int agentID;
    private double saleRatio;

    public VIPCustomer(int customerID, String customerName, int agentID) {
        super(customerID, customerName);
        customerGrade = &quot;VIP&quot;;
        bonusRatio = 0.05;
        saleRatio = 0.1;
        this.agentID = agentID;
    }

    @Override
    public int calcPrice(int price) {
        bonusPoint += price * bonusRatio;
        return price - (int)(price * saleRatio);
    }

    @Override
    public String showCustomerInfo() {
        return super.showCustomerInfo() + &quot; 담당 상담원 아이디는 &quot; + agentID + &quot;입니다.&quot;;
    }

    public int getAgentID() {
        return agentID;
    }
}</code></pre>
<pre><code class="language-java">public class GoldCustomer extends Customer{
    private double saleRatio;

    public GoldCustomer(int customerID, String customerName) {
        super(customerID, customerName);
        customerGrade = &quot;Gold&quot;;
        bonusRatio = 0.02;
        saleRatio = 0.1;
    }

    @Override
    public int calcPrice(int price) {
        bonusPoint += price * bonusRatio;
        return price - (int)(price*saleRatio);
    }
}</code></pre>
<pre><code class="language-java">import java.util.ArrayList;

public class CustomerTest {
    public static void main(String[] args) {
        ArrayList&lt;Customer&gt; customerList = new ArrayList&lt;Customer&gt;();

        Customer customerLee = new Customer(10010, &quot;이순신&quot;);
        Customer customerShin= new Customer(10011, &quot;신사임당&quot;);
        GoldCustomer customerHong = new GoldCustomer(10012, &quot;홍길동&quot;);
        GoldCustomer customerYul = new GoldCustomer(10013, &quot;율곡&quot;);
        VIPCustomer customerKim = new VIPCustomer(10014, &quot;김유신&quot;, 100);

        customerList.add(customerLee);
        customerList.add(customerShin);
        customerList.add(customerHong);
        customerList.add(customerYul);
        customerList.add(customerKim);

        System.out.println(&quot;============= 고객정보 출력 ==============&quot;);
        for(Customer customer : customerList) {
            System.out.println(customer.showCustomerInfo());
        }

        System.out.println(&quot;========== 할인율과 보너스 포인트 결과 ===========&quot;);
        int price = 10000;
        for(Customer customer : customerList) {
            int cost = customer.calcPrice(price);
            System.out.println(customer.getCustomerName() + &quot;님이 &quot; + cost + &quot;원을 지불하셨습니다.&quot;);
            System.out.println(customer.showCustomerInfo());
        }
    }
}</code></pre>
<p><img src="https://images.velog.io/images/migratory_bird/post/a96c9e8d-b5e3-4039-b4bc-7e844c870bdf/image.png" alt=""></p>
<h1 id="상속은-언제-사용할까">상속은 언제 사용할까?</h1>
<ul>
<li>여러 클래스를 생성하지 않고 하나의 클래스에 공통적인 요소를 모으고 나머지 클래스는 이를 상속받은 다음 각각 필요한 특성과 메서드를 구현하는 방법을 사용한다.</li>
<li>하나의 클래스에 여러 특성을 한꺼번에 구현하는 경우 많은 코드 내에 많은 if문이 생길 수 있다.</li>
</ul>
<blockquote>
<ul>
<li>IS-A 관계 (is a relatioship : inheritance)
일반적인(general) 개념과 구체적인(specific) 개념과의 관계
상위 클래스 : 일반적인 개념 클래스 (예 : 포유류)
하위 클래스 : 구체적인 개념 클래스 (예 : 사람, 원숭이, 고래...)
단순히 코드를 재사용하는 목적으로 사용하지 않음</li>
<li>HAS-A 관계(composition)
한 클래스가 다른 클래스를 소유한 관계
코드 재사용의 한 방법으로, 클래스 안에서 다른 클래스를 객체로 생성하는 경우를 말함</li>
</ul>
</blockquote>
<pre><code class="language-java">// HAS-A 관계
class Student {
    Subject majorSubject;
}</code></pre>
<h1 id="다운-캐스팅---instanceof">다운 캐스팅 - instanceof</h1>
<ul>
<li>하위 클래스가 상위 클래스로 형변환되는 것은 묵시적으로 이루어진다.</li>
<li>다시 원래 자료형인 하위 클래스로 형변환 하려면 명시적으로 다운 캐스팅을 해야한다.</li>
<li>이 때, 원래 인스턴스의 타입을 체크하는 예약어가 instanceof 이다. </li>
</ul>
<p><img src="https://images.velog.io/images/migratory_bird/post/85d610fc-b637-4aa5-9df6-1cd08c14910d/image.png" alt=""></p>
<p>지난 강의에서 다형성 예제에 사용한 Animal 클래스이다.
Human, Tiger, Eagle 클래스에 각각 고유의 메서드를 추가하고,
Test 클래스의 메서드에서 다운캐스팅을 활용해 해당 메서드를 호출하는 코드이다.</p>
<pre><code class="language-java">class Animal{
    public void move() {
        System.out.println(&quot;동물이 움직입니다.&quot;);
    }
}
class Human extends Animal{
    public void move() {
        System.out.println(&quot;사람이 두발로 걷습니다.&quot;);
    }
    public void readBook() {
        System.out.println(&quot;사람이 책을 읽습니다.&quot;);
    }
}
class Tiger extends Animal{
    public void move() {
        System.out.println(&quot;호랑이가 네발로 뜁니다.&quot;);
    }
    public void hunting() {
        System.out.println(&quot;호랑이가 사냥을 합니다.&quot;);
    }
}
class Eagle extends Animal{
    public void move() {
        System.out.println(&quot;독수리가 하늘을 납니다.&quot;);
    }
    public void flying() {
        System.out.println(&quot;독수리가 하늘을 납니다.&quot;);
    }
}

public class AnimalTest {
    public static void main(String[] args) {
        AnimalTest test = new AnimalTest();
        test.moveAnimal(new Human());
        test.moveAnimal(new Tiger());
        test.moveAnimal(new Eagle());
    }
    public void moveAnimal(Animal animal) {
        animal.move();
        if(animal instanceof Human) {
            Human human = (Human)animal;
            human.readBook();
        }else if(animal instanceof Tiger) {
            Tiger tiger = (Tiger)animal;
            tiger.hunting();
        }else if(animal instanceof Eagle) {
            Eagle eagle = (Eagle)animal;
            eagle.flying();
        }else {
            System.out.println(&quot;지원되지 않는 기능입니다.&quot;);
        }
    }
}</code></pre>
<p><img src="https://images.velog.io/images/migratory_bird/post/e6abb548-263f-4b88-a6e7-e3438995ddcd/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[24강. 오버라이딩과 다형성(3)]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-24</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-24</guid>
            <pubDate>Tue, 01 Mar 2022 05:22:36 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>24강 &quot;오버라이딩과 다형성(3)&quot;</li>
<li>메서드 오버라이딩(overridind) &gt; 다형성 (polymorphism) &gt; 다형성 활용하기</li>
</ul>
<h1 id="메서드-오버라이딩overridind">메서드 오버라이딩(overridind)</h1>
<ul>
<li>상위 클래스에 정의된 메서드 중 하위 클래스와 기능이 맞지 않거나 추가 기능이 필요한 경우 같은 이름과 매개변수로 하위 클래스에서 재정의 하는 것이다.</li>
</ul>
<p>Customer 클래스(상위 클래스)와 VIPCustomer 클래스(하위 클래스)에 가격을 매개변수로 받는 calcPrice() 메서드를 이름은 동일하지만 return 값은 다르게 추가하여 확인해보겠다.</p>
<pre><code class="language-java">public class Customer {
    public int calcPrice(int price) {
        bonusPoint += price * bonusRatio;
        return price;
    }
}</code></pre>
<pre><code class="language-java">public class VIPCustomer extends Customer{
    public int calcPrice(int price) {
        bonusPoint += price * bonusRatio;
        return price - (int)(price * saleRatio);
    }
}</code></pre>
<p>main 함수에서 Customer 객체와 VIPCustomer 객체를 생성하여 출력해보면 VIPCustomer 의 메서드는 overriding 되어 VIPCustomer 클래스의 메서드가 적용된다.</p>
<pre><code class="language-java">public class OverridingTest {
    public static void main(String[] args) {
        Customer customerLee = new Customer(100010, &quot;Lee&quot;);
        int price1 = customerLee.calcPrice(10000);
        customerLee.showCustomerInfo();
        System.out.println(customerLee.getCustomerName() + &quot;님의 지불 금액은 &quot; + price1 + &quot;입니다.&quot;);

        VIPCustomer customerKim = new VIPCustomer(100020, &quot;Kim&quot;, 100);
        int price2 = customerKim.calcPrice(10000);
        customerKim.showCustomerInfo();
        System.out.println(customerKim.getCustomerName() + &quot;님의 지불 금액은 &quot; + price2 + &quot;입니다.&quot;);
    }
}</code></pre>
<p><img src="https://images.velog.io/images/migratory_bird/post/95ce8701-37e7-4f00-a68e-6bab56c9d753/image.png" alt=""></p>
<h3 id="묵시적-형변환과-재정의된-메서드-호출">묵시적 형변환과 재정의된 메서드 호출</h3>
<ul>
<li>형변환(업캐스팅)된 객체에서는 재정의된 메서드가 호출된다.</li>
</ul>
<pre><code class="language-java">public class OverridingTest {
    public static void main(String[] args) {
        Customer customerPark = new VIPCustomer(100020, &quot;Park&quot;, 100);
        int price3 = customerPark.calcPrice(10000);
        customerPark.showCustomerInfo();
        System.out.println(customerPark.getCustomerName() + &quot;님의 지불 금액은 &quot; + price3 + &quot;입니다.&quot;);
    }
}
</code></pre>
<p><img src="https://images.velog.io/images/migratory_bird/post/3e7325c0-bd13-4a86-b561-50d1fc7ece39/image.png" alt=""></p>
<h3 id="가상-메서드-virtual-method">가상 메서드 (virtual method)</h3>
<ul>
<li>프로그램에서 어떤 객체의 변수나 메서드의 참조는 그 타입에 따라 이루어진다.
(가상 메서드의 경우는 타입과 상관없이 실제 생성된 인스턴스의 메서드가 호출되는 원리)</li>
<li>customerPark의 타입은 Customer 이지만, 실제 생성된 인스턴스인 VIPCustomer 클래스의 calcPrice 메서드가 호출된다.</li>
</ul>
<p><img src="https://images.velog.io/images/migratory_bird/post/4ae44cb7-8517-4b9c-b23d-71625b3d03aa/image.png" alt=""></p>
<h1 id="다형성-polymorphism">다형성 (polymorphism)</h1>
<ul>
<li>하나의 코드가 여러가지 자료형으로 구현되어 실행되는 것</li>
<li>정보은닉, 상속과 더불어 객체지향 프로그래밍의 가장 큰 특징 중 하나</li>
<li>객체지향 프로그래밍의 유연성, 재활용성, 유지보수성에 기본이 되는 특징이다.</li>
</ul>
<h3 id="다형성-구현하기">다형성 구현하기</h3>
<pre><code class="language-java">class Animal{
    public void move() {
        System.out.println(&quot;동물이 움직입니다.&quot;);
    }
}
class Human extends Animal{
    public void move() {
        System.out.println(&quot;사람이 두발로 걷습니다.&quot;);
    }
}
class Tiger extends Animal{
    public void move() {
        System.out.println(&quot;호랑이가 네발로 뜁니다.&quot;);
    }
}
class Eagle extends Animal{
    public void move() {
        System.out.println(&quot;독수리가 하늘을 납니다.&quot;);
    }
}

public class AnimalTest {
    public static void main(String[] args) {
        AnimalTest test = new AnimalTest();
        test.moveAnimal(new Human());
        test.moveAnimal(new Tiger());
        test.moveAnimal(new Eagle());
    }
    public void moveAnimal(Animal animal) {
        animal.move();
    }
}</code></pre>
<p>위 코드는 Animal 클래스를 상속받는 Human, Tiger, Eagle 클래스를 만들고
각각 move() 메서드를 통해 다른 메시지를 출력하도록 overriding 한 것이다.
Test 클래스에서는 moveAnimal() 메서드에서 Animal를 매개변수로 받으면 해당 객체의 move() 메서드를 호출하는 메서드를 만들었고, main 함수에서 각각 Human, Tiger, Eagle 인스턴스를 생성하여 매개변수로 moveAnimal에 넣어주었다.
<img src="https://images.velog.io/images/migratory_bird/post/82d9f891-f0a6-4561-ae05-3040e4f42b3c/image.png" alt="">
moveAnimal() 메서드에서는 animal.move(); 라는 코드 한 줄이 쓰여있지만 실제 구현될 때는 여러 결과가 나타나게 되고, 이것을 다형성이라고 한다.</p>
<h1 id="다형성-활용하기">다형성 활용하기</h1>
<ul>
<li>일반 고객과 VIP 고객의 중간 등급(Gold)의 고객을 생성</li>
<li>5명의 고객을 ArrayList에 생성하여 저장한 다음 각 고객이 물건을 샀을 때의 가격과 보너스 포인트를 계산함</li>
</ul>
<p>일단, GoldCustomer 클래스를 생성하여 Customer 클래스를 상속받도록 만들어준다.</p>
<pre><code class="language-java">public class GoldCustomer extends Customer{
    public GoldCustomer(int customerID, String customerName) {
        super(customerID, customerName);
        customerGrade = &quot;Gold&quot;;
        bonusRatio = 0.05;
    }
}</code></pre>
<p>main 함수가 있는 Test 클래스에서는 다형성을 활용하기 위해 showInfoAndPrice() 메서드를 만들고 Customer 객체를 매개변수로 받는다.</p>
<pre><code class="language-java">public class OverridingTest {
    public static void main(String[] args) {
        OverridingTest test = new OverridingTest();
        test.showInfoAndPrice(new Customer(1001, &quot;customerLee&quot;));
        test.showInfoAndPrice(new VIPCustomer(1002, &quot;customerKim&quot;, 100));
        test.showInfoAndPrice(new GoldCustomer(1003, &quot;customerPark&quot;));
    }
    public void showInfoAndPrice(Customer customer) {
        int price = customer.calcPrice(10000);
        customer.showCustomerInfo();
        System.out.println(customer.getCustomerName() + &quot;님의 지불 금액은 &quot; + price + &quot;입니다.&quot;);
    }
}</code></pre>
<p>main함수에서 Customer, VIPCustomer, GoldCustomer 객체로 showInfoAndPrice() 메서드를 호출하면 결과가 각각 정상적으로 출력되는 것을 확인할 수 있다.</p>
<p><img src="https://images.velog.io/images/migratory_bird/post/2b46c8f7-ad4a-44d5-a871-1d5246f38431/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[23강. 상속과 다형성(2)]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-23</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-23</guid>
            <pubDate>Mon, 28 Feb 2022 15:56:59 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>23강 &quot;상속과 다형성(2)&quot;</li>
<li>접근 제한자 가시성 &gt; 상속에서 클래스 생성 과정 &gt; 상속에서의 메모리 상태 &gt; super 예약어 &gt; 상위 클래스로의 묵시적 형변환 (업캐스팅)</li>
</ul>
<p>지난 강의에서 사용한 Customer 클래스와 VIPCustomer 클래스를 수정하면서 강의가 진행된다.</p>
<pre><code class="language-java">public class Customer {
    protected int customerID;
    protected String customerName;
    protected String customerGrade;
    int bonusPoint;
    double bonusRatio;

    public Customer() {
        customerGrade = &quot;SILVER&quot;;
        bonusRatio = 0.01;
    }

    public int calcPrice(int price) {
        bonusPoint += price * bonusPoint;
        return price;
    }
    public void showCustomerInfo() {
        System.out.println(customerName + &quot;님의 등급은 &quot; + customerGrade + &quot;이며, 보너스 포인트는 &quot; + bonusPoint + &quot;입니다.&quot;);
    }

    public int getCustomerID() {
        return customerID;
    }

    public void setCustomerID(int customerID) {
        this.customerID = customerID;
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

    public String getCustomerGrade() {
        return customerGrade;
    }

    public void setCustomerGrade(String customerGrade) {
        this.customerGrade = customerGrade;
    }
}</code></pre>
<pre><code class="language-java">public class VIPCustomer extends Customer{
    private int agentID;
    private double saleRatio;

    public VIPCustomer() {
        customerGrade = &quot;VIP&quot;;
        bonusRatio = 0.05;
        saleRatio = 0.1;
    }

    public int getAgentID() {
        return agentID;
    }
}
</code></pre>
<h1 id="접근-제한자-가시성">접근 제한자 가시성</h1>
<table>
<thead>
<tr>
<th align="center"></th>
<th align="center">외부 클래스</th>
<th align="center">하위 클래스</th>
<th align="center">동일 패키지</th>
<th align="center">내부 클래스</th>
</tr>
</thead>
<tbody><tr>
<td align="center">public</td>
<td align="center">O</td>
<td align="center">O</td>
<td align="center">O</td>
<td align="center">O</td>
</tr>
<tr>
<td align="center">protected</td>
<td align="center">X</td>
<td align="center">O</td>
<td align="center">O</td>
<td align="center">O</td>
</tr>
<tr>
<td align="center">선언되지 않음 <br> (default)</td>
<td align="center">X</td>
<td align="center">X</td>
<td align="center">O</td>
<td align="center">O</td>
</tr>
<tr>
<td align="center">private</td>
<td align="center">X</td>
<td align="center">X</td>
<td align="center">X</td>
<td align="center">O</td>
</tr>
</tbody></table>
<h1 id="상속에서-클래스-생성-과정">상속에서 클래스 생성 과정</h1>
<ul>
<li>하위 클래스가 생성될 때 상위 클래스가 먼저 생성된다.</li>
<li>상위 클래스의 생성자가 호출되고 하위 클래스의 생성자가 호출된다.</li>
</ul>
<p>Customer 클래스의 기본 생성자와 VIPCustomer 클래스의 기본 생성자에 출력문을 추가하여 확인해보자.</p>
<pre><code class="language-java">public class Customer {
    Customer(){
        System.out.println(&quot;Customer() 호출&quot;);
    }
}

public class VIPCustomer extends Customer{
    public VIPCustomer() {
        System.out.println(&quot;VIPCustomer() 호출&quot;);
    }
}</code></pre>
<p>main 함수가 있는 CustomerTest 클래스에서 VIPCustomer 객체를 생성하여 출력해보면 상위 클래스인 Customer 클래스의 생성자가 먼저 호출된 것을 확인할 수 있다.</p>
<pre><code class="language-java">public class CustomerTest {
    public static void main(String[] args) {
        VIPCustomer customerKim = new VIPCustomer();
    }
}</code></pre>
<p><img src="https://images.velog.io/images/migratory_bird/post/87252905-6b32-4d8f-9bdb-6f275c4d9346/image.png" alt=""></p>
<ul>
<li>하위 클래스의 생성자에서는 무조건 상위 클래스의 생성자가 호출되어야 한다.</li>
<li>아무것도 없는 경우 컴파일러는 상위 클래스 기본 생성자를 호출하기 위한 super() 를 코드에 넣어준다.</li>
<li>super() 는 상위 클래스의 기본 생성자이다.</li>
</ul>
<p>즉, 위 코드에서 VIPCustomer 클래스의 생성자에는 super() 를 자동으로 호출해준 것이다.
Customer 클래스의 생성자도 super() 가 자동으로 호출되는데, java의 최상위 클래스인 Object 클래스의 생성자가 호출된 것이다.</p>
<pre><code class="language-java">public class VIPCustomer extends Customer{
    public VIPCustomer() {
        super();
        System.out.println(&quot;VIPCustomer() 호출&quot;);
    }
}</code></pre>
<ul>
<li>만약 상위 클래스의 기본 생성자가 없는 경우 (매개변수가 있는 생성자만 존재하는 경우) 하위 클래스는 명시적으로 상위 클래스를 호출해야 한다.</li>
</ul>
<p>Customer 클래스의 기본 생성자를 없애고, 매개변수를 받는 constructor를 만들어준다면 VIPCustomer 클래스의 생성자에서는 Super(매개변수)를 통해 생성자를 호출해주어야 한다.</p>
<pre><code class="language-java">public class Customer {
    Customer(int customerID, String customerName){
        this.customerID = customerID;
        this.customerName = customerName;
        System.out.println(&quot;Customer(int, String) 호출&quot;);
    }
}

public class VIPCustomer extends Customer{
    public VIPCustomer() {
        super(1001, &quot;이순신&quot;);
        System.out.println(&quot;VIPCustomer() 호출&quot;);
    }
    public VIPCustomer(int customerID, String customerName) {
        super(customerID, customerName);
        System.out.println(&quot;VIPCustomer(int, String) 호출&quot;);
    }
}</code></pre>
<h1 id="상속에서의-메모리-상태">상속에서의 메모리 상태</h1>
<ul>
<li>상위 클래스의 인스턴스가 먼저 생성이 되고, 하위 클래스의 인스턴스가 생성된다.</li>
<li>private 변수는 상위 클래스에서 생성되지만(메모리에 생성됨) 하위 클래스에서 보이지 않는 것이다.</li>
</ul>
<p><img src="https://images.velog.io/images/migratory_bird/post/d512d7c0-9ea2-4ad2-a37c-58ad82cf0c9e/image.png" alt=""></p>
<h1 id="super-예약어">super 예약어</h1>
<ul>
<li>this가 자기 자신의 인스턴스의 주소를 가지는 것처럼 super는 하위 클래스가 상위 클래스에 대한 주소를 가지게 된다.</li>
<li>하위 클래스가 상위 클래스에 접근할 때 사용할 수 있다.</li>
</ul>
<p><img src="https://images.velog.io/images/migratory_bird/post/42f80253-4920-4231-b247-24dc712cf7b7/image.png" alt=""></p>
<h1 id="상위-클래스로의-묵시적-형변환-업캐스팅">상위 클래스로의 묵시적 형변환 (업캐스팅)</h1>
<ul>
<li>상위 클래스 형으로 변수를 선언하고 하위 클래스 인스턴스를 생성할 수 있다.</li>
<li>하위 클래스는 상위 클래스의 타입을 내포하고 있으므로 상위 클래스로 묵시적 형변환이 가능하다.</li>
</ul>
<p><img src="https://images.velog.io/images/migratory_bird/post/f6bdc0ae-19f8-46f0-9346-323f14e265b9/image.png" alt=""></p>
<p>위 코드에서 vc는 VIPCustomer() 생성자를 호출했으므로 인스턴스는 모두 생성된다.
하지만 타입이 Customer 이므로 접근할 수 있는 변수나 메서드는 Customer 클래스의 변수와 메서드이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[22강. 상속과 다형성(1)]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-22</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-22</guid>
            <pubDate>Fri, 25 Feb 2022 15:23:39 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>22강 &quot;상속과 다형성(1)&quot;</li>
<li>상속이란? &gt; 상속을 활용한 고객관리 프로그램</li>
</ul>
<h1 id="상속이란">상속이란?</h1>
<ul>
<li>클래스를 정의할 때 이미 구현된 클래스를 상속(ingeritance) 받아서 속성이나 기능이 확장되는 클래스를 구현한다.</li>
<li>상속하는 클래스 : 상위 클래스, parent class, base class, super class</li>
<li>상속 받는 클래스 : 하위 클래스, child class, derived class, subclass</li>
</ul>
<p><img src="https://images.velog.io/images/migratory_bird/post/23ba027f-1e5c-48f1-bf82-6e8249379297/image.png" alt=""></p>
<pre><code class="language-java">//클래스 상속 문법
class B extends A{
    code...
}</code></pre>
<ul>
<li>상위 클래스는 하위 클래스보다 일반적인 의미를 가진다.</li>
<li>하위 클래스는 상위 클래스보다 구체적인 의미를 가진다.</li>
<li>extends 뒤에는 단 하나의 class만 사용할 수 있다. (자바는 single inheritance만 지원함)</li>
</ul>
<pre><code class="language-java">public class Piont{
    private int x;
    private int y;
    public int getX(){
        return x;
    }
    public void setX(int x){
        this.x = x;
    }
    public int getY(){
        return x;
    }
    public void setY(int y){
        this.y = y;
    }
}</code></pre>
<p>x와 y 값을 갖는 Point라는 클래스가 있다고 하자.
이 때, 중심(점)과 반지름을 갖는 Circle 클래스를 만든다면 Circle 클래스는 Point 클래스를 상속받는 것이 아니라 객체를 생성해서 변수에 넣어주면 된다.</p>
<pre><code class="language-java">//잘못된 코드
public Circle extends Point{
    private int radius;
}

//권장되는 코드
public Circle {
    Point point;
    private int radius;

    public Circle(){
        point = new Point();
    }
}</code></pre>
<p>Point 클래스가 일반적이고, Circle 클래스가 구체적인 관계가 아니기 때문에 상속 관계가 아닌 것이다.</p>
<h1 id="상속을-활용한-고객관리-프로그램">상속을 활용한 고객관리 프로그램</h1>
<ul>
<li>고객의 정보를 활용하여 고객 맞춤 서비스를 구현</li>
<li>고객의 등급에 따라 차별화된 할인율과 포인트를 지급</li>
<li>등급에 따른 클래스를 따로 구현하는 것이 아닌 일반적인 클래스를 먼저 구현하고, 그보다 기능이 많은 클래스는 상속을 활용하여 구현</li>
</ul>
<p><img src="https://images.velog.io/images/migratory_bird/post/e2916a02-9c08-44d4-930a-6a5cb1993776/image.png" alt=""></p>
<h3 id="customer-클래스-속성">Customer 클래스 속성</h3>
<table>
<thead>
<tr>
<th align="center">멤버 변수</th>
<th align="left">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="center">customerID</td>
<td align="left">고객 아이디</td>
</tr>
<tr>
<td align="center">customerName</td>
<td align="left">고객 이름</td>
</tr>
<tr>
<td align="center">customerGrade</td>
<td align="left">고객 등급 <br> 기본 생성자에서 지정되는 기본 등급은 SILVER</td>
</tr>
<tr>
<td align="center">bonusPoint</td>
<td align="left">고객의 보너스 포인트 <br> 고객이 제품을 구매할 경우 누적되는 보너스 포인트</td>
</tr>
<tr>
<td align="center">bonusRatio</td>
<td align="left">보너스 포인트 적립 비율 <br> 고객이 제품을 구매할 때 보너스 포인트로 적립될 적립 비율 <br> 기본 생성자에서 지정되는 적립 비율은 1%</td>
</tr>
</tbody></table>
<pre><code class="language-java">public class Customer {
    protected int customerID;
    protected String customerName;
    protected String customerGrade;
    int bonusPoint;
    double bonusRatio;

    public Customer() {
        customerGrade = &quot;SILVER&quot;;
        bonusRatio = 0.01;
    }

    public int calcPrice(int price) {
        bonusPoint += price * bonusPoint;
        return price;
    }
    public void showCustomerInfo() {
        System.out.println(customerName + &quot;님의 등급은 &quot; + customerGrade + &quot;이며, 보너스 포인트는 &quot; + bonusPoint + &quot;입니다.&quot;);
    }

    public int getCustomerID() {
        return customerID;
    }
    public void setCustomerID(int customerID) {
        this.customerID = customerID;
    }
    public String getCustomerName() {
        return customerName;
    }
    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }
    public String getCustomerGrade() {
        return customerGrade;
    }
    public void setCustomerGrade(String customerGrade) {
        this.customerGrade = customerGrade;
    }
}</code></pre>
<h3 id="새로운-고객-등급이-필요한-경우">새로운 고객 등급이 필요한 경우</h3>
<ul>
<li>단골 고객에 대한 혜택이 필요함</li>
<li>우수 고객을 관리하기 위해 다음과 같은 혜택을 줌</li>
<li>고객 등급 : VIP</li>
<li>제품 구매 할인율 : 10%</li>
<li>보너스 포인트 : 5%</li>
<li>담당 전문 상담원 배정</li>
</ul>
<pre><code class="language-java">public class VIPCustomer extends Customer{
    private int agentID;
    private double saleRatio;

    public VIPCustomer() {
        customerGrade = &quot;VIP&quot;;
        bonusRatio = 0.05;
        saleRatio = 0.1;
    }

    public int getAgentID() {
        return agentID;
    }
}</code></pre>
<p>child class는 parent class를 그대로 복사해와서 사용하므로 중복되는 변수나 메서드는 다시 선언할 필요가 없다.</p>
<blockquote>
<ul>
<li>potected 로 변수를 선언하면 상속받는 클래스에서 해당 변수에 접근할 수 있다.
(다른 패키지에 있어도 접근 가능)</li>
</ul>
</blockquote>
<ul>
<li>public 으로 선언하면 어디서든 접근 가능</li>
<li>private 으로 선언하면 해당 클래스 내부에서만 접근 가능</li>
<li>아무런 선언도 하지 않으면 (default) 같은 패키지 내에서 접근 가능</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[21. 이클립스에서 디버깅하기]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-21</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-21</guid>
            <pubDate>Thu, 24 Feb 2022 01:58:25 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>21강 &quot;이클립스에서 디버깅&quot;</li>
<li>디버그</li>
</ul>
<p><img src="https://images.velog.io/images/migratory_bird/post/585282f4-50dc-4892-83c9-f4d4446d2285/image.png" alt="">
Line을 표시하는 숫자 왼쪽 부분을 더블클릭하여 break point를 설정할 수 있다.</p>
<p><img src="https://images.velog.io/images/migratory_bird/post/57d8ea53-c06a-40c0-b721-bd96033d39ff/image.png" alt="">
위쪽 메뉴 아래 버튼에서 벌레(bug)모양의 버튼을 누르면 디버그 모드로 들어갈 수 있다. (단축키 : F11)</p>
<p><img src="https://images.velog.io/images/migratory_bird/post/d0073199-e0cc-4c9b-b834-21d46596d13b/image.png" alt="">
우측에 Java 버튼을 누르면 원래 화면으로 돌아갈 수 있다.</p>
<p><img src="https://images.velog.io/images/migratory_bird/post/b9801899-e8a0-4aa6-899f-7ce7cb41e726/image.png" alt="">
왼쪽 창에서 실행중인 Debug를 확인할 수 있고, 같은 코드를 여러개의 쓰레드에서 실행시킬 경우 성능 저하가 일어날 수 있으므로 사용하지 않는 쓰레드는 중지시켜준다.
(&lt; terminated &gt; 표시가 중지되었다는 의미)</p>
<p><img src="https://images.velog.io/images/migratory_bird/post/42e0a154-be9f-450a-a267-2f79a6e5dc78/image.png" alt="">
Step Into 버튼 (단축키 : F5) 누르면 해당하는 메서드가 있는 클래스로 들어간다.</p>
<p><img src="https://images.velog.io/images/migratory_bird/post/dd883c89-6fc6-4048-b3e9-a2320e2b87ef/image.png" alt="">
우측 Variable(변수) 창에서 변수의 상태 등을 확인할 수 있다.</p>
<p><img src="https://images.velog.io/images/migratory_bird/post/5fea7abd-7204-473a-bbaa-06d14f26267d/image.png" alt="">
Step Over 버튼 (단축키 : F6) 누르면 다음 줄의 코드를 실행한다.</p>
<p><img src="https://images.velog.io/images/migratory_bird/post/d2ec7011-fd30-44e8-a954-0e2f517e585b/image.png" alt="">
Step Return 버튼 (단축키 : F7) 누르면 다시 바깥 클래스로 나간다.</p>
<p><img src="https://images.velog.io/images/migratory_bird/post/7816a6fe-51d7-4bd9-a8d1-2d0df14d3a50/image.png" alt="">
Break Point가 두 개 이상 있을 경우 Resume 버튼 (단축키 : F8) 누르면 다음 Break Point까지 실행된다.</p>
<p><img src="https://images.velog.io/images/migratory_bird/post/f676eceb-715f-445a-908e-9b5ec8854a56/image.png" alt="">
우측 Expressions 탭에서는 Variables에 나오지 않은 다른 변수에 대해 알고 싶으면 추가해서 확인할 수 잇다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[20강. ArrayList 클래스]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-20</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-20</guid>
            <pubDate>Wed, 23 Feb 2022 02:41:01 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>20강 &quot;ArrayList 클래스&quot;</li>
<li>ArrayList 클래스 &gt; 주요 메서드 &gt; 사용 예제</li>
</ul>
<h1 id="arraylist-클래스">ArrayList 클래스</h1>
<ul>
<li>기존 배열은 길이를 정하여 선언하므로 사용 중 부족한 경우 다른 배열로 복사하는 코드를 직접 구현해야 한다.</li>
<li>중간의 요소가 삭제되거나 삽입되는 경우에도 나머지 요소에 대한 조정하는 코드를 구현해야 한다.</li>
<li>ArrayList 클래스는 자바에서 제공되는 객체 배열이 구현된 클래스이다.</li>
<li>여러 메서드와 속성 등을 사용하여 객체 배열을 편리하게 관리할 수 있다.</li>
<li>가장 많이 사용하는 객체 배열 클래스이다.</li>
<li>ArrayList 클래스를 import 해야 사용할 수 있다.</li>
</ul>
<pre><code class="language-java">//기본 문법
import java.util.ArrayList;
ArrayList&lt;자료형&gt; 변수명 = new ArrayList&lt;자료형&gt;();</code></pre>
<h1 id="주요-메서드">주요 메서드</h1>
<table>
<thead>
<tr>
<th align="left">메서드</th>
<th align="left">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="left">boolean add(E e)</td>
<td align="left">요소 하나를 배열에 추가한다. E는 요소의 자료형을 의미한다.</td>
</tr>
<tr>
<td align="left">int size()</td>
<td align="left">배열에 추가된 요소 전체 개수를 반환한다.</td>
</tr>
<tr>
<td align="left">E get(int index)</td>
<td align="left">배열의 index 위치에 있는 요소 값을 반환한다.</td>
</tr>
<tr>
<td align="left">E remove(int index)</td>
<td align="left">배열의 index 위치에 있는 요소 값을 제거하고 그 값을 반환한다.</td>
</tr>
<tr>
<td align="left">boolean isEmpty()</td>
<td align="left">배열이 비어있는지 확인한다.</td>
</tr>
</tbody></table>
<ul>
<li>요소를 추가하거나 제거할 때, 각 내부에서 코드가 모두 구현되어 있으므로 배열을 직접 선언하여 사용하는 것보다 편리하다.</li>
<li>주요 메서드는 자주 사용되는 메서드이며, eclipse에서 F1 키를 눌러서 다양한 메서드를 확인할 수 있다.</li>
</ul>
<pre><code class="language-java">import java.util.ArrayList;

public class BookArrayList {
    public static void main(String[] args) {
        //ArrayList 선언
        ArrayList&lt;Book&gt; library = new ArrayList&lt;Book&gt;();

        //add() 메서드로 요소 값 추가
        library.add(new Book(&quot;태백산맥&quot;, &quot;조정래&quot;));
        library.add(new Book(&quot;데미안&quot;, &quot;헤르만 헤세&quot;));
        library.add(new Book(&quot;어떻게 살 것인가&quot;, &quot;유시민&quot;));
        library.add(new Book(&quot;토지&quot;, &quot;박경리&quot;));
        library.add(new Book(&quot;어린왕지&quot;, &quot;생텍쥐페리&quot;));

        //배열에 추가된 요소 개수만큼 출력
        for(int i=0; i&lt;library.size(); i++) {
            Book book = library.get(i);
            book.showBookInfo();
        }
    }
}</code></pre>
<p>위 코드는 Book 클래스를 이용하여 객체 배열을 만들었던 예제(<a href="https://velog.io/@migratory_bird/Do-it-Java-Programming-18">18강. 객체 배열 사용하기</a>)를 ArrayList에 담아본 예제이다.</p>
<h1 id="사용-예제">사용 예제</h1>
<p>이것을 응용하여 학생과 과목 객체를 이용한 예제를 만들어보았다.</p>
<ul>
<li>Subject 클래스는 과목명과 점수를 private 멤버변수로 갖고 있고, get/set 메서드를 생성하였다.</li>
</ul>
<pre><code class="language-java">package arrayList;

public class Subject {
    private String name;
    private int scorePoint;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getScorePoint() {
        return scorePoint;
    }
    public void setScorePoint(int scorePoint) {
        this.scorePoint = scorePoint;
    }
}</code></pre>
<ul>
<li>Student 클래스는 멤버변수로 학번, 이름, 과목(Subject)를 갖고 있다.</li>
<li>학번은 static변수를 이용하여 객체가 생성될 때마다 1씩 더해서 대입하였고,
이름은 생성자의 매개변수로 받는다.
과목과 점수는 addSubject() 메서드를 통해 넣어주어야 한다.</li>
<li>showStudentInfo() 메서드를 통해 각 과목의 점수와 평균점수를 확인할 수 있다.</li>
</ul>
<pre><code class="language-java">import java.util.ArrayList;

public class Student {
    private static int serialNumber = 1000;
    private int studentID;
    private String studentName;
    private ArrayList&lt;Subject&gt; subjectList;

    public Student(String studentName) {
        serialNumber++;
        studentID = serialNumber;
        this.studentName = studentName;
        subjectList = new ArrayList&lt;Subject&gt;();
    }

    public void addSubject(String name, int score) {
        Subject subject = new Subject();
        subject.setName(name);
        subject.setScorePoint(score);

        subjectList.add(subject);
    }

    public void showStudentInfo() {
        int total = 0;
        for(Subject subject : subjectList) {
            total += subject.getScorePoint();
            System.out.println(studentName + &quot;님의 &quot; + subject.getName() + &quot; 점수는 &quot; + subject.getScorePoint() + &quot;점 입니다.&quot;);
        }
        System.out.println(studentID + &quot;님의 평균 점수는 &quot; + ((float)total / subjectList.size()) + &quot;점 입니다.&quot;);
    }

}</code></pre>
<ul>
<li>main() 에서 studentLee와 studentKim 을 생성하여 각자 과목과 점수를 넣어주었다.
과목의 수를 다르게 하여 평균을 출력한 결과를 확인할 수 있다.</li>
</ul>
<pre><code class="language-java">package arrayList;

public class StudentTest {
    public static void main(String[] args) {
        Student studentLee = new Student(&quot;Lee&quot;);
        studentLee.addSubject(&quot;국어&quot;, 90);
        studentLee.addSubject(&quot;영어&quot;, 95);
        studentLee.addSubject(&quot;수학&quot;, 100);
        studentLee.showStudentInfo();
        System.out.println(&quot;======================&quot;);
        Student studentKim = new Student(&quot;Kim&quot;);
        studentKim.addSubject(&quot;국어&quot;, 90);
        studentKim.addSubject(&quot;영어&quot;, 95);
        studentKim.addSubject(&quot;수학&quot;, 100);
        studentKim.addSubject(&quot;사회&quot;, 85);
        studentKim.addSubject(&quot;과학&quot;, 93);
        studentKim.showStudentInfo();
    }
}</code></pre>
<p><img src="https://images.velog.io/images/migratory_bird/post/a16a4a45-d0a6-40ae-b29d-e915e94146bb/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[19강. 다차원 배열]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-19</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-19</guid>
            <pubDate>Tue, 22 Feb 2022 15:40:44 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>19강 &quot;다차원 배열&quot;</li>
<li>다차원 배열</li>
</ul>
<h1 id="다차원-배열">다차원 배열</h1>
<ul>
<li>2차원 이상의 배열</li>
<li>지도, 게임 등 평면이나 공간을 구현할 때 많이 사용된다.</li>
</ul>
<p><img src="https://images.velog.io/images/migratory_bird/post/054425df-07b9-426e-bb6e-7765819c1961/image.png" alt="">
<img src="https://images.velog.io/images/migratory_bird/post/a45fe224-4dce-425a-9467-de4f6db28fb0/image.png" alt=""></p>
<pre><code class="language-java">public class TwoDimensionArray {
    public static void main(String[] args) {
        int[][] arr = {{1,2,3},{4,5,6}};

        //length 출력
        System.out.println(&quot;arr.length : &quot; + arr.length);
        System.out.println(&quot;arr[0].length : &quot; + arr[0].length);

        for(int i=0; i&lt;arr.length; i++) {
            for(int j=0; j&lt;arr[i].length; j++) {
                System.out.println(&quot;arr[&quot;+i+&quot;][&quot;+j+&quot;] : &quot; + arr[i][j]);
            }
        }
    }
}</code></pre>
<p><img src="https://images.velog.io/images/migratory_bird/post/5177b6ae-6662-4367-8d48-7482d9054868/image.png" alt=""></p>
<p>다차원 배열의 length는 바로 뒷부분 대괄호 안에 쓰인 숫자라고 생각하면 되겠다.
예를들어 arr의 경우 int[2][3] 형태이므로 arr[2][3] 이라고 생각한다면
arr.length는 arr의 바로  뒷부분 대괄호가 2 이므로 arr.length==2 이고,
arr[i].length는 arr[i]의 뒷부분 대괄호가 3이므로 arr[i].length==3 이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[18강. 객체 배열 사용하기]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-18</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-18</guid>
            <pubDate>Mon, 21 Feb 2022 15:01:40 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>18강 &quot;객체 배열 사용하기&quot;</li>
<li>객체 배열 만들기 &gt; 배열 복사하기 &gt; 객체 배열 복사하기 &gt; 향상된 for문</li>
</ul>
<h1 id="객체-배열-만들기">객체 배열 만들기</h1>
<ul>
<li>참조 자료형을 선언하는 객체 배열</li>
<li>배열만 생성한 경우 요소는 null로 초기화 된다.</li>
<li>각 요소를 new를 활용하여 생성하여 저장해야 한다.</li>
</ul>
<p>예제는 Book 클래스를 생성하여 객체 배열을 만들어 보았다.</p>
<pre><code class="language-java">public class Book {
    private String bookName;
    private String author;

    public Book() {}
    public Book(String bookName, String author) {
        this.bookName = bookName;
        this.author = author;
    }

    public void showBookInfo() {
        System.out.println(bookName + &quot;, &quot; + author);
    }


    public String getBookName() {
        return bookName;
    }
    public void setBookName(String bookName) {
        this.bookName = bookName;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
}</code></pre>
<p>main이 있는 BookArray 클래스에서 객체 배열을 생성한 후 출력하면 null로 초기화되어 있는 것을 확인할 수 있다.</p>
<pre><code class="language-java">public class BookArray {
    public static void main(String[] args) {
        Book[] library = new Book[5];

        for(int i=0; i&lt;library.length; i++) {
            System.out.println(library[i]);
        }
    }
}</code></pre>
<p><img src="https://images.velog.io/images/migratory_bird/post/ba44c2db-11a9-42bb-8461-435fa28a8d8e/image.png" alt=""></p>
<p>int, double과 같은 기본 자료형으로 배열을 생성하면 해당 자료형이 차지하는 크기(int면 4byte 등)와 배열의 개수만큼의 공간이 만들어진다.
하지만 객체 배열에서는 처음부터 객체가 만들어지는 것이 아니라 객체가 가리킬 주소의 자리가 만들어진다. 때문에 나중에 객체를 new 키워드를 통해 직접 생성해주어야 한다.</p>
<p>즉, 위 코드는 library 배열에 Book 객체가 5개 생성된 것이 아니라 주소의 자리가 5개 생성된 상태이다.
<img src="https://images.velog.io/images/migratory_bird/post/f8d2d424-f45f-44bb-81a8-84009c5d5657/image.png" alt=""></p>
<p>따라서 그림처럼 배열 안에 다시 객체를 넣어주어야 한다.
<img src="https://images.velog.io/images/migratory_bird/post/9a0a5a4f-7420-4be0-88d7-57de6885bac3/image.png" alt=""></p>
<pre><code class="language-java">public class BookArray {
    public static void main(String[] args) {
        Book[] library = new Book[5];

        library[0] = new Book(&quot;태백산맥&quot;, &quot;조정래&quot;);
        library[1] = new Book(&quot;데미안&quot;, &quot;헤르만 헤세&quot;);
        library[2] = new Book(&quot;어떻게 살 것인가&quot;, &quot;유시민&quot;);
        library[3] = new Book(&quot;토지&quot;, &quot;박경리&quot;);
        library[4] = new Book(&quot;어린 왕자&quot;, &quot;생텍쥐페리&quot;);

        for(int i=0; i&lt;library.length; i++) {
            System.out.println(library[i]);
        }
        for(int i=0; i&lt;library.length; i++) {
            library[i].showBookInfo();
        }
    }
}</code></pre>
<p><img src="https://images.velog.io/images/migratory_bird/post/83f44bdc-6774-4b09-b29d-fed872d6663f/image.png" alt="">
배열의 각 자리에 Book 객체를 생성하였고, 객체 주소를 반환하는 것을 확인할 수 있다.</p>
<h1 id="배열-복사하기">배열 복사하기</h1>
<ul>
<li>기존 배열과 같은 배열을 만들거나 배열이 꽉 찬 경우 더 큰 배열을 만들고 기존 배열 자료를 복사할 수 있다.</li>
<li>System.arraycopy(src, srcPos, dest, destPos, length);</li>
</ul>
<table>
<thead>
<tr>
<th align="center">매개변수</th>
<th align="left">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="center">src</td>
<td align="left">복사할 배열 이름</td>
</tr>
<tr>
<td align="center">srcPos</td>
<td align="left">복사할 배열의 첫 번째 위치</td>
</tr>
<tr>
<td align="center">dest</td>
<td align="left">복사해서 붙여 넣을 대상 배열 이름</td>
</tr>
<tr>
<td align="center">destPos</td>
<td align="left">복사해서 대상 배열에 붙여 넣기를 시작할 첫 번째 위치</td>
</tr>
<tr>
<td align="center">length</td>
<td align="left">src에서 dest로 자료를 복사할 요소 개수</td>
</tr>
</tbody></table>
<pre><code class="language-java">public class ArrayCopy {
    public static void main(String[] args) {
        int[] arr1 = {10, 20, 30, 40, 50};
        int[] arr2 = {1, 2, 3, 4, 5, 6, 7, 8, 9};

        System.arraycopy(arr1, 0, arr2, 1, 4);
        for(int i=0; i&lt;arr2.length; i++) {
            System.out.println(arr2[i]);
        }
    }
}</code></pre>
<p><img src="https://images.velog.io/images/migratory_bird/post/5a1e80e9-aeee-4af3-93a2-63fc0f6fca91/image.png" alt=""></p>
<p>System.arraycopy(arr1, 0, arr2, 1, 4); 을 해석해보면
arr1의 0번째부터 복사할 것이고, arr2의 1번째부터 붙여넣을 것인데, 4개를 복사할 것이라는 의미이다.
arr2를 출력해보면 0번째 요소는 바뀌지 않고 1번째부터 4개는 변한 것을 확인할 수 있다.
붙여넣을 배열의 size가 복사할 size를 초과하면 에러가 발생한다.</p>
<h1 id="객체-배열-복사하기">객체 배열 복사하기</h1>
<ul>
<li>얕은 복사 : <strong>배열 요소의 주소만 복사</strong>되므로 배열 요소가 변경되면 복사된 배열의 값도 변경된다.</li>
</ul>
<pre><code class="language-java">public class ObjectCopy {
    public static void main(String[] args) {
        Book[] bookArr1 = new Book[5];
        Book[] bookArr2 = new Book[5];

        bookArr1[0] = new Book(&quot;태백산맥&quot;, &quot;조정래&quot;);
        bookArr1[1] = new Book(&quot;데미안&quot;, &quot;헤르만 헤세&quot;);
        bookArr1[2] = new Book(&quot;어떻게 살 것인가&quot;, &quot;유시민&quot;);
        bookArr1[3] = new Book(&quot;토지&quot;, &quot;박경리&quot;);
        bookArr1[4] = new Book(&quot;어린 왕자&quot;, &quot;생텍쥐페리&quot;);

        //bookArr1의 객체를 boorArr2에 복사
        System.arraycopy(bookArr1, 0, bookArr2, 0, 5);

        //bookArr1의 배열을 수정
        bookArr1[0].setBookName(&quot;나목&quot;);
        bookArr1[0].setAuthor(&quot;박완서&quot;);

        //bookArr2 출력
        for(int i=0; i&lt;bookArr2.length; i++) {
            bookArr2[i].showBookInfo();
        }
    }
}</code></pre>
<p><img src="https://images.velog.io/images/migratory_bird/post/896358d9-2e3a-4dd5-b0c5-c087902b63ba/image.png" alt="">
bookArr2에는 bookArr1의 값이 복사된 것이 아니라 주소가 복사된 것이라 bookArr1의 요소를 수정하면 bookArr2의 요소도 함께 수정된다.
(정확히는 함께 수정되는 것이 아니라 동일한 인스턴스 주소를 가리키고 있으므로 인스턴스가 수정되면 동시에 바뀌는 것이다.)</p>
<p><img src="https://images.velog.io/images/migratory_bird/post/10daa444-d369-4b82-abe4-2fd280169b1f/image.png" alt="">
<img src="https://images.velog.io/images/migratory_bird/post/2676bcef-64d2-4bf3-bb75-85787a3e3d80/image.png" alt=""></p>
<ul>
<li>깊은 복사 : 각 배열마다 객체를 생성 후, 원래 배열에 있는 객체의 정보를 직접 대입한다.</li>
</ul>
<pre><code class="language-java">public class ObjectCopy {
    public static void main(String[] args) {
        Book[] bookArr1 = new Book[5];
        bookArr1[0] = new Book(&quot;태백산맥&quot;, &quot;조정래&quot;);
        bookArr1[1] = new Book(&quot;데미안&quot;, &quot;헤르만 헤세&quot;);
        bookArr1[2] = new Book(&quot;어떻게 살 것인가&quot;, &quot;유시민&quot;);
        bookArr1[3] = new Book(&quot;토지&quot;, &quot;박경리&quot;);
        bookArr1[4] = new Book(&quot;어린 왕자&quot;, &quot;생텍쥐페리&quot;);

        //bookArr2 배열에 Book 객체 생성 후 bookArr1의 인스턴스를 대입
        Book[] bookArr2 = new Book[5];
        for(int i=0; i&lt;bookArr2.length; i++) {
            bookArr2[i] = new Book();
            bookArr2[i].setBookName(bookArr1[i].getBookName());
            bookArr2[i].setAuthor(bookArr1[i].getAuthor());
        }

        //bookArr1의 배열을 수정
        bookArr1[0].setBookName(&quot;나목&quot;);
        bookArr1[0].setAuthor(&quot;박완서&quot;);

        //bookArr2 출력
        for(int i=0; i&lt;bookArr2.length; i++) {
            bookArr2[i].showBookInfo();
        }
    }
}</code></pre>
<p><img src="https://images.velog.io/images/migratory_bird/post/6f1224e7-7086-404b-b02e-9b86e0722409/image.png" alt="">
이렇게 하면 서로 다른 인스턴스의 메모리를 요소로 가지게 된다.</p>
<p><img src="https://images.velog.io/images/migratory_bird/post/de4b3fd8-40e5-4f42-9aeb-db0384b15341/image.png" alt=""></p>
<p>객체 배열을 복사할 때는 반드시 깊은 복사를 해야하는 것이 아니라, 복사한 배열이 수정될 일이 없다면 얕은 복사를, 수정될 일이 있다면 깊은 복사를 하면 되는 것이다.</p>
<h1 id="향상된-for문-enhanced-for-loop">향상된 for문 (enhanced for loop)</h1>
<ul>
<li>배열 요소의 처음부터 끝까지 모든 요소를 참조할 때 편리한 반복문</li>
</ul>
<pre><code class="language-java">// 기본 문법
for(자료형 변수 : 배열){
    반복 실행문;
}

// 사용 예제
public class EnhancedForLoop {
    public static void main(String[] args) {
        String[] strArr = {&quot;Java&quot;, &quot;Android&quot;, &quot;C&quot;, &quot;JavaScript&quot;, &quot;Python&quot;};

        for(String s : strArr) {
            System.out.println(s);
        }
    }
}</code></pre>
<p><img src="https://images.velog.io/images/migratory_bird/post/b94fe012-dfe1-41fd-81cb-3f5d1c1616a3/image.png" alt=""></p>
<p>변수에 배열의 0번째부터 마지막 요소까지 순차적으로 대입되며, 변수의 자료형은 배열의 자료형과 일치해야 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[17강. 배열과 ArrayList]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-17</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-17</guid>
            <pubDate>Sun, 20 Feb 2022 10:24:58 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>17강 &quot;배열과 ArrayList&quot;</li>
<li>배열</li>
</ul>
<p><strong>배열 선언</strong></p>
<ul>
<li>자료형[] 배열이름 = new 자료형[개수];
int[] arr = new int[10];</li>
<li>자료형 배열이름[] = new 자료형[개수];
int arr[] = new int[10];</li>
</ul>
<p><img src="https://images.velog.io/images/migratory_bird/post/e54475f7-04b0-44c4-afb0-63c101525ca5/image.png" alt=""></p>
<p><strong>배열 초기화</strong></p>
<ul>
<li>배열은 선언과 동시에 초기화 할 수 있다.</li>
<li>배열을 초기화 할 때는 배열의 개수를 명시하지 않는다.<pre><code class="language-java">int[] studentIDs = new int[10]                    //배열을 선언할 땐 배열의 길이를 명시
int[] studentIDs = new int[] {101, 102, 103};    //선언과 동시에 초기화 할 땐 개수 생략
int[] studentIDs = new int[3] {101, 102, 103};    //오류 발생
int[] studentIDs = {101, 102, 103};                //new를 안써도 int형 요소가 3개인 배열 생성</code></pre>
배열을 선언할 땐 배열의 길이를 반드시 명시해야 하고, 선언과 동시에 초기화할 때에는 개수를 생략해야 한다. 선언과 동시에 초기화할 땐 new 키워드를 쓰지 않아도 해당 길이만큼의 배열이 선언된다.</li>
</ul>
<p>선언 이후에 초기화를 따로 할 때는 아래와 같이 작성하면 된다.</p>
<pre><code class="language-java">int[] numbers = new int[3];
numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;</code></pre>
<p>배열을 선언하고 초기화를 따로 하지 않으면 기본값으로 배열이 초기화 된다.
(int형은 0, double형은 0.0, 객체 배열은 null로 초기화가 된다.)</p>
<p><strong>배열 사용</strong></p>
<ul>
<li>[](인덱스 혹은 첨자 연산자)를 이용하여 배열의 위치를 지정하여 자료를 가져온다.</li>
<li>모든 배열의 순서는 0부터 시작한다.</li>
<li>n개 배열은 0 부터 n-1 위치까지 자료가 존재한다.
<img src="https://images.velog.io/images/migratory_bird/post/eb5d142e-07d3-44d9-93bd-ac7fa4b4471b/image.png" alt=""><pre><code class="language-java">double[] nums = new double[5];
nums[0] = 10.0;
nums[1] = 20.0;
nums[2] = 30.0;
</code></pre>
</li>
</ul>
<p>for(int i=0; i&lt;nums.length; i++) {
        System.out.println(&quot;nums[&quot; + i + &quot;] = &quot; + nums[i]);
}</p>
<pre><code>![](https://images.velog.io/images/migratory_bird/post/0ba63807-65cc-4adc-8222-5cf291908a21/image.png)

만약 nums 배열에서 초기화된 값들을 모두 곱하고 싶은 경우에는 자동으로 초기화된 0.0을 제외하고 곱해줘야 한다. 따라서 변수를 따로 설정하여 초기화한 개수를 세어주는 방법을 이용할 수 있다.
```java
double[] nums = new double[5];
int size = 0;
nums[0] = 10.0; size++;
nums[1] = 20.0; size++;
nums[2] = 30.0; size++;

double total = 1;
for(int i=0; i&lt;size; i++) {
    total *= nums[i];
}</code></pre><p>아래는 알파벳을 각각의 배열에 넣어주는 방법에 대한 예제이다.</p>
<pre><code class="language-java">char[] alphabets = new char[26];
char ch = &#39;A&#39;;

for(int i=0; i&lt;alphabets.length; i++, ch++) {
    alphabets[i] = ch;
    System.out.println(&quot;alphabets[&quot; + i + &quot;] = &quot; + alphabets[i]);
}</code></pre>
<p>이번 시간에는 기본 자료형을 이용한 배열만 다루었고, 다음 강의에서는 String, 객체 배열을 다룰 예정이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[16강. 클래스와 객체2(4) - singleton 패턴]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-16</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-16</guid>
            <pubDate>Fri, 18 Feb 2022 14:53:52 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>16강 &quot;클래스와 객체2(3) - static 변수&quot;</li>
<li>singleton 패턴</li>
</ul>
<h1 id="singleton-패턴">singleton 패턴</h1>
<ul>
<li>전 시스템에 단 하나의 인스턴스만이 존재하도록 구현하는 방식이다.</li>
<li>자바에는 글로벌 변수가 없으므로 static 변수를 사용한다.</li>
<li>생성자를 private으로 만들고 public으로 선언된 static 메서드를 제공하여 외부에서 사용할 수 있도록 한다.</li>
<li>여러 개의 객체가 생성되면 문제가 되는 경우나, framework에서 많이 쓰인다.</li>
</ul>
<pre><code class="language-java">public class Company {
    //Company 객체는 현재 클래스 내부에서 단 한 개만 존재함.
    private static Company instance = new Company();

    //외부에서 constructor 호출을 제한
    private Company(){}

    //외부에서 instance 객체를 사용할 수 있게 함
    public static Company getInstance() {
        if(instance == null) {
            instance = new Company();
        }
        return instance;
    }
}</code></pre>
<p>이처럼 private으로 생성자를 만들고, 객체를 class 내부에서 private static으로 선언한 후, public static 메서드를 제공하여 객체를 사용할 수 있도록 만든다.</p>
<pre><code class="language-java">public class CompanyTest {
    public static void main(String[] args) {
        Company c1 = Company.getInstance();
        Company c2 = new Company();    //error
    }
}</code></pre>
<p>main함수가 있는 다른 class에서 Company객체를 사용하고 싶다면 new 생성자가 아닌 getInstance() 메서드를 이용하여 사용할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[15강. 클래스와 객체2(3) - static 변수]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-15</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-15</guid>
            <pubDate>Thu, 17 Feb 2022 15:47:06 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>15강 &quot;클래스와 객체2(3) - static 변수&quot;</li>
<li>static 변수 &gt; static 메서드 &gt; 변수의 유효 범위</li>
</ul>
<h1 id="static-변수">static 변수</h1>
<ul>
<li>static 변수는 자료형 앞에 static 예약어를 써서 사용하며, <strong>여러 개의 인스턴스가 같은 메모리의 값을 공유하기 위해 사용</strong>한다.</li>
<li>static 변수는 heap 메모리가 아닌 <strong>다른 영역(데이터 영역 메모리)에 저장</strong>되고, 프로그램이 메모리에 적재(load)될 때 값이 할당된다. (인스턴스는 new 키워드로 객체가 생성될 때 heap 메모레어 할당되고, 객체가 소멸되면 사라진다.)</li>
<li>따라서 인스턴스의 생성과 관계없이 <strong>클래스 이름으로 직접 참조</strong>한다.</li>
<li>static 변수는 클래스 변수라고도 한다. (멤버변수는 인스턴스 변수라고도 한다.)</li>
</ul>
<p><img src="https://images.velog.io/images/migratory_bird/post/ab91f905-eb0c-4e4b-a45a-e88a3b4eb59c/image.png" alt="static변수의 정의와 사용 방법"></p>
<p><img src="https://images.velog.io/images/migratory_bird/post/97bb4b73-2698-466c-9706-0f78c274e55d/image.png" alt=""></p>
<h1 id="static-메서드">static 메서드</h1>
<ul>
<li>클래스 메서드 라고도 한다.</li>
<li>메서드에 static 키워드를 사용해서 구현한다.</li>
<li>주로 static 변수를 위한 기능을 제공한다.</li>
<li>static메서드는 멤버변수보다 먼저 생성되므로 static메서드 안에서는 멤버변수를 사용할 수 없다. (지역변수는 사용 가능)</li>
<li>인스턴스의 생성과 관계 없이 클래스 이름으로 직접 메서드를 호출한다.</li>
</ul>
<blockquote>
<p>아래는 Student 객체를 생성할 때마다 studentID가 1씩 증가하여 대입되도록 만든 코드이다.</p>
</blockquote>
<pre><code class="language-java">public class Student {
    //객체가 생성될 때만 값이 변화해야 하므로 private으로 static변수 선언
    private static int serialNum = 10000;

    int studentID;
    String studentName;

    //객체 생성 시 serailNum이 증가하고 그 값을 studentID에 대입
    public Student() {
        serialNum++;
        studentID = serialNum;
    }

    //static메서드로 static변수를 반환
    public static int getSerialNum() {
        return serialNum;
    }
}</code></pre>
<pre><code class="language-java">public class StudentTest1 {
    public static void main(String[] args) {
        //객체 생성 전에 static 변수 값 확인
        System.out.println(Student.getSerialNum());

        //객체 생성하여 static 변수 값 확인
        Student studentLee = new Student();
        System.out.println(studentLee.getSerialNum());

        Student studentSon = new Student();
        System.out.println(studentSon.getSerialNum());
    }
}</code></pre>
<p><img src="https://images.velog.io/images/migratory_bird/post/45a7ee6c-d211-497d-a287-b529d6a0a934/image.png" alt=""></p>
<ul>
<li>static변수와 static메서드는 객체가 생성되기 전에 이미 데이터 영역에 할당되어 있기 때문에
객체 생성 전에 Student.getSeiralNum()으로 serialNum의 값을 확인할 수 있다.</li>
<li>studentLee가 생성될 때 serialNum이 1 증가하였고, studentSon이 생성될 때 이미 1 증가한 serialNum이 다시 1이 증가한 것을 확인할 수 있다.</li>
</ul>
<h1 id="변수의-유효-범위">변수의 유효 범위</h1>
<table>
<thead>
<tr>
<th align="center">변수 유형</th>
<th align="center">선언 위치</th>
<th align="center">사용 범위</th>
<th align="center">메모리</th>
<th align="center">생성과 소멸</th>
</tr>
</thead>
<tbody><tr>
<td align="center">지역 변수 <br>(로컬 변수)</td>
<td align="center">함수 내부에 선언</td>
<td align="center">함수 내부에서만 사용</td>
<td align="center">스택</td>
<td align="center">함수가 호출될 때 생성되고,<br>함수가 끝나면 소멸함</td>
</tr>
<tr>
<td align="center">멤버 변수 <br>(인스턴스 변수)</td>
<td align="center">클래스 멤버 변수로 선언</td>
<td align="center">클래스 내부에서 사용하고 <br>private이 아니면 참조 변수로<br> 다른 클래스에서 사용 가능</td>
<td align="center">힙</td>
<td align="center">인스턴스가 생성될 때 힙에 생성되고,<br>가비지 컬렉터가 메모리를 수거할 때<br> 소멸됨</td>
</tr>
<tr>
<td align="center">static 변수 <br>(클래스 변수)</td>
<td align="center">static 예약어를 사용하여<br>클래스 내부에 선언</td>
<td align="center">클래스 내부에서 사용하고<br>private이 아니면 클래스 이름으로 <br>다른 클래스에서 사용 가능</td>
<td align="center">데이터<br> 영역</td>
<td align="center">프로그램이 처음 시작할 때<br> 상수와 함께 데이터 영역에 생성되고<br> 프로그램이 끝나고 메모리를 해제할 때<br> 소멸됨</td>
</tr>
</tbody></table>
<p><img src="https://images.velog.io/images/migratory_bird/post/ad30f55e-7e6e-4f67-b128-26a02a99eb2a/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[14강. 클래스와 객체2(2)]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-14</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-14</guid>
            <pubDate>Wed, 16 Feb 2022 16:27:10 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>14강 &quot;클래스와 객체2(2)&quot;</li>
<li>객체 간의 협력</li>
</ul>
<h1 id="객체-간의-협력">객체 간의 협력</h1>
<ul>
<li>학생이 버스나 지하철을 타는 상황을 객체지향으로 프로그래밍하는 예시
<img src="https://images.velog.io/images/migratory_bird/post/bc16cc54-b9b2-49dc-a613-eb9411bc4512/image.png" alt="학생이 버스나 지하철을 가는 상황을 객체지향으로 프로그래밍하는 예시"></li>
</ul>
<p>학생이 버스나 지하철을 타는 상황을 프로그래밍하기 위해서는 클래스가 학생, 버스, 지하철이 필요하다.</p>
<pre><code class="language-java">public class Student {
    String studentName;
    int grade;
    int money;

    public Student(String studentName, int money) {
        this.studentName = studentName;
        this.money = money;
    }

    public void takeBus(Bus bus) {
        bus.take(1000);
        money -= 1000;
    }
    public void takeSubway(Subway subway) {
        subway.take(1500);
        money -= 1500;
    }
    public void showInfo() {
        System.out.println(studentName + &quot;님의 남은 돈은 &quot; + money + &quot;원 입니다.&quot;);
    }
}</code></pre>
<p>학생의 속성은 이름, 학년(해당 상황에 필요한 것은 아님), 가진 돈으로 만들어 주었고, 버스를 타는 행위와 지하철을 타면 가진 돈이 줄어드는 메서드로 만들어 주었다.</p>
<pre><code class="language-java">public class Bus {
    int busNumber;
    int passengerCount;
    int money;

    public Bus(int busNumber) {
        this.busNumber = busNumber;
    }
    public void take(int money) {
        passengerCount++;
        this.money += money;
    }
    public void showInfo() {
        System.out.println(&quot;버스 &quot; + busNumber + &quot;번의 승객은 &quot; + passengerCount + &quot;명이고, 수입은 &quot; + money +&quot;입니다.&quot;);
    }
}</code></pre>
<p>버스의 속성은 버스 번호, 승객 수, 수입으로 만들어 주었고, 탑승하는 경우에 승객과 수입이 증가하는 메서드를 만들어 주었다.</p>
<pre><code class="language-java">public class Subway {
    int lineNumber;
    int passengerCount;
    int money;

    public Subway(int lineNumber) {
        this.lineNumber = lineNumber;
    }
    public void take(int money) {
        passengerCount++;
        this.money += money;
    }
    public void showInfo() {
        System.out.println(&quot;지하철 &quot; + lineNumber + &quot;호선의 승객은 &quot; + passengerCount + &quot;명이고, 수입은 &quot; + money +&quot;입니다.&quot;);
    }
}</code></pre>
<p>지하철의 속성은 노선 번호, 승객 수, 수입으로 만들어 주었고, 버스와 마찬가지로 탑승하는 경우에 승객과 수입이 증가하는 메서드를 만들어 주었다.</p>
<pre><code class="language-java">public class TakeTrans {
    public static void main(String[] args) {
        Student james = new Student(&quot;James&quot;, 5000);
        Student tomas = new Student(&quot;Tomes&quot;, 10000);

        Bus bus100 = new Bus(100);        
        james.takeBus(bus100);
        james.showInfo();
        bus100.showInfo();

        Subway subway2 = new Subway(2);
        tomas.takeSubway(subway2);
        tomas.showInfo();
        subway2.showInfo();
    }
}</code></pre>
<p>main 함수에서 실행시킨 후 showInfo()로 확인해본 결과 정상 작동하는 것을 확인할 수 있다.
<img src="https://images.velog.io/images/migratory_bird/post/25e1ef9a-a077-4568-a39f-cec17846196b/image.png" alt="Test"></p>
<blockquote>
<p>강의에서 작성한 코드가 깔끔하지 않다고 생각해서 약간 수정해보았습니다.</p>
</blockquote>
<pre><code class="language-java">public class Student {
    String studentName;
    int age;
    int money;

    public Student(String studentName, int age, int money) {
        this.studentName = studentName;
        this.age = age;
        this.money = money;
    }

    public void takeBus(Bus bus) {
        bus.take(this);
        money -= bus.fare;
        showInfo();
    }
    public void takeSubway(Subway subway) {
        subway.take(this);
        money -= subway.fare;
        showInfo();
    }
    public void showInfo() {
        System.out.println(studentName + &quot;님의 남은 돈은 &quot; + money + &quot;원 입니다.&quot;);
    }
}</code></pre>
<p>나이마다 요금을 다르게 설정하기 위해 Student 클래스에 나이 변수를 추가하였고, 가진 돈은 그 요금만큼 줄어들도록 코딩하였다.</p>
<pre><code class="language-java">public class Bus {
    int busNumber;
    int passengerCount;
    int fare;
    int money;

    public Bus(int busNumber) {
        this.busNumber = busNumber;
    }
    public void take(Student student) {
        if(student.age &lt; 7) {
            fare = 450;
        }else if(student.age &lt; 19) {
            fare = 720;
        }else {
            fare = 1050;
        }
        passengerCount++;
        money += fare;
        showInfo();
    }
    public void showInfo() {
        System.out.println(&quot;버스 &quot; + busNumber + &quot;번의 승객은 &quot; + passengerCount + &quot;명이고, 수입은 &quot; + money +&quot;입니다.&quot;);
    }
}</code></pre>
<pre><code class="language-java">public class Subway {
    int lineNumber;
    int passengerCount;
    int fare = 1500;
    int money;

    public Subway(int lineNumber) {
        this.lineNumber = lineNumber;
    }
    public void take(Student student) {
        if(student.age &lt; 7) {
            fare = 450;
        }else if(student.age &lt; 19) {
            fare = 720;
        }else {
            fare = 1250;
        }
        passengerCount++;
        money += fare;
        showInfo();
    }
    public void showInfo() {
        System.out.println(&quot;지하철 &quot; + lineNumber + &quot;호선의 승객은 &quot; + passengerCount + &quot;명이고, 수입은 &quot; + money +&quot;입니다.&quot;);
    }
}</code></pre>
<p>버스와 지하철의 take() 메서드는 Student의 나이에 따라 요금이 달라지도록 설정하였다.</p>
<pre><code class="language-java">public class TakeTrans {
    public static void main(String[] args) {
        Student james = new Student(&quot;James&quot;, 25, 10000);
        Student tomas = new Student(&quot;Tomes&quot;, 15, 10000);
        Student harry = new Student(&quot;Harry&quot;, 5, 10000);

        Bus bus100 = new Bus(100);        
        james.takeBus(bus100);
        tomas.takeBus(bus100);
        harry.takeBus(bus100);

        Subway subway2 = new Subway(2);
        james.takeSubway(subway2);
        tomas.takeSubway(subway2);
        harry.takeSubway(subway2);
    }
}</code></pre>
<p><img src="https://images.velog.io/images/migratory_bird/post/74aa6e70-d4a5-4a4d-912b-96f91a4da83e/image.png" alt="수정 코드 출력"></p>
<p>25살, 15살, 5살의 Student 객체를 만들고 각각 버스와 지하철을 탔을 때 요금이 다르게 줄어드는 것을 확인할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[13강. 클래스와 객체2(1)]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-13</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-13</guid>
            <pubDate>Tue, 15 Feb 2022 16:52:22 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>13강 &quot;클래스와 객체2(1)&quot;</li>
<li>this가 하는 일</li>
</ul>
<h1 id="this가-하는-일">this가 하는 일</h1>
<ul>
<li>자신의 메모리를 가리킨다.</li>
<li>생성자에서 다른 생성자를 호출한다.</li>
<li>자신의 주소를 반환한다.</li>
</ul>
<pre><code class="language-java">class Birthday{
    int day;
    int month;
    int year;

    public void setYear(int year) {
        this.year = year;
    }
    public void printThis() {
        System.out.println(this);
    }
}

public class ThisExample {
    public static void main(String[] args) {
        Birthday b1 = new Birthday();
        Birthday b2 = new Birthday();

        System.out.println(b1);
        b1.printThis();
        System.out.println(b2);
        b2.printThis();
    }
}</code></pre>
<p>위 코드는 Birthday 클래스에 printThis()를 통해 this가 자신의 주소를 가리킨다는 것을 확인해보는 코드이다. setYear()에서 this.year에서의 this는 자기 자신의 클래스를 의미하며 this.year은 그 클래스의 year변수를 뜻한다.
<img src="https://images.velog.io/images/migratory_bird/post/68b0c1d0-debc-4f75-a529-071dc8def8f5/image.png" alt="this 출력">
b1, b2는 각각 Birthday 객체이다.
b1자체를 출력하고, printThis 메서드를 호출하여 b1에서의 this를 출력해보면 값이 같은 것을 확인할 수 있고, b1과 b2는 heap 메모리에서 다른 메모리 공간을 가지므로 서로 다른 값을 참조하는 것을 확인할 수 있다.</p>
<pre><code class="language-java">class Person{
    String name;
    int age;

    public Person() {
        this(&quot;이름없음&quot;, 1);
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public class CallAnotherConst {
    public static void main(String[] args) {
        Person p1 = new Person();
        System.out.println(p1.name);
    }
}</code></pre>
<p>위 코드는 this를 이용하여 다른 생성자(constructor)를 호출하는 예제이다.
<img src="https://images.velog.io/images/migratory_bird/post/a8257576-1788-4e10-bba6-5c1106f75cc5/image.png" alt="">
p1 변수에 Person 객체를 default 생성자로 호출했고 default 생성자에서는 name과 age를 사용한 생성자를 호출하여 name이 &quot;이름없음&quot;으로 출력된다.</p>
<blockquote>
<pre><code class="language-java">public Person() {
    int i = 0;
    this(&quot;이름없음&quot;, 1);
}</code></pre>
</blockquote>
<pre><code>위처럼 constructor에서 다른 constructor를 호출할 때에는 그 앞에 다른 코드를 작성할 수 없다.
왜냐하면 constructor 안에서 다른 constructor를 호출하면 내부의 constructor가 호출되어야 초기화가 이루어지는데, 그 전에 다른 코드가 작성되어 초기화를 시도하면 오류를 발생시킬 수 있기 때문이다.</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[12강. 클래스와 객체1(4)]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-12</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-12</guid>
            <pubDate>Mon, 14 Feb 2022 16:28:43 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>12강 &quot;클래스와 객체1(4)&quot;</li>
<li>참조 자료형 &gt; 정보은닉</li>
</ul>
<h1 id="참조-자료형reference-data-type">참조 자료형(reference data type)</h1>
<ul>
<li>클래스 형으로 선언하는 자료형</li>
<li>기본 자료형 : int, long, float, double 등</li>
<li>참조 자료형 : String, Data, Student 등</li>
</ul>
<p><strong>참조 자료형의 예</strong>
<em>학생의 속성 중 수업에 대한 부분을 만들 때, 수업에 대한 각 속성을 학생 클래스에 정의하지 않고 수업이라는 클래스로 분리해서 사용한다. 이 때, 과목은 참조 자료형으로 선언한다.</em></p>
<p><img src="https://images.velog.io/images/migratory_bird/post/a429f2c2-24a5-49dd-9196-4bae7b3b01da/image.png" alt="참조 자료형의 예"></p>
<p>그림과 같이 학생의 학번, 이름, 국어성적, 수학성적, 수강 과목 이름을 만들어보자.</p>
<pre><code class="language-java">public class Student {
    int studentID;
    String studentName;

    int koreaScore;
    int mathScore;
    String koreaSubject;
    String mathSubject;
}</code></pre>
<p>이런 방식으로 Student()에 모든 데이터를 담으면 데이터를 추가하거나 제거할 때 번거로움이 발생한다.
예를 들어 수강하는 과목의 선생님을 추가하고 싶다면 현재는 Student()에 변수 koreaTeacher와 mathTeacher이 추가되어야 한다.
이러한 방식은 과목 수가 늘어나면 번거로워지고, 필요없어서 지워야하는 경우에도 하나하나 지워야하므로 비효율적이다.
학생과 과목의 class를 분리하여 참조 자료형으로 사용하면 이러한 번거로움을 줄일 수 있다.</p>
<pre><code class="language-java">public class Subject {
    String subjectName;
    int score;
}

public class Student {
    int studentID;
    String studentName;
    Subject korea;
    Subject math;

    public Student() {
        korea = new Subject();
        math = new Subject();
    }
}
</code></pre>
<p>Subject()에서 과목에 필요한 정보를 담고, Student()에서 각 과목을 참조 자료형으로 선언하면 선생님을 추가할 때에는 Subject()에 teacher 변수만 추가해주면 된다.</p>
<blockquote>
<p><strong>eclipse에서는 getter와 setter를 자동으로 만들어주는 편의기능이 있다.</strong></p>
</blockquote>
<ul>
<li>마우스 우클릭 -&gt; Source -&gt; Generate Getters and Setters -&gt; get, set 메서드를 만들 변수를 선택 -&gt; Generate</li>
<li>단축키 : Alt + Shift + s -&gt; r</li>
</ul>
<pre><code class="language-java">public class Subject {
    String subjectName;
    int score;
    public Subject() {}
    public Subject(String name) {
        subjectName = name;
    }
    public String getSubjectName() {
        return subjectName;
    }
    public void setSubjectName(String subjectName) {
        this.subjectName = subjectName;
    }
    public int getScore() {
        return score;
    }
    public void setScore(int score) {
        this.score = score;
    }
}</code></pre>
<p>Subject()에 getter와 setter 메서드를 등록해주고, constructor를 정의해 주었다.</p>
<pre><code class="language-java">public class Student {
    int studentID;
    String studentName;
    Subject korea;
    Subject math;

    public Student() {
        korea = new Subject();
        math = new Subject();
    }

    public Student(int id, String name) {
        studentID = id;
        studentName = name;
        korea = new Subject(&quot;국어&quot;);
        math = new Subject(&quot;수학&quot;);
    }

    public void setKorea(int score) {
        korea.setScore(score);
    }

    public void setMath(int score) {
        math.setScore(score);
    }

    public void showStudentInfo() {
        int total = korea.getScore() + math.getScore();
        System.out.println(studentName + &quot; 학생의 총점은 &quot; + total + &quot;점 입니다.&quot;);
    }
}</code></pre>
<p>Student() 에서는 국어와 수학 점수에 대한 setter를 정의하고, totalScore를 보여주는 showStudentInfo 메서드를 만들었다.</p>
<pre><code class="language-java">public class StudentTest {
    public static void main(String[] args) {
        Student studentJames = new Student(100, &quot;James&quot;);
        studentJames.setKorea(95);
        studentJames.setMath(88);

        Student studentTomas = new Student(100, &quot;Tomas&quot;);
        studentTomas.setKorea(80);
        studentTomas.setMath(75);

        studentJames.showStudentInfo();
        studentTomas.showStudentInfo();
    }
}
</code></pre>
<p>StudentTest()에서 테스트 해 본 결과 구상한대로 정상 출력된 것을 확인할 수 있다.
<img src="https://images.velog.io/images/migratory_bird/post/dc6f0c9e-3136-4c6e-b09c-8570e035faf6/image.png" alt="StudentTest"></p>
<h1 id="정보은닉-information-hiding">정보은닉 (information hiding)</h1>
<ul>
<li><strong>private 접근 제어자</strong></li>
<li>클래스 외부에서 클래스 내부의 멤버변수나 메서드에 접근(access)하지 못하게 하는 경우에 사용한다.</li>
<li>멤버변수나 메서드를 외부에서 사용하지 못하도록 하여 오류를 줄일 수 있다.</li>
<li>변수에 대해서는 필요한 경우 get(), set() 메서드를 제공한다.</li>
</ul>
<pre><code class="language-java">class BirthDay {
    public int day;
    public int month;
    public int year;
}

public class BirthDayTest{
    public static void main(String[] args) {
        BirthDay day = new BirthDay();
        day.year = 2022;
        day.month = 2;
        day.day = 30;
    }
}</code></pre>
<p>위와 같이 BirthDay 클래스의 변수인 day, month, year에 클래스 외부(BirthDayTest 클래스)에서 접근하는 경우에는 2월 30로 지정할 수 있다.
2월은 28일까지밖에 없기 때문에 이것은 코드상 오류는 없지만 실제로는 존재하지 않아야 한다.
이럴 때 변수는 private으로 감추고, public 메서드를 통해 이러한 오류들을 막는 코드를 작성할 수 있다.</p>
<pre><code class="language-java">class BirthDay {
    private int day;
    private int month;
    private int year;

    public int getDay() {
        return day;
    }
    public void setDay(int day) {
        if(month == 2) {
            if(day &lt; 1 || day &gt; 28) {
                System.out.println(&quot;날짜 오류입니다.&quot;);
            }
        }else {
            this.day = day;            
        }
    }
    public int getMonth() {
        return month;
    }
    public void setMonth(int month) {
        this.month = month;
    }
    public int getYear() {
        return year;
    }
    public void setYear(int year) {
        this.year = year;
    }
}

public class BirthDayTest{
    public static void main(String[] args) {
        BirthDay day = new BirthDay();
        day.setYear(2022);
        day.setMonth(2);
        day.setDay(30);
    }
}</code></pre>
<p>위처럼 setDay()에 2월일 경우 day가 28을 넘지 않도록 코드를 추가해주면 원하지 않는 값이 변수에 들어가는 것을 막을 수 있다.</p>
<h3 id="접근제어자">접근제어자</h3>
<ul>
<li>public : 외부 클래스에서 모두 사용 가능</li>
<li>private : 클래스 내부에서만 사용 가능</li>
<li>default(아무것도 쓰지 않는 경우) : 같은 package 내에서 사용 가능</li>
<li>protected : 상속 관계에서 사용 가능</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[11강. 클래스와 객체1(3)]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-11</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-11</guid>
            <pubDate>Fri, 11 Feb 2022 15:42:18 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>11강 &quot;클래스와 객체1(3)&quot;</li>
<li>class &amp; instance &gt; 클래스 생성 &gt; 인스턴스와 힙(Heap) 메모리 &gt; 용어 정리 &gt; 생성자(constructor) &gt; 생성자 오버로드 (constructor overload)</li>
</ul>
<h1 id="class--instance">class &amp; instance</h1>
<ul>
<li>클래스(class)는 객체를 추상화한 개념이며, 그것을 구체적으로 표현한 것을 인스턴스(instance)라고 한다.
ex) class : 개 / instance : 진돗개, 삽살개 등</li>
<li>객체지향 프로그래밍은 객체를 정의하고 객체들을 class라는 코드로 표현한다.
class를 구체적으로 작성하는 것을 instance화 한다고 한다.</li>
</ul>
<h1 id="클래스-생성">클래스 생성</h1>
<ul>
<li>클래스를 <strong>사용</strong>하기 위해서는 클래스를 <strong>생성</strong>해야 한다.</li>
<li><strong>new</strong> 예약어를 이용하여 클래스를 생성한다.</li>
<li><strong><em>클래스형 변수이름 = new 생성자;</em></strong></li>
</ul>
<pre><code class="language-java">public class Student {
    // 멤버 변수를 정의
    int studentID;
    String studentName;
    int grade;
    String address;

    public String getStudentName() {
        return studentName;
    }
    public void setStudentName(String name) {
        studentName = name;
    }

    // 메서드 정의
    public void showStudentInfo() {
        System.out.println(&quot;학번 : &quot; + studentID);
        System.out.println(&quot;이름 : &quot; + studentName);
        System.out.println(&quot;학년 : &quot; + grade);
        System.out.println(&quot;주소 : &quot; + address);
    }

    public static void main(String[] args) {
        Student studentLee = new Student();    //클래스 생성
        //생성된 클래스의 멤버 변수를 초기화
        studentLee.studentID = 20220210;
        studentLee.studentName = &quot;이순신&quot;;
        studentLee.grade = 2;
        studentLee.address = &quot;서울시 서초구 서초동&quot;;
        //클래스의 메서드 호출
        studentLee.showStudentInfo();
    }
}</code></pre>
<p>지난 강의에서 작성했던 코드이다. Student라는 클래스를 호출하기 위한
<strong><em>Student studentLee = new Student();</em></strong> 코드를 분석해보면 다음과 같다.</p>
<ul>
<li>맨 앞의 Student는 객체형(클래스형)이며 <strong>참조형 데이터타입</strong>이라고 한다.</li>
<li>두 번째 studentLee는 <strong>참조 변수</strong>라고 한다.</li>
<li>Student()는 <strong>기본생성자</strong>라고 한다.</li>
</ul>
<h1 id="인스턴스와-힙heap-메모리">인스턴스와 힙(Heap) 메모리</h1>
<ul>
<li>하나의 클래스 코드로부터 여러 개의 인스턴스를 생성할 수 있다.</li>
<li>지역변수는 스택메모리에 생성되며, 인스턴스는 힙(Heap) 메모리에 생성된다.</li>
<li>각각의 인스턴스는 다른 메모리에 다른 값을 가진다.</li>
<li>힙 메모리는 동적으로 생성되는 메모리로, 필요할 때 allocation(할당) 받는다.
<img src="https://images.velog.io/images/migratory_bird/post/b1ba83d1-078d-4d90-8891-31495802dd17/image.png" alt="heap 메모리 설명"></li>
</ul>
<ol>
<li>예시코드의 경우에 studentID, studentName, grade, address 변수들이 Student의 instance로서 힙 메모리에 할당된다.</li>
<li>studentLee 라는 변수에 new Student()로 클래스를 생성하면, studentLee 변수는 stack 메모리에 생성되어 heap 메모리에 저장된 instance의 주소를 가리키게 된다.</li>
<li>studentSong 이라는 새로운 변수에 new Student()로 클래스를 생성하면, studentSong과 studentLee의 인스턴스는 각각 다른 메로리 공간을 갖는다.
즉, studentSong과 studentLee는 서로 다른 주소를 가리키게 된다.</li>
<li>heap 메모리는 추후 배우게 될 가비지 컬렉션을 통해 수거된다.</li>
</ol>
<h1 id="용어-정리">용어 정리</h1>
<table>
<thead>
<tr>
<th align="center">용어</th>
<th align="center">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="center">객체</td>
<td align="center">객체 지향 프로그램의 대상, 생성된 인스턴스</td>
</tr>
<tr>
<td align="center">클래스</td>
<td align="center">객체를 프로그래밍하기 위해 코드로 만든 상태</td>
</tr>
<tr>
<td align="center">인스턴스</td>
<td align="center">클래스가 메모리에 생성된 상태</td>
</tr>
<tr>
<td align="center">멤버 변수</td>
<td align="center">클래스의 속성, 특성</td>
</tr>
<tr>
<td align="center">메서드</td>
<td align="center">멤버 변수를 이용하여 클래스의 기능을 구현</td>
</tr>
<tr>
<td align="center">참조 변수</td>
<td align="center">메모리에 생성된 인스턴스를 가리키는 변수</td>
</tr>
<tr>
<td align="center">참조 값</td>
<td align="center">생성된 인스턴스의 메모리 주소 값</td>
</tr>
</tbody></table>
<h1 id="생성자constructor">생성자(constructor)</h1>
<ul>
<li>인스턴스 생성 시 new 키워드와 함께 사용했던 생성자
Student studentLee = new Student() 에서 <strong>Student()</strong>가 생성자다.</li>
<li>생성자는 객체를 처음 생성하면서 해야될 일들을 구현하는 것이다.</li>
<li>클래스의 생성자가 하나도 없는 경우 자바 컴파일러가 코드를 컴파일하기 전에 default 생성자를 넣어준다. (매개변수도 없고, 실행 코드도 없는 생성자)</li>
<li>생성자가 하나라도 있으면 default 생성자는 자동으로 생기지 않기 때문에 필요하다면 작성해주어야 한다.</li>
</ul>
<pre><code class="language-java">// 생성자 기본 문법
&lt;modifiers&gt; &lt;class_name&gt; ([&lt;argument_list&gt;]){
    [&lt;statements&gt;]
}</code></pre>
<ul>
<li>생성자는 인스턴스를 초기화할 때의 명령어 집합이다.</li>
<li>생성자의 이름은 그 클래스의 이름과 같다.</li>
<li>생성자는 메소드가 아니다. 때문에 상속되지 않으며, 리턴 값은 없다.</li>
</ul>
<p>Student class에 작성해보겠다.</p>
<pre><code class="language-java">public class Student {
    // 멤버 변수를 정의
    int studentID;
    String studentName;
    int grade;
    String address;

    // 생성자(constructor) 정의
    public Student(int id, String name) {
        studentID = id;
        studentName = name;
    }

    public static void main(String[] args) {
        Student studentLee = new Student();    //클래스 생성
        //생성된 클래스의 멤버 변수를 초기화
        studentLee.studentID = 20220210;
        studentLee.studentName = &quot;이순신&quot;;
        studentLee.grade = 2;
        studentLee.address = &quot;서울시 서초구 서초동&quot;;
        //클래스의 메서드 호출
        studentLee.showStudentInfo();
    }
}
</code></pre>
<p>위와 같이 class 내부에 생성자를 정의할 수 있지만 main()에서 에러가 난다.
그 이유는 생성자를 정의해주었기 때문에 default 생성자를 자동으로 생성해주지 않기 때문이다.
에러를 수정하기 위한 방법은 두 가지가 있다.</p>
<ol>
<li>new Student() 부분을 new Student(20220210, &quot;이순신&quot;) 처럼 바꿔준다.</li>
<li>class 내부에 default 생성자를 직접 만들어준다. ex) public Student( ) { }</li>
</ol>
<h1 id="생성자-오버로드-constructor-overload">생성자 오버로드 (constructor overload)</h1>
<ul>
<li><p>필요에 의해 생성자를 추가하는 경우 여러 개의 생성자가 하나의 클래스에 있을 수 있다.
(다른 매개변수, 다른 구현부를 가지고 하나의 클래스에 존재할 수 있다.)</p>
<pre><code class="language-java">public class Person {
  String name;
  float height;
  float weight;

  //default 생성자
  public Person() {}
  //이름을 매개변수로 입력받는 생성자
  public Person(String pname) {
      name = pname;
  }
  //이름, 키, 몸무게를 매개변수로 입력받는 생성자
  public Person(String pname, float pheight, float pweight) {
      name = pname;
      height = pheight;
      weight = pweight;
  }
}</code></pre>
<p>위와 같이 생성자를 만들어두면 Person클래스를 호출할 때는
new Person()
new Person(&quot;홍길동&quot;)
new Person(&quot;홍길동&quot;, 180, 73)
세 가지 방식으로 호출할 수 있게 되는 것이다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[10강. 클래스와 객체1(2)]]></title>
            <link>https://velog.io/@migratory_bird/Do-it-Java-Programming-10</link>
            <guid>https://velog.io/@migratory_bird/Do-it-Java-Programming-10</guid>
            <pubDate>Thu, 10 Feb 2022 16:04:44 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>Do it! 자바 프로그래밍 입문 온라인 강의를 수강하며 작성하였습니다.</li>
</ul>
</blockquote>
<ul>
<li>Section 1. 자바의 핵심 - 객체지향 프로그래밍</li>
<li>10강 &quot;클래스와 객체1(2)&quot;</li>
<li>메서드 &gt; 함수 정의하기 &gt; 함수와 스택 메모리 &gt; 클래스에 메서드 구현하기 &gt; 함수의 목적</li>
</ul>
<h1 id="메서드">메서드</h1>
<ul>
<li>함수의 일종으로, 객체의 기능을 제공하기 위해 클래스 내부에 구현되는 <strong>함수</strong></li>
<li>함수는 하나의 기능을 수행하는 일련의 코드로, 중복되는 기능은 함수로 구현하고,
함수를 호출하여 사용한다.</li>
</ul>
<h1 id="함수-정의하기">함수 정의하기</h1>
<pre><code class="language-java">// 정의하는 방법
[함수 반환형] [함수 이름] (매개변수1, 매개변수2...){
    기능 코드;
    return [결과값]
}
//예시
int add (int num1, int num2){
    int result;
    result = num1 + num2;
    return result;
}</code></pre>
<p>함수는 위와 같은 형식으로 정의한다.</p>
<ol>
<li>함수 반환형은 return값의 자료형을 나타내고, return 값이 없는 경우에는 <strong>void</strong>라고 쓴다.</li>
<li>함수 이름은 함수의 기능과 관련하여 명명한다.</li>
<li>매개변수는 함수의 수행을 위해 필요한 변수로, 함수를 사용할 때 넣어주는 값을 의미한다.</li>
</ol>
<pre><code class="language-java">public class FunctionTest {
    public static void main(String[] args) {
        int num1 = 10;
        int num2 = 30;

        int sum = addNum(num1, num2);    //1
        System.out.println(sum);    //3
    }

    public static int addNum(int n1, int n2) {    //2
        int result = n1 + n2;
        return result;
    }
}</code></pre>
<p><em>함수를 표현할 때 &quot;함수명()&quot; 으로 표현한다.</em></p>
<ol>
<li>main() 바깥에 addNum()을 정의하였고, main()에서 addNum()을 호출하면서 num1과 num2를 넘겨주었다.</li>
<li>addNum()은 int 값 두 개를 매개변수로 받아 두 값을 더해서 return한다.</li>
<li>함수의 return 값은 변수 sum에 대입된다.
<img src="https://images.velog.io/images/migratory_bird/post/f5418bdc-0c5e-45e7-902e-86aaeeef694b/image.png" alt="함수 호출 출력">
num1의 값인 10과 num2의 값인 30이 더해져서 sum에 40이 정상적으로 대입된 것을 확인할 수 있다.</li>
</ol>
<h1 id="함수와-스택-메모리">함수와 스택 메모리</h1>
<ul>
<li>함수가 호출될 때 사용하는 메모리를 <strong>스택(stack)</strong>이라고 한다.</li>
<li>함수의 기능 수행이 끝나면 자동으로 메모리가 반환된다.</li>
</ul>
<p><img src="https://images.velog.io/images/migratory_bird/post/d7313eb9-0bb5-449a-a8b9-286a63c986ff/image.png" alt="함수와 스택 메모리"></p>
<p>위에서 FunctionTest 클래스에서 함수를 정의하는 예제를 기준으로 설명하면,</p>
<ol>
<li>main()에서 int형의 num1, num2, sum 변수를 선언했으므로 4byte*3 = 12byte의 공간이 스택에 생성된다.</li>
<li>main()에서 addNum()을 호출하면서 addNum()에서 사용한 int형의 n1, n2, result 변수로 인해 또 12byte의 공간이 스택에 생성된다.</li>
<li>result값이 sum에 대입되고 addNum()이 사용한 공간은 자동으로 사라진다.</li>
</ol>
<h1 id="클래스에-메서드-구현하기">클래스에 메서드 구현하기</h1>
<ul>
<li><p>클래스의 메서드는 멤버변수를 사용하여 기능을 구현한다.</p>
<pre><code class="language-java">public class Student {
  // 멤버 변수를 정의
  int studentID;
  String studentName;
  int grade;
  String address;

  //학생 이름을 가져오는 메서드
  public String getStudentName() {
      return studentName;
  }
  //학생 이름을 설정하는 메서드
  public void setStudentName(String name) {
      studentName = name;
  }
}</code></pre>
</li>
<li><p>위 코드는 지난 강의에서 사용한 Student 클래스에 2개의 메서드를 추가한 것이다.</p>
</li>
<li><p>메서드 이름은 클래스 입장이 아닌 메서드를 사용하는 입장에서 이름을 정해주는 것이 좋다.</p>
</li>
<li><p>학생 이름을 가져오는 메서드는 getStudentName으로 명명하고, return 값이 String 자료형이므로 메서드 이름 앞에 반환형으로 String을 써주었다.</p>
</li>
<li><p>학생 이름을 설정하는 메서드는 setStudentName으로 명명하고, return 값 없이 studentName을 바꾸는 기능만 하므로 반환형을 void로 써주었다.</p>
</li>
</ul>
<h1 id="함수의-목적">함수의 목적</h1>
<ol>
<li><strong><em>코드를 효율적으로 구현하</em></strong>기 위해 함수로 기능을 분리해서 구현하고, 필요한 기능을 가져다 쓴다.</li>
<li><strong><em>유지보수가 용이</em></strong>하다. 함수를 호출하는 방식이 아니라면 같은 기능을 하는 여러 개의 코드를 수정할 때 여러번 수정해야하는 불편함이 있지만, 함수를 호출하는 방식으로 구현했다면 함수만 수정하면 된다.</li>
<li>함수의 이름은 함수의 기능을 나타내는 것이 좋고, 하나의 함수는 하나의 기능만 구현하는 것이 좋다.</li>
</ol>
]]></description>
        </item>
    </channel>
</rss>