항해99 온보딩 스터디[Java 언어 기초] 6일차

Hohomi·2023년 3월 12일
0
post-thumbnail

스터디 6일차 : 객체지향 프로그래밍 1 (Object-oriented Programming)


✏️ static메서드와 인스턴스 메서드

static 메서드(클래스 메서드)

  • 클래스 변수와 같이, 객체(인스턴스)를 생성하지 않고도 호출이 가능하다.
  • 클래스이름.메서드이름(매개변수) 의 형태로 호출
  • 클래스 설계 시 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다.
  • 클래스 메서드는 인스턴스변수를 사용할 수 없다.
  • 메서드 내에서 인스턴스 변수나 인스턴스 메서드를 사용할 필요가 없을 때 static 붙이는 걸 고려한다.

인스턴스 메서드

  • 반드시 객체를 생성해야만 호출 가능
  • 메서드 호출 시 매개변수를 반드시 필요로 하지는 않는다.
class MyMath2 {
  long a, b;

// 인스턴스 변수 a,b만을 이용해서 작업하므로 매개변수가 필요없다.
  long add() { return a + b; }
  long subtract() { return a - b; }

// 인스턴스 변수와 관계없이 매개변수만으로 작업이 가능하다.
  static long add(long a, long b) { return a + b; }
  static long subtract(long a, long b) { return a - b; }
}

class Ex6_9 {
public static void main(String[] args) {
	//클래스 메서드 호출. 인스턴스 생성 없이 호출 가능
	System.our.println(MyMath2.add(200L,100L));
	

  	MyMath2 mm = new MyMath2();
    mm.a = 200L;
    mm.b = 100L;
    //인스턴스 메서드는 객체생성 후에만 호출이 가능
    System.out.println(mm.add());
  	}
}

✏️ 오버로딩(overloading)

  • 한 클래스 내에 이름이 같은 메서드가 있어도 매개변수의 개수나 타입이 다르면 같은 이름을 사용하여 메서드를 정의할 수 있다.

    오버로딩이 가능한 조건
    - 메서드 이름이 같아야 한다.
    - 매개변수의 개수 또는 타입이 달라야 한다.
    - 반환 타입은 같든 다르든 상관없다.


✏️ 생성자(constructor)

  • 인스턴스가 생성될 때 호출되는 '인스턴스 초기화 메서드' => 인스턴스 변수들을 초기화한다.
  • 메서드처럼 클래스 내에 선언되며, 구조도 메서드와 유사하지만 리턴값이 없다.
  • 생성자의 이름은 클래스의 이름과 같아야 한다.
class Point {
	Point() {
    ...
    }			//매개변수가 없는 생성자

	Point(int x,int y) {
    ...
    }
    ...
}				//매개변수가 있는 생성자
  • 인스턴스를 생성한 다음에 인스턴스 변수의 값을 변경하는 것보다 매개변수를 갖는 생성자를 사용하는 게 코드를 보다 간결&직관적이게 만들 수 있다.
Car c = new Car(); 	// 인스턴스 생성 수 인스턴스 변수값 변경
c.color = "white";
c.gearType = "auto":
c.door = 4;

Car c = new Car("white","auto",4); // 매개변수를 갖는 생성자 사용

생성자에서 다른 생성자 호출하기 - this()

  • 생성자 이름으로 클래스 이름 대신 this를 사용한다.
  • 한 생성자에서 다른 생성자를 호출 시 반드시 첫 줄에서만 호출이 가능하다.
class Car2 {
    String color;
    String gearType;
    int door;

    Car2() {
    	this("white","auto",4);
    }

	Car2(String color) {
    	this(color,"auto",4);
    }
    
    Car2(String color, String gearType, int door) {
    this.color = color;
    this.gearType = gearType;
    this.door = door;
 	}
}

Class Ex6_13 {
	public static void main(String[] args) {
    	Car2 c1 = new Car2();
        Car2 c2 = new Car2("blue");
    }
}

객체 자신을 가리키는 참조변수 - this

  • this는 인스턴스멤버에서만 사용가능하다. 클래스 메서드에서는 사용불가
Car(String c, String g, int d) {
	color = c;
    gearType = g;
    door = d;
}

// this를 이렇게 사용 가능
Car(String color, String gearType, int door) {
	this.color = color;
    this.gearType = gearType;
    this.door = door;
}



📖 『JAVA의 정석 기초편』 연습문제 풀이!

Chapter 6

6-7.

다음은 컴퓨터 게임의 병사(marine)를 클래스로 정의한 것이다. 이 클래스의 멤버 중에 static을 붙여야 하는 것은 어떤 것들이고 그 이유는 무엇인가? (단, 모든 병사의 공격력과 방어력은 같아야 한다.)

