객체 지향 프로그래밍
자바로 계산기를 구현해보자
class Calculator {
static int result = 0;
static int add(int num) {
result += num;
return result;
}
}
public class Sample {
public static void main(String[] args) {
System.out.println(Calculator.add(3)); // 3
System.out.println(Calculator.add(4)); // 7
}
}
음? 계산기 2대가 필요해짐
class Calculator1 {
static int result = 0;
static int add(int num) {
result += num;
return result;
}
}
class Calculator2 {
static int result = 0;
static int add(int num) {
result += num;
return result;
}
}
public class Sample {
public static void main(String[] args) {
System.out.println(Calculator1.add(3)); // 3
System.out.println(Calculator1.add(4)); // 7
System.out.println(Calculator2.add(3)); // 3
System.out.println(Calculator2.add(7)); // 10
}
}
// Calculator1과 Calculator2는 서로 영향 X
필요한 계산기가 많아질 때 클래스를 계속 추가하면 너무 복잡해짐... 그러면 어떻게 헤야할까?
class Calculator {
int result = 0;
int add(int num) {
result += num;
return result;
}
}
public class Sample {
public static void main(String[] args) {
Calculator cal1 = new Calculator(); // 계산기1 객체를 생성한다.
Calculator cal2 = new Calculator(); // 계산기2 객체를 생성한다.
System.out.println(cal1.add(3)); // 3
System.out.println(cal1.add(4)); // 7
System.out.println(cal2.add(3)); // 3
System.out.println(cal2.add(7)); //10
}
}
Caculator 클래스로 cal1, cal2라는 객체를 만들었다! 필요한 계산기가 추가될 때마다 객체만 늘리면 되니 아주 간편하고 좋군! Calculator 클래스에 더하기 말고 다른 연산 메서드도 추가할 수 있음 bb
이게 바로 객체 지향 프로그램의 장점이다!!
클래스
그렇다면 클래스란 과연 무엇인지...
클래스는 객체를 만드는 기능을 가진다
class Animal {
}
public class Sample {
public static void main(String[] args) {
Animal cat = new Animal();
Animal dog = new Animal();
Animal duck = new Animal(); // 객체를 영원히 추가할 수 잇삼
}
}
Animal 클래스의 인스턴스인 cat이 만들어졌다! (인스턴스: 클래스에 의해 만들어진 객체; cat은 객체 & Animal의 인스턴스)
Animal 클래스로 무수히 많은 객체를 만들 수 있다 bb
class Animal {
String name; // Animal 클래스에 name이라는 String 변수를 추가
}
public class Sample {
public static void main(String[] args) {
Animal cat = new Animal();
System.out.println(duck.name); // null, 왜냐하면 아무런 값도 대입하지 않앗삼
}
}
name이라는 String 변수처럼클래스에 선언된 변수를 객체 변수라고 한다 (클래스에 의해 생성되는 변수: 객체, 클래스에 선언된 변수: 객체 변수)
객체 변수는 객체.객체변수 와 같이 도트 연산자를 이용하여 접근하고, 값을 대입할 수 있다 (duck.name으로 접근)
그러면은 이제 객체 변수에 값을 대입해보자메서드를 이용하는 방법이 있음 (여기서 메서드란? 클래스 내에 구현된 함수!)
class Animal {
String name;
public void setName(String name) { // setName이라는 메서드 추가햇삼
this.name = name;
}
}
public class Sample {
public static void main(String[] args) {
Animal cat = new Animal();
duck.setName("donald");
System.out.println(duck.name); // 이제 donald 출력
}
}
setName 메서드는 입력으로 name이라는 문자열을 받고 출력은 없는 형태의 메서드
객체.메서드 로 호출한당 (duck.setName("donald");) >> 메서드 입력 항목(name)으로 문자열("donald") 전달
이때 setName 메서드 내부에 선언된 this는 바로 duck 객체를 지칭 (만약 Animal cat = new Animal(); > cat.setName("tom"); > 이러면 this는 cat 객체를 지칭)
따라서 이때 this.name = name; == this.name = "donald"; == duck.name = "donald"; 임!그리고 객체 변수는 공유되지 않음 주의 완전히 독립적
메서드
메서드는 입력값을 가지고 어떤 일을 하고 결과값을 내어놓는 일을 함
같은 내용을 반복하는 일을 할 때 메서드를 이용해서 한 번에 해결할 수 있도록 하자
public class Sample {
int sum(int a, int b) {
return a + b;
}
public static void main(String[] args) {
int a = 3;
int b = 4;
Sample sample = new Sample();
int c = sample.sum(a, b);
System.out.println(c); // 7
}
}
이런 식으로 말이당
또, 메서드에 전달된 입력값을 저장하는 변수를 매개 변수, 메서드를 호출할 때 전달하는 입력값을 인수 라고 함
위 코드에서 a와 b는 매개변수, c는 인수가 되는 것이다
메서드의 입력값과 리턴값
입력값 ---> 메서드(블랙박스와 같은 역할을 한다.) ----> 리턴값
메서드는 이런 구조를 가짐!
리턴자료형 메서드명(입력자료형1 매개변수1, 입력자료형2 매개변수2, ...) {
...
return 리턴값; // 리턴자료형이 void 인 경우에는 return 문이 필요X
}
그리고 메서드는 입출력 유무에 따라 4가지로 분류됨
1. 입력값O 리턴값O : 리턴값_받을_변수 = 객체.메서드명(입력인수1, 입력인수2, ...)
int sum(int a, int b) { // 입력값: int 자료형 a, b
return a+b; // 리턴값: int 자료형
}
Sample sample = new Sample();
int result = sample.sum(3, 4); // 7
2. 입력값X 리턴값O : 리턴값_받을_변수 = 객체.메서드명()
public class Sample {
String say() { // 입력값 X
return "Hi"; // 리턴값: String 자료형
}
public static void main(String[] args) {
Sample sample = new Sample();
String a = sample.say();
System.out.println(a); // "Hi"
}
}
3. 입력값O 리턴값X : 객체.메서드명(입력인수1, 입력인수2, ...)
public class Sample {
void sum(int a, int b) { // 입력값: int 자료형 a, int 자료형 b
System.out.println(a+"과 "+b+"의 합은 "+(a+b)+"입니다."); // return 명령어X -> 리턴값X
}
public static void main(String[] args) {
Sample sample = new Sample();
sample.sum(3, 4); // 7
}
}
4. 입력값X 리턴값X : 객체.메서드명()
public class Sample {
void say() {
System.out.println("Hi");
}
public static void main(String[] args) {
Sample sample = new Sample();
sample.say(); // "Hi"
}
}
cf) 메서드를 빠져나가고 싶을 때 return을 단독으로 사용해도 됨!
값에 의한 호출과 객체에 의한 호출
메서드에 값을 전달하는 것 vs 객체를 전달하는 것 << 너무 다름!
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); // update 메서드는 값(int 자료형)을 전달받앗삼
System.out.println("after update:"+myCounter.count);
}
}
before update:0
after update:0
Counter 클래스에 의해 생성된 myCounter 객체의 객체 변수인 count 값을 Updater클래스를 이용해 증가시키려 했지만 실패했다... 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
그래서 이렇게 고쳐보았다! int count 처럼 값을 전달받는 게 아닌 Counter counter 처럼 객체를 전달받도록 말이당
QUIZ
1. 객체 지향 프로그래밍의 4대 특징이 아닌 것은?
- a 복사
2. 클래스에서 필드와 메서드의 차이점은 무엇인가?
- d 필드는 객체의 상태를 나타내고, 메서드는 동작을 정의한다
3. 다음 중 this 키워드의 역할은 무엇인가?
- b 현재 객체를 참조한다
4. 클래스에서 this 키워드를 사용하는 이유는 무엇인가?
- a 같은 이름의 지역 변수와 필드를 구분하기 위해
5. 메서드의 리턴 타입이 void인 경우, 메서드가 반환하는 값은?
- c 아무 값도 반환하지 않는다
6. 아래 코드에서 출력값은?
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);
}
}
- 10
7. 매개변수와 인자의 차이는 무엇인가?
- a 매개변수는 메서드 정의 시 사용되고, 인자는 메서드 호출 시 전달된다
8. 메서드가 값을 반환하는 데 사용하는 키워드는?
- return
9. 메서드 내에서 선언된 변수의 효력 범위는?
- d 메서드 내에서만 유효하다
10. 자바에서 call by value의 의미는?
- c 값의 복사본을 전달한다
11. 객체를 생성할 때 사용하는 키워드는?
- c new
12. 다음 중 클래스 멤버에 해당하지 않는 것은?
- d 지역 변수
13. 다음 중 지역 변수와 필드를 구분하는 올바른 방법은?
- c 지역 변수는 메서드 내에서만 사용된다
14. 자바에서 기본 데이터 타입을 객체로 감싸는 클래스는?
- c Wrapper 클래스
15. 객체의 생성자를 호출하는 역할을 하는 것은?
- d new 연산자
16. return 키워드는 언제 사용되는가?
- a 메서드의 실행을 종료하고 값을 반활할 때
17. call by reference는 무엇을 의미하는가?
- b 객체의 참조를 전달한다
서술형1. 클래스와 객체의 차이점?- 클래스는 객체를 만드는 기능을 가졌다. 객체는 클래스를 기반으로 생성된 인스턴스이다.
서술형2. this 키워드를 사용하는 이유?- 현재 객체의 인스턴스를 참조하여 메서드 내부에서 해당 객체의 메서드에 접근할 때 사용한다. 또, 메서드의 매개변수와 클래스의 필드 이름이 동일한 경우 this를 이용하여 구분한다.
서술형3. 매개변수와 인자의 차이점?- 매개변수는 메서드에 전달된 입력값을 저장하는 변수이고, 인자는 메서드를 호출할 때 전달하는 입력값이다.
서술형4. 필드와 지역 변수의 차이점을 설명하고, this 키워드가 사용되는 이유를 함께 설명하기- 필드는 클래스의 속성을 나타내는 변수이고 클래스 내부에서 선언되어 클래스의 모든 메서드에 접근할 수 있다. 지역 변수는 메서드나 생성자, 블록 내부에 선언된 변수이고 해당 블록 내에서만 유효하여 메서드가 종료되면 사라진다. this 키워드는 현재 객체를 참조하거나 매개변수와 클래스 필드의 이름이 같을 때 이름의 충돌을 해결하기 위해 사용된다.
서술형5. 자바에서 call by value와 call by reference의 차이?- call by value의 경우 메서드에 매개변수를 전달할 때 실제 값의 복사본이 전달된다. 따라서 메서드 내에서 매개변수의 값을 변경해도 원래 변수에 영향을 주지 않는다. 반면 call by reference는 메서드에 매개변수를 전달할 때 객체의 참조가 전달되어 메서드 내에서 매개변수의 값을 변경하면 원래 변수에도 영향을 준다.
서술형6. 메서드 내에서 선언된 변수의 효력 범위란?- 메서드 내에서 선언된 변수는 지역 변수로, 해당 메서드 내에서만 유효하다. 메서드가 종료되면 지역 변수도 사용할 수 없어 사라진다.
서술형7. 자바에서 생성자의 역할?
- 생성자는 객체가 생성될 때 호출되어 해당 객체의 초기 상태를 설정해 초기화하는 역할을 한다.
서술형8. 클래스에서 final 키워드를 사용하는 이유와 그 효과?- final 키워드는 한 번 설정된 것을 변경할 수 없어 클래스, 메서드, 필드를 고정시키는 데 사용되며 안정성을 높인다.
서술형9. 메서드가 return을 사용하는 이유와 반환되는 값을 처리하는 방법?- return 키워드는 메서드가 더 이상 실행되지 않도록 하고, 메서드가 처리한 결과를 호출한 곳으로 반환할 때에도 사용하여 다른 메서드에 인자로 전달하는 등의 방식으로 처리한다. 반환값을 출력하거나 계산에 직접 사용하기도 한다.
서술형10. 객체를 생성하는 방법과 그 과정에서 new 연산자의 역할?- 객체를 생성할 클래스를 정의하고 new 연산자를 사용하여 클래스의 인스턴스를 생성한다. new 연산자는 객체를 위한 메모리를 할당해주며 생성자를 호출하여 초기화시켜준다.
서술형11. 클래스와 인터페이스의 차이점?- 클래스는 객체의 필드와 메서드을 정의하여 인스턴스를 생성하고 구현한다. 반면 인터페이스는 객체가 수행해야 하는 메서드의 집합으로 메서드의 구현 내용은 포함하지 않는다.
서술형12. 다음코드에서 this 키워드가 어떻게 동작하는지 설명하기
public class Test {
int value;
public Test(int value) {
this.value = value;
}
}
- 현재 객체를 참조하고 필드와 매개변수를 구분한다. 생성자 매개변수 value와 클래스 필드 value가 같은 이름이라 this.value는 클래스 필드를, value는 생성자 매개변수를 가리킨다.
서술형 13. 지역 변수와 전역 변수의 차이점- 지역 변수는 메서드 내에서 선언된 변수로 해당 메서드 안에서만 사용가능하고, 전역 변수(필드)는 클래스 내에서 선언된 변수로 모든 메서드에 접근할 수 있다.
코딩테스트
1.
2.
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]
}
}
'WINK-(Web & App) > JAVA 스터디' 카테고리의 다른 글
[2024-2 Java 스터디] 김지나 #3주차 (0) | 2024.10.31 |
---|---|
[2024-2 Java 스터디] 김태일 #3주차 (1) | 2024.10.31 |
[2024-2 Java 스터디] 김민서 #3주차 (1) | 2024.10.30 |
[2024-2 Java 스터디] 정채은 #2주차 (0) | 2024.10.18 |
[2024-2 Java 스터디] 김지수 #2주차 (2) | 2024.10.18 |