객체지향 프로그래밍1
1. 객체 지향 프로그래밍과 클래스
1)객체(Object)
- 속성 : 정의, 상태 -> 변수
- 행위 : -> 함수
- 객체는 클래스의 인스턴스(Instance)
- 클래스를 기반으로 실제 메모리에 할당되어 사용되는 것이 객체
2. 클래스(Class)
- 객체를 만들기 위한 설계도
ㄴ 변수가 어떻게 될것이고 함수가 어떻게 될것이고...
ㄴ 실제 존재하는것은 아님
- 객체에 필요한 변수와 함수를 정의
-> 클래스에는 변수와 함수가 있는게 아니다!!
-> 정의가 있는 것이다!!
1) 클래스를 정의하는 문법
class 클래스명 {
변수 정의
함수 정의
}
객체가 되면 이러이러한게(변수 정의, 함수 정의) 있을것이다(설계 명세서)
2) 클래스 이름을 짓는 규칙(관례)
OrderInfo -> Order + Info
- 클래스명 맨 앞자는 대문자
- 각각의 단어 앞문자도 대문자
참고)
↔ 변수: 첫단어 제외하고 뒤에부터 대문자
ex) noOfStudent
3) 클래스의 속성을 구현하는 멤버변수
- 클래스에 정의된 변수 정의 -> 멤버 변수(정의)
- 클래스에 정의된 함수 -> 메서드
변수.속성명 == 참조변수.멤버변수
변수.함수명(....); == 참조변수.메서드
3. 클래스와 인스턴스
인스턴스(instance)
- 실체 : 실제로 존재한다.
- 인스턴스 == 생성된 객체
- class라는 설계를 통해서 메모리에 존재(실제로 존재)
- 정의에 불과한 클래스 설계도 -> 메모리에 생성된 객체(실체)
- 예시) 클래스 명세 / 인스턴스
- 클래스 명세

ㄴ 변수가 아니다!! 객체를 만들기 위한 설계도
ㄴ 음..4바이트라는 공간을 생성해야겠군
- 인스턴스

ㄴ Student s1 = new Student();
ㄴ new연산자를 통해 메모리(공간)이 생성됨
ㄴ 객체가 되었다.
ㄴ 정의했던것을 변수로 사용 할 수 있다.
ㄴ 변수에 값을 담을 수 있다.
ㄴ 객체가 되지 않았다면 값이 담기지도 않음 근데 값이 담겼으니 객체이다ㅏㅏ
메서드
1. 함수란?
2. 함수 정의하기
접근제어자 리턴타입 함수명 (매개변수 .... ) {
// 실행될 코드 정의
return 반환값;
}

1) 함수이름
2) 매개변수
3) return 예약어와 반환형
3. 함수 호출하고 값 반환하기
함수명(값, ...); : 함수 호출

4. 스택 메모리와 함수 호출
- 스택 메모리 : 임시메모리
-> 함수가 연산을 수행할때만 공간을 할당
-> 작업 완료(return)되면 -> 제거
참고) 함수가 스택영역인 이유
함수 = 레시피
재료는 언제 필요? 실제 요리(수행) 할 때
함수(레시피) 는 연산하기 위해 존재
연산하기위해선 변수(함수의 재료) 가 필요

ㄴ n1, n2는 수행되기 전 아직 변수가 아니다
ㄴ 즉 아직 공간이 없다

ㄴ 함수가 호출되고 실행될 때 변수가 되는 것
ㄴ 드디어 공간이 생겼다!
ㄴ 변수 = 공간 + 이름
ㄴ 함수는 메모리가 필요하지만 수행(요리)할때만 필요
-> 임시메모리(스택) 필요
-> 필요할 때만 할당받고
-> return 즉 필요없어지면 할당받은 메모리 삭제
1) 스택(stack) 구조
- 쌓이는 구조
- 가장 마지막에 투입된 자료 : 가장 먼저 나오고
- 가장 처음에 투입된 자료 : 가장 나중에 나온다.

① 함수가 스택구조로 되어 있어야 하는 이유

함수가 2개가 호출됨
add함수 = main함수의 지역변수??
main함수가 실행되어야 애플리케이션이 실행됨
main이 마지막까지 남아 있어야 모든 코드가 실행된다
그래서 함수는 스택구조 일 수 밖에 없다

2) 큐(queue) 구조
- 가장 마지막에 투입된 자료 : 가장 마지막 나오고
- 가장 처음에 투입된 자료 : 가장 먼저 나온다.

3) 지역변수