class Marine {
    int x = 0, y = 0; //Marine의 위치좌표(x,y)
    int hp = 60; //현재 체력
    static int weapon = 6; // 공격력       
    static int armor = 0; // 방어력

    void weaponUp() {
        weapon++;
    }

    void armorUp() {
        armor++;
    }

    void move(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

⭐️ 모든 병사의 공격력과 방어력은 같아야 하기 때문에 인스턴스 값을 고정시켜야 하므로 weapon과 armor에 static을 붙인다.

6-8.

다음 중 생성자에 대한 설명으로 옳지 않은 것?

  1. 모든 생성자의 이름은 클래스의 이름과 동일해야 한다.
  2. 생성자는 객체를 생성하기 위한 것이다.
  3. 클래스에는 생성자가 반드시 하나 이상 있어야 한다.
  4. 생성자가 없는 클래스는 컴파일러가 기본 생성자를 추가한다.
  5. 생성자는 오버로딩 할 수 없다.

정답: 2, 5
-2번 : 객체는 연산자 new가 생성한다. 생성자는 인스턴스 변수를 초기화하는 역할.
-5번 : 생성자도 오버로딩 할 수 있다.

6-9.

다음 중 this에 대한 설명으로 맞지 않은 것?

  1. 객체 자신을 가리키는 참조변수이다.
  2. 클래스 내에서라면 어디서든 사용할 수 있다.
  3. 지역변수와 인스턴스 변수를 구별할 때 사용한다.
  4. 클래스 메서드 내에서는 사용할 수 없다.

정답: 2
-클래스 내 static메서드에서는 사용 불가하다.

6-10.

다음 중 오버로딩이 성립하기 위한 조건이 아닌 것?

  1. 메서드의 이름이 같아야 한다.
  2. 매개변수의 개수나 타입이 달라야 한다.
  3. 리턴타입이 달라야 한다.
  4. 매개변수의 이름이 달라야 한다.

정답: 3, 4

6-11.

다음 중 아래의 add메서드를 올바르게 오버로딩한 것은?

long add(int a, int b) { return a+b; }
1. long add(int x, int y) { return x+y; }
2. long add(long a, long b) { return a+b ; }
3. int add(byte a, byte b) { return a+b; }
4. int add(long a, int b) { return (int)(a+b); }

정답: 2, 3, 4

6-12.

다음 중 초기화에 대한 설명으로 옳지 않은 것?

  1. 멤버변수는 자동 초기화되므로 초기화하지 않고도 값을 참조할 수 있다.
  2. 지역변수는 사용하기 전에 반드시 초기화해야 한다.
  3. 초기화 블럭보다 생성자가 먼저 수행된다.
  4. 명시적 초기화를 제일 우선적으로 고려해야 한다.
  5. 클래스 변수보다 인스턴스 변수가 먼저 초기화된다.

정답: 3,4,5
-3,4번 : 자동 초기화 -> 명시적 초기화 -> 초기화 블럭, 생성자 순서로 실행된다.

6-13.

다음 중 인스턴스 변수의 초기화 순서가 올바른 것?

  1. 기본값 - 명시적초기화 - 초기화블럭 - 생성자
  2. 기본값 - 명시적초기화 - 생성자 - 초기화블럭
  3. 기본값 - 초기화블럭 - 명시적초기화 - 생성자
  4. 기본값 - 초기화블럭 - 생성자 - 명시적초기화

정답: 1

6-14.

다음 중 지역변수에 대한 설명으로 옳지 않은 것?

  1. 자동 초기화되므로 별도의 초기화가 필요없다.
  2. 지역변수가 선언된 메서드가 종료되면 지역변수도 함께 소멸된다.
  3. 메서드의 매개변수로 선언된 변수도 지역변수이다.
  4. 클래스 변수나 인스턴스 변수보다 메모리 부담이 적다.
  5. 힙(heap) 영역에 생성되며 가비지 컬렉터에 의해 소멸된다.

정답: 1,5

6-15.

호출스택이 다음과 같은 상황일 때 옳지 않은 것?

println (color)
--------
method1
--------
method2
--------
main
  1. 제일 먼저 호출스택에 저장된 것은 main메서드이다.
  2. println메서드를 제외한 나머지 메서드들은 모두 종료된 상태이다.
  3. method2메서드를 호출한 것은 main메서드이다.
  4. println메서드가 종료되면 method1 메서드가 수행을 재개한다.
  5. main-method2-method1-println의 순서로 호출되었다.
  6. 현재 실행중인 메서드는 println 뿐이다.

정답: 2

6-16.⭐️

다음 코드의 실행 결과를 예측하여 적으시오.

class Quiz6_16 {
    public static void change(String str) {     //static 메서드
        str += "456";
    }

    public static void main(String[] args)
    {
        String str = "ABC123";
        System.out.println(str);
        change(str);
        System.out.println("After change: " + str);
    }
}

정답:
ABC123
ABC123

-조원분들과 의논하고 기술매니저님께 질문드렸던 문제다. 우리는 다들 두번째 str을 "ABC123456"으로 예상했는데 아니었다. 이유는? chanege메서드는 void 타입이고 따라서 안에 리턴값이 지정되어있지 않았다. 메서드가 실행되면 str에 "456"이 더해진 문자열이 만들어지지만 그것이 반환되지는 않는 것!

6-17. ⭐️

다음과 같이 정의된 메서드를 작성하고 테스트하시오.

  • 메서드명 : shuffle
  • 기능 : 주어진 배열에 담긴 값의 위치를 바꾸는 작업을 반복하여 뒤섞이게 한다. 처리한 배열을 반환한다.
  • 반환타입 : int[]
  • 매개변수 : int[] arr - 정수값이 담긴 배열
import java.util.Arrays;
class Quiz6_17 {
    public static int[] shuffle(int[] arr) {
        for (int i=0; i<arr.length; i++) {  //i를 배열 길이만큼 반복
            int n = (int)(Math.random()*arr.length);

            int tmp = arr[n];
            arr[n] = arr[i];
            arr[i] = tmp;
        }
        return arr;
    }

    public static void main(String[] args) {
        int[] original = {1,2,3,4,5,6,7,8,9};
        System.out.println(Arrays.toString(original));

        int[] result = shuffle(original);
        System.out.println(java.util.Arrays.toString(result));
    }
}

6-18.

다음과 같이 정의된 메서드를 작성하고 실행하시오.

  • 메서드명 : isNumber
  • 기능 : 주어진 문자열이 모두 숫자로만 이루어져있는지 확인. 모두 숫자로만 이루어져 있으면 true를, 그렇지 않으면 false를 반환. 만일 주어진 문자열이 null이거나 빈문자열""이면 false를 반환한다.
  • 반환티입 : boolean
  • 매개변수 : String str - 검사할 문자열
public class Quiz6_18 {
    public static boolean isNumber(String str) {
        if (str == null || str.equals(""))
            return false;

        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);

            if (ch < '0' || '9' < ch) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        String str = "123";
        System.out.println(str + "는 숫자입니까?" + isNumber(str));

        str = "1234o";
        System.out.println(str + "는 숫자입니까?" + isNumber(str));
    }
}

6-19.

Tv클래스를 주어진 로직대로 완성하시오. 완성한 후에 실행해서 주어진 실행결과와 일치하는지 확인하라.

class MyTv {
    boolean isPowerOn;
    int channel;
    int volume;

