본문 바로가기

WINK-(Web & App)/JAVA 스터디

[2024-2 Java 스터디] 김지나 #3주차

반응형

05장. 객체 지향 프로그래밍

 

✅ 객체 지향 프로그래밍

- '객체'들의 모임으로 컴퓨터 프로그램을 파악하는 것

- 객체들은 각각의 역할을 수행하고, 결괏값도 독립적으로 유지함

 

 

✅ 클래스

class Animal {
}

public class Sample {
    public static void main(String[] args) {
        
    }
}
// Animal 클래스 만들기 (원래 Aniaml 클래스 사용하려면 파일 이름 Animal.java여야 함!!)

- 이렇게 아무 내용이 없는 클래스여도 객체를 만드는 기능을 가지고 있음

class Animal {
}

public class Sample {
    public static void main(String[] args) {
        Animal dog = new Animal();
    }
}
// new 키워드로 dog 객체(= Animal 클래스의 인스턴스) 생성

 

☆ 객체와 인스턴스의 차이점 ☆

- new 키워드를 통해 만들어진 dog은 객체임. 이 객체는 Animal의 인스턴스임. => 인스턴스는 어떤 객체가 어떤 클래스의 객체인지를 나타낼 때 씀 (dog은 객체, dog은 Animal의 인스턴스) 

 

 

✅ 객체 변수

class Animal {
    String name; // String 변수 추가
}

public class Sample {
    public static void main(String[] args) {
        Animal dog = new Animal();
    }
}

- 객체 변수(= 인스턴스 변수, 멤버 변수, 속성): 클래스에 선언된 변수

- 도트 연산자(.)를 통해 접근 가능

객체.객체변수
dog.name // 객체: dog, 객체변수: name

- dog.name을 출력하면 -> null (객체 변수에 값을 대입하지 않았기 때문)

- ☆ 객체 변수의 값은 독립적으로 유지된다 ☆

ㄴ 클래스 내에서 두 개 이상의 객체를 만들어도 그 객체들의 name 변수는 독립적으로 유지됨 

 

 

✅ 메서드

- 클래스 내에 구현된 함수

- 메서드를 이용해서 객체 변수에 값 대입 

class Animal {
    String name;

    public void setName(String name) {
        this.name = name; 
    } //setName 메서드로 name에 값 대입
}

public class Sample {
    public static void main(String[] args) {
        Animal dog = new Animal();
        dog.setName("ddoddo"); // 메서드 호출
        System.out.println(dog.name);
    }
}

- 메서드 내에 this는 Animal 클래스에 의해 생성된 객체(dog)를 지칭 => this.name = dog.name

- 매개 변수: 메서드에 전달된 입력값을 저장하는 변수

- 인수: 메서드를 호출할 때 전달하는 입력값

 

- 메서드의 구조

리턴자료형 메서드명(입력자료형1 매개변수1, 입력자료형2 매개변수2, ...) {
    ...    
    return 리턴값;  // 리턴자료형이 void 인 경우에는 return 문이 필요 x
}

 

- 메서드의 종류

① 입력값 O, 리턴값 O

int sum(int a, int b) {
    return a+b;
}
/* 입력값: int a, int b
리턴값: int (a+b) */

Sample sample = new Sample();
int result = sample.sum(3, 4);
// sum의 리턴 자료형이 int이기 때문에 result의 자료형도 int여야 함
//메서드 호출: 리턴값_받을_변수 = 객체.메서드명(입력인수1, 입력인수2, ...)

 

② 입력값 X, 리턴값 O

String say() {
	return "Hi";
} 
/* 입력값: 없음
리턴값: String ("Hi") */

// 입력 인수가 없다면 괄호 안을 비움
Sample sample = new Sample();
String a = sample.say();
System.out.println(a); // "Hi" 출력
// 메서드 호출: 리턴값_받을_변수 = 객체.메서드명()

 

③ 입력값 O, 리턴값 X

void sum(int a, int b) {
    System.out.println(a + "더하기 " + b + "는 "+ (a+b) + "입니당.");
}
/* 입력값: int a, int b 
리턴값: void (리턴값 없음) <- 리턴값 없는 메서드는 리턴 자료형 부분에 void 표기 */

Sample sample = new Sample();
sample.sum(3, 4); // 3 더하기 4는 7입니당. 출력 <- System.out.println을 통해 실행됐을 뿐 리턴값 아님
// 메서드 호출: 객체.메서드명(입력인수1, 입력인수2, ...)

 