ㄴ 아직 함수의 변수가 아니다
ㄴ 코드에 불과한 함수 정의이다
실제로 연산을 할 때(호출될때) 쓰여야 변수(공간을 할당받음)이다

return 하게 되면 연산이 종료되므로 할당되었던 공간도 없어진다

정리

함수에 정의된 변수(지역변수) -> 스택에서 활성화, 스택에서 제거
① 서로 다른 지역변수

1번 함수에 있는 변수(num1, num2, result)와
2번 함수에 있는 변수(num1, num2, result)는 다른 변수이다
-> 왜?
서로 다른 지역이니까
main이라는 함수의 지역의 변수
add라는 함수의 지역의 변수

7. void
- 반환값 없음을 의미한다
- 반환값을 따로 정의하지 않을 때 사용

8. 클래스 기능을 구현하는 메서드
1) 힙 영역 메모리 : 객체 전용 메모리
- 객체는 임시메모리가 아니라 계속 유지되어야 함
- 그래서 힙 영역에 있다
2) 참조 자료형
예시)


s1: main함수의 지역변수(스택영역)
id, name, subject : 객체 (힙영역)
음...둘이 영역(스택/힙)이 다른데 어떻게 접근하지?
s1(스택): 주소를 알아! 주소 참조해서 찾아갈게
어떻게 알아?
s1(스택): new Student의 반환값(주소값)을 받아왔기때문에 주소값을 알고 있음ㅇㅇ
-> s1 : 참조변수 이자 main함수의 지역변수
-> Student(클래스 형태의 자료형) : 참조 자료형
-> 클래스 형태의 자료형은 모두 참조자료형

① 참조자료형은 모두 동일한 크기의 자료형이다
왜?
객체의 주소값만 담으면 되니까 주소값을 담을 공간만 필요

ㄴ 객체의 주소값 구하는 식

ㄴ 출력된값: 객체의 주소값
ㄴ 요 값을 담을 수 있는 정도의 크기만 필요
② 같은 클래스로 함수를 호출해도 참조자료형이 다른경우


ㄴ 주소값이 다르다 -> 독립적인 객체이다

ㄴ 같은 공장에서 자동차를 찍어냈어도 서로 다른 자동차인거랑 같은 개념
ㄴ 같은 클래스로 함수를 호출해도 서로 다른 주소값을 참조한다
③ 참조자료형이 같은경우


ㄴ 같은 참조자료형이라 s2의 값이 바뀜

ㄴ s2, s3의 주소값이 같다

ㄴ 왜 같을까? s2의 주소값을 s3에 대입했기 때문에 같은 주소이다ㅏㅏ

④ 가비지 콜렉터
- 객체간의 참조가 없으면 청소해 줌
예시) 주소값이 null인 경우
s1 = null;
-> 주소에 대한 참조가 끊김
-> 객체자원 접근이 안됨
↓

9. 메모리
1) 데이터 영역
- 변경되지않은 정적인 것 (한번 설정되면 변경x)
ex) 작성한 코드, 상수, 메서드...
① 클래스로더
- 데이터 영역에 클래스 파일들을 올리는 역할
ㄴ 우리가 만든거 아니고 시스템에서 알아서 만든다
② 클래스클래스
- 클래스의 정보가 담겨있는 객체이다
ㄴ 클래스 정보를 확인하기 위한 목적

2) 스택 영역
- 동적 메모리
- 알아서 제거가 됨
- ex) 호출된 함수, 지역변수, 매개변수..
3) 힙 영역
- 동적 메모리
- 가비지 콜렉터(청소부)-> 객체간의 참조가 없으면 청소해 줌
- ex) 객체..
번외) 자바의 이름짓기 관례
1) 클래스 이름
파스칼케이스 - 단어의 시작 문자는 모두 대문자 예) OrderInfo, OrderItems
2) 메서드 및 멤버변수
카멜케이스 - 첫 단어를 제외 단어의 시작문자는 대문자
예) showStudentInfo
3) 패키지 이름
모두 소문자
4) 상수명
모두 대문자, 단어와 단어 사이는 언더바(_)로 구분
예) NO_OF_STUDENT
생성자
-
객체를 생성해 주는 역할
-
클래스명과 동일한 명칭의 함수
예시)

Student();
: 클래스명과 동일한 명칭의 함수
: 객체를 생성해 주는 역할
: 객체를 만들기 위해선 함수와 변수가 필요한데 그 중 함수 역할을 하고 있다
① 데이터 영역 메모리(코드 & 상수 영역)
- 힙 영역의 객체는 재료
- 데이터 영역의 코드는 설계도
위 두 개를 이용해서 생성