    final int MAX_VOLUME = 100;
    final int MIN_VOLUME = 0;
    final int MAX_CHANNEL = 100;
    final int MIN_CHANNEL = 1;

    void turnOnOff() {
        // (1) isPowerOn의 값이 true이면 false로, false이면 true로 바꾼다.
        isPowerOn = !isPowerOn;
        }

     void volumeUp() {
        // (2) volume의 값이 MAX_VOLUME보다 작을 때만 값을 1 증가시킨다.
        if (volume < MAX_VOLUME) {
            volume++;
        }
    }

    void volumeDown() {
        // (3) volume의 값이 MIN_VOLUME보다 클 때만 값을 1 감소시킨다.
        if (volume > MIN_VOLUME)
            volume--;
    }

    void channelUp() {
        //(4) channel의 값을 1 증가시킨다.
        // 만일 channel이 MAX_CHANNEL이면, channel의 값을 MIN_CHANNEL로 바꾼다.
        if(channel == MAX_CHANNEL) {
            channel = MIN_CHANNEL;
        } else {
            channel++;
        }
    }

    void channelDown() {
        //(5) channel의 값을 1 감소시킨다.
        //만일 channel이 MIN_CHANNEL이면, channel의 값을 MAX_CHANNEL로 바꾼다.
        if(channel == MIN_CHANNEL) {
            channel = MAX_CHANNEL;
        } else {
            channel--;
        }
    }
}

public class Quiz6_19 {
    public static void main(String[] args) {
        MyTv t = new MyTv();

        t.volume = 0;
        t.channel = 100;
        System.out.println("CH: " + t.channel + ", VOL: " + t.volume);

        t.channelDown();
        t.volumeDown();
        System.out.println("CH: " + t.channel + ", VOL: " + t.volume);

        t.volume = 100;
        t.channelUp();
        t.volumeUp();
        System.out.println("CH: " + t.channel + ", VOL: " + t.volume);
    }
}

// 실행결과
CH: 100, VOL: 0
CH: 99, VOL: 0
CH: 100, VOL: 100



✏️ 참고 자료

참고 도서 : 『JAVA의 정석 기초편』, 남궁 성, 도우출판

profile
게발로 개발하기

0개의 댓글