④ 입력값 X, 리턴값 X

void say() {
    System.out.println("Hi");
}
/* 입력값: 없음
리턴값: void (리턴값 없음) */

Sample sample = new Sample();
sample.say(); // Hi 출력, 사용 방법은 이거 한 가지!!
// 메서드 호출: 객체.메서드명()

 

- return을 단독으로 사용하면 즉시 메서드를 빠져나갈 수 있음

- 메서드에서 쓰이는 매개 변수는 해당 메서드 내에서만 사용 가능. 메서드에 값(원시 자료형)을 전달할 때는 메서드 내에서만 그 값을 가짐(원본에 영향 x) 

- 메서드에 객체를 전달한 후 메서드가 객체의 값을 변경한다면 메서드 수행 이후에도 객체는 변경된 값을 가짐

 

 

✅ 값에 의한 호출과 객체에 의한 호출

class Updater {
    void update(int count) {
        count++;
    }
}

class Counter {
    int count = 0;  
}

public class Sample {
    public static void main(String[] args) {
        Counter myCounter = new Counter();
        System.out.println("before update:"+myCounter.count);
        Updater myUpdater = new Updater();
        myUpdater.update(myCounter.count);
        System.out.println("after update:"+myCounter.count);
    }
}
/* before update:0
after update:0 출력 */

- update 메서드의 입력값인 객체 변수 count는 int 자료형이기 때문에 update 메서드를 실행시키더라도 값에 변화가 없음

class Updater {
    void update(Counter counter) {
        counter.count++;
    }
}

class Counter {
    int count = 0;
}

public class Sample {
    public static void main(String[] args) {
        Counter myCounter = new Counter();
        System.out.println("before update:"+myCounter.count);
        Updater myUpdater = new Updater();
        myUpdater.update(myCounter);
        System.out.println("after update:"+myCounter.count);
    }
}
/* before update:0
after update:1 출력 */

- update 메서드의 입력값이 객체로 바뀜. (Counter counter) -> 메서드 수행 후 객체의 변경된 값이 유지됨

 


객관식 문제

Q1. 객체지향 프로그래밍(OOP)의 4대 특징이 아닌 것은?

A1. d) 복사

 

Q2. 클래스에서 필드와 메서드의 차이점은 무엇인가?

A2. a) 필드는 객체의 상태를 나타내고, 메서드는 동작을 정의한다.

 

Q3. 다음 중 this 키워드의 역할은 무엇인가?

A3. b) 현재 객체를 참조한다.

 

Q4. 클래스에서 this 키워드를 사용하는 이유는 무엇인가?

A4. a) 같은 이름의 지역 변수와 필드를 구분하기 위해

 

Q5. 메서드의 리턴 타입이 void인 경우, 메서드가 반환하는 값은?

A5. c) 아무 값도 반환하지 않는다.

 

Q6. 아래 코드에서 출력값은?

public class Example {
    int a = 5;
    public void setA(int a) {
        this.a = a;
    }
    public static void main(String[] args) {
        Example ex = new Example();
        ex.setA(10);
        System.out.println(ex.a);
    }
}

A6. b) 10

 

Q7. 매개변수(parameter)와 인자(argument)의 차이는 무엇인가?

A7. a) 매개변수는 메서드 정의 시 사용되고, 인자는 메서드 호출 시 전달된다.

 

Q8. 메서드가 값을 반환하는 데 사용하는 키워드는?

A8. a) return

 

Q9. 메서드 내에서 선언된 변수의 효력 범위(scope)는?

A9. d) 메서드 내에서만 유효하다.

 

Q10. 자바에서 call by value의 의미는?

A10. c) 값의 복사본을 전달한다.

 

Q11. 객체를 생성할 때 사용하는 키워드는?

A11. c) new

 

Q12. 다음 중 클래스 멤버에 해당하지 않는 것은?

A12. d) 지역 변수

 

Q13. 다음 중 지역 변수와 필드를 구분하는 올바른 방법은?

A13. c) 지역 변수는 메서드 내에서만 사용된다.

 

Q14. 자바에서 기본 데이터 타입을 객체로 감싸는 클래스는?

A14. a) Wrapper 클래스

 

Q15. 객체의 생성자를 호출하는 역할을 하는 것은?

A15. d) new 연산자

 

Q16. return 키워드는 언제 사용되는가? (중요)