② 생성자 함수의 반환값 == 주소값
- 생성자함수
new Student();가 호출됨으로서
객체가 만들어 지고
반환값으로 주소값이 나온다
-> 생성자 함수는 반환값이 항상 주소값이기 때문에 굳이 반환값을 명시하지않는다
-> 생성자 함수의 반환값을 바꿔서도 안된다!
-> 반환값을 바꾸면 주소값을 모르게 되고 그러면 객체를 이용할 수 없으니까...

1. 기본 생성자(디폴트 생성자) : public 클래스명(){}
- 클래스에 생성자 메서드(함수)가 정의된 것이 없으면 -> 컴파일러가 자동 추가
- 생성자 함수가 없으면 객체를 못 만드니까 안보여도 기본으로 컴파일러가 생성을 한다
public 클래스명() {}
- 예시)

① ✨생성자 함수의 역할 : 객체를 만드는일
- 생성자 함수는 건드리면 안됨,
- 통제하자!
- 건드리지 못하게 내부적으로 처리코드 이미 시행함(안보이는것 뿐임, 안보이게 해야 건드리지 못하니까)
- 객체를 만들었으면 그걸 써야지!
- 주소값이 있어야 쓸 수 있음
- 반환값 = 주소값
- 이것도 안보이는 이유는 건드리지 못하게 할려고 ...안보이지만 내부적으로 있는거다
- 고로 보이는 실행 코드는 이미 객체가 생성된 이후의 실행코드이다


ㄴ public Student(){} 함수가 실행될 때는 id, name, subject는 이미 변수이다
ㄴ 왜? 객체를 만들어 준 이후의 시점이니까
ㄴ 그럼 이제 값을 넣어줘야지ㅣㅣㅣ



ㄴ 함수가 실행되려면 우선 객체가 먼저 생성되어야 한다
ㄴ 객체(재료), 함수(레시피)


ㄴ 기본생성자에 매개변수 설정

ㄴ 매개변수를 통해 초기화


ㄴ 기본생성자랑 같은 함수인데 매개변수 없으니까 오류 뜸
ㄴ 같은 함수로 만들어 주기 위해 값을 넣어야 함

오류해결
② 멤버변수의 초기화
멤버변수 : 클래스에 정의된 변수 정의


③ 같은 클래스지만 주소값(참조자료형)이 다른 함수의 변수값 유연하게 바꾸기

ㄴ 같은 클래스지만 주소값이 다르다

ㄴ 기본생성자 함수에 매개변수 설정

ㄴ 값 대입 하면 다른 주소값이기 때문에 변수값 유연하게 바꿀 수 있음
2. 생성자 만들기
- 생성자는 주로 멤버변수에 대한 값들을 매개변수로 받아서 인스턴스가 새로 생성될 때 멤버 변수 값들을 초기화하는 역할을 합니다.
- 즉, 인스턴스가 생성됨과 동시에 멤버변수의 값을 지정하고 인스턴스를 초기화하기 위해 생성자를 직접 구현하여 사용합니다.
3. 함수의 이름 - 함수의 시그니처
패지명 + 클래스명 + 반환값 타입 + 함수명 + 매개변수 + 예외 전가
- 함수의 시그니처 동일 -> 함수의 중복 정의
- 함수의 시그니처가 다르면 -> 함수명이 같아도 다른 함수를 정의한 것
예시1)

ㄴ 2번 3번은 함수의 시그니처가 모두 동일하기 때문에 같은 함수이며 같은 함수를 중복 정의 하여 오류가 뜬 것
예시2) 변수명 바꿔도 동일하게 취급
-> 자료형이 달라야 한다ㅏㅏ

4. 생성자 오버로드(constructor overload)
- 클래스 내에 여러 개의 생성자를 정의 하는 것
-> 클래스에 생성자를 여러 개 제공하면 이 클래스를 사용하는 코드에서는 원하는 생성자를 선택해 사용할 수 있습니다.
-> 생성자를 오버로딩하면 사용자는 다양한 방법으로 객체를 생성할 수 있습니다.
= 생성자 오버로딩은 코드의 재사용성과 가독성을 높여줍니다.
- 각 생성자는 서로 다른 매개변수를 가지고 있어야 함
- 매개변수의 개수, 자료형, 순서 등(함수의 시그니처)을 다르게 함으로써 여러 개의 생성자를 정의할 수 있슴
- 객체지향 프로그램에서 메서드 이름이 같고 매개변수만 다른 경우를 오버로드라고 한다
① 메서드 오버로드

ㄴ 3개 다 다른 함수이다


번외) 자바문서
https://docs.oracle.com/en/java/javase/17/docs/api/index.html






