✏️ 0424
2주차 과제
Java 문법 종합반 강의_3주차
[ 특강 ] 학습법
2주차 과제
LinkedHashSet<String> strSet = new LinkedHashSet<>();
while (true) {
String text = sc.nextLine();
if (Objects.equals(text, "끝")) {
break;
}
strSet.add(text);
}
title = "[ Set 로 저장된 " + title + " ]";
System.out.println(title);
// 하나하나 순회할 수 있도록
Iterator<String> it = strSet.iterator();
for (int i = 0; i < strSet.size(); i++) {
int count = i + 1;
System.out.println(count + ". " + it.next());
}
기본적으로 순서가 없는 Set 컬랙션에서 순서 보장이 필요하다면
LinkedHashSet 을 사용한다
강의에서 설명들은 건 없고 이런 게 있다 정도에서만 기억하고 있어서 사용하기 전에 사용법을 찾아봤다
값 추가는 .add() 선택 삭제는 .remove() 전체 삭제는 .clear()
중복값은 제외
Set 의 값을 출력하는 방법
하나의 값만 출력하는 메서드는 따로 제공하지 않아 Iterator 를 사용하여 값을 출력해줘야 한다
Iterator<String> it = strSet.iterator();
iterator 는 저장된 객체를 한번씩 반복해서 가져오는 반복자다
strSet.next() 메서드를 통해 순차적으로 값을 가져올 수 있다
ArrayList 로 출력하거나 Map 으로 출력하는 방법은 강의 내에서 들었던 설명이라 쉽게 진행할 수 있었지만
Set 은 처음 써보기도 하고 값을 출력하는 방법에 대해 듣지 않아서 어려웠다
강의를 제대로 안들었나 싶어서 컬렉션 부분을 다시 틀기도 했다
컬렉션 부분은 버튼을 누르면 띡 하고 나오는 출력기 처럼 바로 나올 수 있을 정도로
공부하는 게 나중에 안 헷갈리고 좋을 것 같다
무한 루프를 돌리게 될지도...?
Java 문법 종합반_3주차
할게 짱 많다..!! 오늘 다 하기엔 힘들어 보인다
- Chapter 3
- 객체지향 프로그래밍에 대한 개념 이해
- 클래스를 설계하는 방법
- 객체의 구성요소(필드, 메서드, 생성자)에 대해서
- 클래스 변수, 인스턴스 변수의 차이점
- 생성자와 생성자 오버로딩
- this 와 this() 키워드에 대해
- 접근 제어자에 대해
- pakage 와 import 에 대해
- 상속, 오버라이딩을 통해 기능을 확장하는 방법
- super와 super() 키워드에 대해
- 다향성의 원리와 구현 방법
- 추상 클래스에 대해
- 인터페이스의 역할에 대해 이해가고 구성 요소와 구현 방법
- 인터페이스의 디폴트 메서드와 static 메서드에 대해
- 인터페이스의 다향성 원리와 구현 방법
3주차는 개념 정리부터 빡세구나...😭
Java 에서는 객체라는 말은 정말, 자주, 항상 튀어나온다
튜터님도 전에 한 번 설명해주실 때 얘기하신 건데
모든 것을 객체로 다 만들 수 있다고 생각해야 한다
라고, 이걸 머릿속에 항상 넣어두라고 하셨다
처음에는 그 이유가 Java 가 세상과 닮은 언어이기 때문이라고 단순히 생각했지만
객체에 대한 개념을 알게 되니 더 깊게 이해할 수 있었다
객체! 넌 누구냐
라고 물으신다면 대답해 드리는 게 인지상정!
이 세계의 파ㄱ... 가 아니라
세상에 존재하는 물체를 뜻하며 식별이 가능한 모든 것을 의미
이렇게 설명하면 그게 뭔데 라는 생각이 들 수 있다
물론 나도 처음엔 그래서 그게 뭔데 라고 생각했었다 ㅎㅎ..
예를 들면 훨씬 이해하기 쉽다
물리적으로 존재하는 자동차, 나, 계산기, 물통 등등 이런 것도 객체고
개념적으로 존재하는 강의, 배달 주문, 운동 같은 것 또한 식별이 가능하기 때문에 객체라고 불 수 있다고 한다
이전에 강의에서 객체는 특징과 행동이라고 비유하며 설명한 적이 있다
이제 이것을 속성와 행위로 구성된다고 할 수 있고,
Java 에서는 필드(속성), 메서드(행위)로 정의하여 구현할 수 있다
객체를 설명할 때 아주 좋은 예시는 자동차라고 한다
자동차의 회사, 모델, 색상, 가격, 속도 등을 속성이라고 하고,
자동차의 가속, 브레이크, 기어변속, 조명, 경적 등을 행위라고 할 수 있다
그래도 잘 이해가 안된다, 헷갈린다면
머릿속에 개념이 자리 잡고 돗자리 피고 집까지 만들어서 박힐 때까지 계속 듣고 읽어보는 걸 추천한다
- 객체 간의 협력
- 각 독립적인 객체(사람과 자동차)는 서로 행위를 통해 상호작용 하며 협력 가능
- 객체 간의 관계
- 사람과 자동차는 사용 관계
- 타이어, 차문, 핸들은 자동차의 포함 관계
- 자동차를 생산하는 공장과 그 공장에서 출고된 자동차들은 상속 관계
객체지향 프로그래밍의 특징 4가지
- 캡슐화
- 속성(필드)와 행위(메서드)를 하나로 묶어서 객체로 만드는 것
- 실제 내부 구현 내용은 외부에서 알 수 없게 감추는 것 ex) 캡슐알약
- 필요없는 내용을 외부에 노출시키지 않고 숨기기 때문에 보안성이 좋고 객체가 변하지 않는다
- 캡슐화된 객체의 필드와 메서드의 노출을 결정하기 위해 접근 제어자를 사용
- 상속
- 부모 객체와 자식 객체
- 부모 객체가 가지고 있는 필드와 메서드를 자식 객체에게 물려줄 수 있지만 그 선택은 자식 객체 쪽
- 객체 간의 구조 파악이 쉬워지고 부모 객체를 수정하면 그 아래에 있는 자식 객체도 모두 수정되기 때문에 일관성 유지하기 좋다
- 코드의 중복이 줄어들고 재사용성이 좋다
- 다향성
- 객체가 연산을 수행할 때 하나의 행위에 대해 각 객체가 가지고 있는 고유한 특성에 따라 여러 가지 형태로 재구성 되는 것
- Car 라는 객체(설계도)를 통해서 CarA, CarB 를 만들었지만 그 안에 있는 경적 소리, 조명 등 메서드(행위)의 구현을 다르게 재정의하여 사용할 수 있는 것
- 추상화
- 객체의 공통적이고 중요한 것들을 모아 객체를 새롭게 정의하는 것
- 예를 들어, 자동차와 오토바이, 자전거의 공통점은 이동 수단이고 모두 전진과 후진이 가능하다는 점, 이 공통적인 기능(전진, 후진, 브레이크)들을 상위 클래스로 추출해서 자동차, 오토바이, 자전거라는 하위 클래스들에게 넣어줄 수 있다
클래스를 토대로 생성된 객체를 인스턴스 라고 부르고
인스턴스를 통해서 각 객체들을 뽑아내는게 인스턴스화 라고 한다
클래스 설계
클래스는 객체를 생성하기 위한 설계도
클래스의 구성은 필드, 생성자, 메서드
⭐ 클래스는 실체가 아니다 설계도이다 ⭐
중요하니까 두 번 말한다
- 클래스를 만들기 위한 4가지 SETP
- 만들려고 하는 설계도의 선언 (클래스 선언)
- 객체가 가지고 있어야 할 속성 (필드) 정의
- 객체를 생성하는 방식을 정의 (생성자)
- 객체가 가지고 있어야 할 행위 (메서드) 정의
- 클래스 선언
// 클래스 선언
public class Car { }
- 속성(필드) 정의
// 속성(필드) 정의
String company; // 자동차회사
String model; // 모델
String color; // 색
double price; // 가격
double speed; // 속도 Km/h
char gear; // 기어 (P, R, N, D)
boolean lights; // 조명 상태
- 생성자 (객체를 생성하는 방식) 정의
// 생성자 (기본적으로 class 의 이름과 동일)
// 처음 객체가 생성될 때(instance 화) 어떤 로직을 수행해야 하며,
// 어떤 값이 필수로 들어와야 하는지 정의
public Car () {
// logic
// 기본생성자 (아무것도 없는 logic) : 생략 가능
}
- 메서드 정의
// 메서드
// gasPedal
// input : kmh // output : speed
double gasPedal(double kmh) {
speed = kmh;
return speed;
}
// brakePedal
// input : x // output : speed
double brakePedal() {
speed = 0;
return speed;
}
// changeGear
// input : gear (char type) // output : gear
char changeGear(char type) {
gear = type;
return gear;
}
// onOffLight
// input : x // output : lights (boolean)
boolean onOffLight() {
lights = !lights;
return lights;
}
// horn
// input : x // output : x
void horn() {
System.out.println("빵빵");
}
페달을 밟고, 브레이크를 밟고, 기어를 바꾸고, 라이터를 켰다끄고, 경적을 울리는 행위에 대한 정의
위에 정의한 속성(필드)를 이용해 input, output 을 연결시켜 주면 된다
객체 생성과 참조형 변수
어지럽다 어지러워
Car car1 = new Car();
Car car2 = new Car();
System.out.println(car1); // week03.Car@4eec7777 => car1 이 가지고 있는 저장공간의 주소
객체 생성 연산자인 new 를 사용하면 클래스로부터 객체를 생성할 수 있고
new 연산자를 통해 객체가 생성되면 해당 인스턴스의 주소가 반환된다 ( 참조형 변수로 사용 )
Car[] carArray = new Car[2];
Car car3 = new Car();
car3.changeGear('P');
carArray[0] = car3;
Car car4 = new Car();
car4.changeGear('N');
carArray[1] = car4;
for (Car car : carArray) {
System.out.println(car.gear); // P, N
}
객체는 참조형 변수와 동일하게 취급되기 때문에 배열 또는 컬렉션도 이용 가능하다
객체의 속성 : 필드
필드
객체의 데이터를 저장하는 역할
객체의 필드에는 고유 데이터, 상태 데이터, 객체 데이터로 분류할 수 있다
고유 데이터는 변하지 않는 데이터,
상태 데이터는 변할 수 있는 데이터,
객체 데이터는 독립적인 존재여서 다른 곳에서도 하위 객체로써 이용가능, 객체화된 데이터
// 속성(필드) 정의
// 고유 데이터 영역
String company; // 자동차회사
String model; // 모델
String color; // 색
double price; // 가격
현재의 필드는 선언만 되어있고 할당(초기화)는 하지 않은 상태이며
각 데이터타입마다 기본값이 존재한다
데이터 타입 | 기본값 |
byte | 0 |
char | \u0000 (공백) |
short | 0 |
int | 0 |
long | 0L |
float | 0.0F |
double | 0.0 |
boolean | false |
배열 | null |
클래스 | null |
인터페이스 | null |
필드를 사용한다라는 의미는 필드의 값을 변경하거나 읽는 것을 의미
필드를 정의하여 선언했다고 해서 바로 사용할 수 있는 것은 아니다
=> 인스턴스화를 해야 사용 가능
객체를 가지고 필드에 접근하는 방법은 외부 접근, 내부 접근 두 가지
Car car = new Car();
car3.changeGear('P');
외부 접근은 객체를 생성했다면 참조변수 car을 이용해 외부에서 객체 내부의 필드에 접근해서 사용가능
이때 객체 내부 필드에 접근하는 방법은 도트(.) 연산자라고 한다
char changeGear(char type) {
gear = type;
return gear;
}
changeGear('D')
내부 접근은 클래스(설계도) 안에 존재하는 변수(필드)에 대해 접근할 때
메서드를 호출하면 필드를 바로 호출해서 사용할 수 있다
객체의 행위 : 메서드
메서드
객체의 행위를 뜻하며 객체 간의 협력을 위해 사용
정의하는 방법 : { } 내부에 실행할 행위 정의
리턴타입 메서드명(매개변수) { 실행할코드; };
리턴 타입은 메서드가 실행된 후 호출을 한 곳으로 값을 반환할 때 해당 값의 타입을 의미
리턴 타입이 void 가 아닐 경우, 반드시 return 이 존재해야 한다
반환할 값이 없을 때는 리턴 타입에 void를 작성하지만
void 에 return 이 존재한다면 원하는 지점에서 메서드를 종료시킬 때 사용한다
매개변수는 메서드를 호출할 때 메서드로 전달하려는 값을 받기 위해 사용되는 변수
double gasPedal(double kmh, char type) {
changeGear(type); // 가속도 페달을 밟으면 자동으로 기어가 변한다
speed = kmh;
return speed;
}
위의 gasPedal 메서드는 double 타입 kmh 변수와 char 타입 type 변수를 받아야 실행이 된다
값을 전달하기 위해서는 순서와 타입을 모두 맞춰서 값을 넣어햐 정확하게 실행되며
이 내용은 호출할 때 또한 마찬가지로 주의해야 할 점이다
가변길이의 매개변수도 선언이 가능하다
void carSpeeds(double ... speeds) {
for (double v : speeds) {
System.out.println("v = " + v);
}
}
위의 내용처럼 ( 타입 ... 변수명 ) 을 사용하면 매개값을 콤마(,)로 구분해서 개수 상관없이 전달이 가능하다
가변길이로 매개값을 받는다면 그 길이는 어떻게 변하게 될지 모르기 때문에
로직 또한 그에 맞춰서 처리할 수 있도록 맞춰줘야 한다 ( 반복문 )
오버로딩
오버로딩
함수가 하나의 기능만 구현하는 것이 아니라
하나의 메서드 이름으로 여러 기능을 구현하도록 하는 Java의 기능
처음에 이게 무슨 소린가 싶었다
근데 나는 사실 이론만 모를 뿐 어떻게 생긴 건지는 이미 알고 있었던 것이다
오버로딩은 한 클래스 내에 이미 사용하려는 이름과 같은 이름을 가진 메서드가 있어도,
매개변수의 개수 또는 타입, 순서가 다르면 동일한 이름을 사용해도 메서드를 정의할 수 있다
- 조건
- 메서드의 이름만 같고, 매개변수의 개수, 타입, 순서가 달라야 한다 ( 다 달라야 하는 거 아니다 )
- 응답 값만 다른 것은 오버로딩을 할 수 없다
- 접근 제어만 다른 것도 오버로딩 할 수 없다
- 오버로딩은 매개변수의 차이로만 구현할 수 있다
- 장점
- 메서드 이름 하나로 상황에 따른 동작을 개별로 정의할 수 있다
- 메서드의 이름을 절약할 수 있다
- 이미 우리는 안다, 잘 쓰고있다 오버로딩 된 메서드를 println( )
println() 의 매개변수로 int, double, String, boolean 등 다양하게 넣을 수 있게 되어 있다
만약 오버로딩이 안된다면 println() 의 이름은 printlnInt(), pinrtlnStr() 같이 낭비가 되게 된다
기본형 & 참조형 매개변수
기본형 매개변수
: 메서드를 호출할 때 전달할 매개값으로 지정한 값을 메서드의 매개변수에 복사해서 전달
매개변수의 타입이 기본형일 때는
⭐값 자체가 복사되어 넘어가기 때문에 매개값으로 지정된 변수의 원본 값이 변경되지 않는다
참조형 매개변수
: 메서드를 호출할 때 전달할 매개값으로 지정한 값의 주소를 매개변수에 복사해서 전달
매개변수를 참조형으로 선언하면
⭐ 값이 저장된 곳의 원본 주소를 알 수 있기 때문에 값을 읽어 오는 것, 값을 변경하는 것도 가능하다
메서드의 매개변수 뿐만 아니라 반환타입도 참조형이 될 수 있다 ( 반환하는 값의 타입이 실제값의 주소 )
쉽게 말해서
기본형 매개변수는 읽는 것만 가능하고
참조형 매개변수는 읽고 변경하는 것까지 가능하다는 말이다
Car car = new Car(); // 객체 생성
// 기본형 매개변수
char type = 'D';
car.brakePedal(type);
// 메서드 실행 완료 후 전달할 매개값으로 지정된 type 값 확인
System.out.println("type = " + type); // 기존에 선언한 값 'D' 출력, 원본 값 변경되지 않음
// 메서드 실행 완료 후 반환된 car 인스턴스의 gear 타입 확인
System.out.println("gear = " + car.gear); // 객체 내부에서 type을 변경하여 수정했기 때문에 'P' 출력
System.out.println();
// 참조형 매개변수
Tire tire = new Tire();
tire.company = "금호"; // 금호 타이어 객체 생성
// 차 객체의 타이어를 등록하는 메서드 호출한 후 반환값으로 차 객체의 타이어 객체 반환
Tire carInstanceTire = car.setTire(tire);
// 메서드 실행 완료 후 전달할 매개값으로 지정된 참조형 변수 tire의 company 값 확인
System.out.println("tire.company = " + tire.company); // "KIA" 출력
// 전달할 매개값으로 지정된 tire 인스턴스의 주소값이 전달되었기 때문에 호출된 메서드에 의해 값이 변경됨.
// 메서드 실행 완료 후 반환된 car 인스턴스의 tire 객체 값이 반환되어 저장된 참조형 변수 carInstanceTire의 company 값 확인
System.out.println("carInstanceTire.company = " + carInstanceTire.company); // "KIA" 출력
이건 나중에 이미지화 해서 넣어보도록 하겠다
오늘 분명 열심히 공부한 것 같은데
어제보다 강의를 덜 들었다
이상하다.. 강의가 혼자서 증식할 일은 없는데
개념 정리한다고 생각보다 시간을 많이 쓴 모양이다..
3주차...엄청난 강적이다 ‼️
'개발 일지 > TIL' 카테고리의 다른 글
[ #10 ] TIL (0) | 2024.04.27 |
---|---|
[ #9 ] TIL (3) | 2024.04.25 |
[ #7 ] TIL (2) | 2024.04.23 |
[ #6 ] TIL (0) | 2024.04.22 |
[ #5 ] TIL (0) | 2024.04.20 |