A16. a) 메서드의 실행을 종료하고 값을 반환할 때

 

Q17. call by reference는 무엇을 의미하는가?

A17. b) 객체의 참조를 전달한다.

 

서술형 문제

Q1. 클래스와 객체의 차이점?

A1. 클래스는 객체를 생성하는 템플릿이고, 객체는 클래스를 통해 생성된 인스턴스이다. 

 

Q2. this 키워드를 사용하는 이유?

A2. this 키워드는 현재 객체를 참조하며 필드와 매개변수 이름이 같을 때 구분하기 위해 사용한다.

 

Q3. 매개변수와 인자의 차이점?

A3. 매개 변수는 메서드에 전달된 입력값을 저장하는 변수고 인수는 메서드를 호출할 때 전달하는 입력값이다.

 

Q4. 필드와 지역 변수의 차이점을 설명하고, this 키워드가 사용되는 이유를 함께 설명하기.

A4. 필드는 클래스 내에서 선언된 변수이고 지역 변수는 메서드 내에서 선언된 변수이다. this 키워드를 사용하는 이유는 필드와 지역변수가 같은 이름을 가진 변수일 때 this를 사용하여 명확하게 구분할 수 있기 때문이다. 

 

Q5. 자바에서 call by value와 call by reference의 차이?

A5. call by value는 값의 복사본을 전달하고 call by reference는 객체의 참조를 전달한다.

 

Q6. 메서드 내에서 선언된 변수의 효력 범위(scope)란?

A6. 지역 변수는 선언된 블록 내에서만 유효하다. 

 

Q7. 자바에서 생성자(constructor)의 역할?

A7. 객체의 초기화를 위해 사용한다.

 

Q8. 클래스에서 final 키워드를 사용하는 이유와 그 효과?

A8. 변수에 final 키워드를 사용하면 값을 변경할 수 없고, 메서드에 사용하면 오버라이드를 할 수 없으며 클래스에 사용하면 상속할 수 없다. 

 

Q9. 메서드가 return을 사용하는 이유와 반환되는 값을 처리하는 방법?

A9. return은 메서드의 실행을 종료하고 값을 반환하기 위해 사용된다. 리턴값은 바로 출력하기도 하고, 다른 메서드의 인자로 전달될 수도 있다. 

 

Q10. 객체를 생성하는 방법과 그 과정에서 new 연산자의 역할?

A10. new 키워드를 사용해서 객체를 생성할 수 있다. (Sample sample = new Sample();) new 연산자는 메모리에 객체를 할당하고 해당 객체의 생성자를 호출해 초기화한다. 

 

Q11. 클래스와 인터페이스의 차이점?

A11. 클래스는 객체를 생성하는 기능을 가지고 있으며, 인터페이스는 클래스가 구현해야 하는 메서드의 집합이다. 

 

Q12. 다음 코드에서 this 키워드가 어떻게 동작하는지 설명하기

public class Test {
    int value;
    public Test(int value) {
        this.value = value;
    }
}

A12. 이 코드에서, 매개변수 value와 필드 value의 이름이 동일하다. this.value는 Test 클래스의 value 필드를 가리킨다. 

 

Q13. 지역 변수와 전역 변수의 차이점?

A13. 지역 변수는 선언된 블록 내에서만 유효하고, 전역 변수는 모든 메서드에서 접근 가능한 변수이다.

 

코딩테스트 문제

Q1. https://school.programmers.co.kr/learn/courses/30/lessons/12906

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

Q2.

import java.util.*;

class NumberFilter {
    private List<Integer> numbers;

    public NumberFilter(int[] numbers) {
        this.numbers = new ArrayList<>();
        for (int number : numbers) {
            this.numbers.add(number);  
        }
    }
    
    public List<Integer> removeConsecutiveDuplicates() {
        List<Integer> result = new ArrayList<>();  

        for (int i = 0; i < numbers.size(); i++) {
            if (i == 0 || !numbers.get(i).equals(numbers.get(i - 1))) {
                result.add(numbers.get(i));
            }
        }
        return result; 
    }
}

public class Main {
    public static void main(String[] args) {
        int[] arr = {1, 1, 3, 3, 0, 1, 1};

        NumberFilter numberFilter = new NumberFilter(arr);
        List<Integer> filteredNumbers = numberFilter.removeConsecutiveDuplicates();
        System.out.println(filteredNumbers);  // [1, 3, 0, 1]
    }
}
반응형