KH

[JAVA] 2023년 2월 14일 火 (객체)

十月 2023. 2. 14. 16:08

· 변수, 연산자, 제어문, 배열 → 프로그래밍 기초

· 객체 상속 다형성 → 개념적인 부분 (설계적인 부분)

 (객체배열)

· API Exception IO Collection


『객체』

 


 

✓ Chap01. 객체지향언어

객체 간의 상호작용으로 발생한 모든 사건들의 개념을 컴퓨터로 옮겨 만든 것이 객체지향 언어

(ex. 사람이 말을 하는 것, 사물, 언어, 등등)


[자바에서의 객체(Object)]

클래스에 정의된 내용대로 new 연산자 Heap 메모리 영역에 올라간 것(공간이 생성된 것)주소 값 반환

(ex : A_if ai = new A_if; → 객체를 만드는 것 / A_if 는 클래스, ai 는 참조 변수)

≫ 클래스를 가지고 객체를 만듦

 


 

[객체지향언어 - 클래스 : 클래스의 등장 배경]

:: 객체의 특성에 대한 정의를 한 것으로 캡슐화를 통해 기능을 포함한 개념,
사물이나 개념의 공통 요소를 추상화(abstraction)하여 정의
ex) 제품의 설계도, 빵 틀

외부에서 데이터에 접근하지 못하도록 캡슐화 시킴

1. 구조체는 어디서든 접근이 가능해 수정, 유출의 위험이 있다.

2. 따라서 데이터가 유출되지 않도록 접근을 제한(private)한다. (데이터 은닉화 = 감싸기만 한 것)

하지만 이건 데이터를 저장만 하는 것이기 때문에 쓸 수 없고 크게 의미가 없다.

3. ∴ 데이터 은닉화 상태에 외부에서도 응용할 수 있는 기능을 넣어두는 것"캡슐화"

4. 그리고 캡슐화까지 적용되어있는 상태를 "클래스" 라고 일컫음.

 

 

ex) 클래스(제품 설계도)와 객체(제품)

붕어빵 틀과 붕어빵

틀(클래스)은 하나지만 속에 뭐가 들었냐에 따라 붕어빵(객체)이 달라짐

 

[추상화 (abstraction)]

추상화 작업을 통해 공통적인 것만 추출하고 클래스를 만드는 것.

유연성을 확보하기 위해 구체적인 것은 제거한다는 의미

(프로그램에서 필요한 공통점을 추출하고, 불필요한 공통점을 제거하는 과정)

 

 


[객체]

:: 객체 지향 언어에서 객체의 개념은 클래스에 정의된 내용대로 

 메모리에 할당된 결과물(Object)


[객체(Instance)의 할당]

예) Student s = new Student()

Student s → Stack에 Student 클래스의 참조 변수 s 선언

new Student() → new 연산자 + 생성자로 Heap 메모리에 공간 생성 (주소값 반환)

참조변수  s는 생성된 객체의 주소를 참조한다.


[객체 지향 3대 특징]

1. 캡슐화 (Encapsulation)

2. 상속 (Inheritance)

3. 다형성 (Polymorbhism)

4. 추상화 (abstraction)


[캡슐화 원칙]

· 멤버 변수 = 전역 변수 = 필드 = 멤버필드

· 캡슐로 감싸는 것을 private 이라고 한다.

일부러 설계 목적을 세우지 않는 한 무조건 private을 붙여야 한다.

≫ 그것이 바로 캡슐화의 원칙

+) 멤버 함수 = 메소드 = 클래스 안에 있는 것

 


직접 해 보기 ▼

1)

◆ 예시 : 입출금 통장

name, phone, pwd, bankcode, balance가 전역 변수에 해당

메소드 안에 넣는 변수는 지역 변수지만, 클래스 안에 바로 변수를 넣을 수 있다.

전체 영역에 다 영향을 끼칠 수 있음 (모든 메서드) → 전역 변수

 

Account 클래스 구조

Run 클래스는 Account와 같은 패키지 안에 만들어줬다.

≫ 캡슐화 원칙에 따라 클래스에 private를 붙였다.


 


 

✓ Chap02. 클래스 (Class)


[클래스 선언]

[접근제한자] [예약어] class 클래스명 {

≫ 대괄호 속 접근제한자와 예약어는 생략 가능

 

[클래스 접근제한자]

접근제한자는 총 4가지, 그 중 2가지만 클래스에 사용 가능

public : 모든 패키지에서 접근이 가능하다.

(default) : 다른(외부) 패키지에서는 접근이 불가능하다. (안 쓰면 디폴트)

 

+) 추가

Project Explorer를 계층 형식으로 바꿔주었다.

DefaultTest 클래스 import 하려 했는데, 에러!남~

(default) : 다른(외부) 패키지에서는 접근이 불가능한 조건으로

같은 패키지 안에 Run 클래스를 생성해주어야 한다.


직접 해 보기 ▼

1) 클래스 실습

- private / + public

▽ 다이어그램대로 작성하기

전역변수에 지역 변수를 넣음.



 

✓ Chap03. package와 import



[package]


[import]

- import문은 패키지문과 클래스 선언의 사이에 선언

 컴파일 시에 처리되므로 프로그램 성능에 영향을 주지 않음
- 지정된 패키지에 포함된 클래스는 import 가능하지만

 서브 패키지에 속한 모든 클래스까지는 불가능

 

<import를 하지 않아도 되는 경우>

1. 같은 패키지에 있을 때 (원래 안 해야 맞는 것)

2. java.lang 패키지 내의 클래스 → String, Object, System... 등 (자주 쓰는 것들)

 (Math.random의 Math도 import한 적 없다. 클래스라서)

 

 


✓ Chap04. 필드 (Field)

:: 멤버 변수 = 전역 변수 = 필드 = 멤버필드


[필드 표현식]

[접근제한자] [예약어] 자료형 변수명 [= 초기값];

[접근제한자] / [예약어] 생략 가능

☆ 외우기



[필드 접근제한자]

// 클래스 접근제한자 : + public / ~ default

private을 넣어야 캡슐화가 됨 (밖에서 안 보이니까)

*protected는 상속을 안하면 default랑 똑같음 (같은 패키지 안에서만 볼 수 있기 때문에)

 만약 상속이 된 경우는 다른 패키지에서도 볼 수 있다.

*private을 넣어야 캡슐화가 됨 (밖에서 안 보이니까)


[필드 예약어 - static]

:: static / 공유

// 접근 제한자 뒤에 붙으면 됨.

(static은 프로그램 시작하자마자 static 메모리 영역에 올라감. → 프로그램 끌 때 같이 내려감.)

프로그램 시작하면서 끝날 때까지 사용할 변수가 필요한데 모든 객체에 공동으로 사용할 것이 필요하다면 static 사용

클래스 변수 (클래스명.변수명)

 

[필드 예약어 - final]

:: 한 번만 저장하겠다 (상수)

// 접근 제한자 뒤에 붙으면 됨.

 

static과 final은 같이 자주 쓰인다.

왜냐면 고정이 되어있는 상태를 공유하는 경우가 많기 때문에.

ex) public static final double PI = 3.14;

 

확인 해 보기 ▼

1)

2) static 변수 (= 클래스 변수) 만들기

// static 변수는 프로그램이 시작할 때 바로 메모리 올라가고 끝날 때 없어진다 : 객체 만들 필요 없음.

public static int staticNum; 에서

= 값 이 없으면 필드를 초기화한 것이 아님.

 

인스턴스 변수는 클래스 변수의 반댓말 (객체를 만들어야 메모리에 올라감)

 

3) 필드 실습1

▽ 다이어그램 대로 작성하기

 

4) 필드 실습2

밑줄static을 나타내는 것.

PI는 이름이 대문자라 final이라는 예약어가 필요.

≫ final과 static은 자주 같이 쓴다.

 

★ 변수 이름은 의미 있게 지어야 눈에 잘 들어옴.

PI는 static 변수 (클래스 변수)

radius는 인스턴스 변수

 

public static final double PI = 3.14; ≫ [접근제한자] static [예약어] 자료형 변수명;

= 값 이 없으면 필드를 초기화한 것이 아님.

 


 


 

✓ Chap05. 생성자

:: 객체가 new연산자를 통해 Heap 메모리 영역에 할당될 때
객체 안에서 만들어지는 필드(전역 변수) 초기화하는 역할

(Heap 메모리에 올라가고 나면 해당 기본 값으로 초기화되는데,

전달 받은 초기 값을 필드에 초기화해주는 역할 / 일종의 메소드)

 

// 규칙 : 생성자 명은 클래스 명과 똑같이! 지정해주어야 한다. 

 메소드 선언과 유사하지만 반환 값 없음 (반환 타입 적지 말자)

생성자를 만드는데 void로 메소드를 만들면 안 됨 (생성자가 아니게 됨)

 

void = 반환 값 없음

length() = 반환 값 있음(int)

charAt() = 반환 값 있음(char)

···

 

▼ ex.

객체를 만들 때,

Account a = new Account();

// 클래스 참조변수명 = new 연산자 + 생성자();

Account() 는 생성자 ≫ new 뒤에 붙었던 모든 소괄호가 생성자


[생성자 표현식]


[기본 생성자]

// 필드 - 생성자 - 메소드 순으로 많이 작성함

// 접근 제한자 대부분 public 씀 (설계 목적 있는 거 아니면)

 

▼ 중요한 의문

[매개변수 생성자]

객체 생성시 매개변수로 전달받은 값으로 필드를 초기화하기 위해 사용

생성자가 아무것도 없으면 jvm이 기본 생성자를 알아서 만들어 준다.

그러면 매개변수는 만들어준다는 얘기가 없으니 매개변수 생성자만 만들면 되나?

≫ 아니다, 매개변수 생성자를 만들면 기본 생성자를 만들 필요가 없다고(생성자가 있다고)

 생각하기 때문에 JVM이 알아서 기본 생성자를 만들어주지 않는다.

 

직접 작성해 보기 ▼

 

≫ 기본 생성자 입력하지 않고 중간에 매개 변수 생성자 넣음

 

≫ 실행 클래스 7번째 줄에 빨간 줄이 뜸

 

≫ 이유 : 기본 생성자 정의가 되어있지 않아서!

 

 

≫ User 매개 변수 생성자는 지금 String 타입을 두 개 받도록 정의해 두었다.

따라서 매개 변수를 입력할 때도 타입(자료형), 개수만 정의된 대로 써야 한다.

(타입만 체크하기 때문에, 데이터 내용을 순서에 맞게 넣었는지도 체크하자.)

 

≫ User라는 객체를 만들 때부터 초기화하고자 함

 

 

▽ 추가로 매개 변수 생성자 더 만들어 봄


 

[오버로딩]

:: 한 클래스 안에 같은 이름의 메소드를 여러 개 작성하도록 하는 기법

+)) 매개 변수의 개수 or 타입 or "순서"가 달라도 괜찮다.

≫ 매개변수의 개수, 타입, 순서 중 하나만 달라도 오버로딩이 적용된다.

≫ 생성자도 메소드의 일종이라 오버로딩이 해당 됨

 

▼ 아래 예시처럼

오버로딩 적용된 것

 

▼ 이건 언뜻 보면 변수명이 달라 오버로딩이 될 것 같지만

 뜯어보면 타입이 String으로 같기에 적용이 되지 않는다.

개수, 타입, 순서 중 하나라도 달라야 함.


+) 그런데, 필드와 지역 변수 이름이 같은 경우에는 어떻게 될까?

int age, double point 를 int a, double p로 이름 붙인 이유.

매개 변수와 가까운 해당 메소드 안에만 영향이 있는 셈.

▼ 해결 방법은 this


[ this ] // 참조 변수

:: 모든 인스턴스 메소드에 숨겨진 채 존재하는 레퍼런스(참조 변수)로 할당된 객체를 가리킴
 함수 실행 시 전달되는 할당된 객체의 주소를 자동으로 받는다.

≫ this에는 는 현재 내가 만든 객체의 내 주소 값이 담겨 있다.

// 알아서 숨겨있기 때문에 정의하지 않고 갖다 쓰면 된다. (꽤 자주 씀)

 

this.age는 this(내 주소 값) 안에 있는 필드 age를 가리킨다.

결론적으로 매개 변수로 받아온 age는 this.age를 통해 내 필드의 age로 받을 수 있다.


[ this() ] // 생성자

:: 같은 클래스 내 다른 생성자를 불러오는 것.

// 레퍼런스 변수 this에 비하면 많이 쓰지는 않는다.

 

▼ 예시

(개발자는 코드 반복을 싫어함)

≫ 위에 동일한 코드를 this()로 작성해줄 수 있다.

≫ this(userId, userName); 이 필드를 향하는지 궁금하다면

 ctrl 을 누른 채 해당 this를 클릭하면 필드 this를 가리킨다.

 

 

▼ 생성자 실습

 



✓ Chap06. 메소드

[메소드 (Method)]

:: 수학 함수랑 비슷 / 정의해놓은 메소드를 호출해 사용.

메소드 : 전달 값이 없는 상태로 호출하거나 어떤 값을 전달하여 호출,

 반환 값/결과 값은 있거나 없을 수 있음 (총 네 가지)


[메소드 표현식]

public void information() {
System.out.println(studentNo);
}


[메소드 접근제한자]

필드 접근제한자랑 같음


[메소드 예약어]

static 은 class.


[메소드 반환형]

:: 반환 값이 있을 수도 있고 없을 수도 있다.

- void 는 없는 것이라 어떤 공간에도 담을 수가 없다.

호출해도 반환하는 결과 값이 없어서 변수에 담을 수 없음.

- 기본 자료형 : 그 타입의 값 자체 (int 은 length() / char는 charAt() / double 은 Math.random... 등)

- 배열 : 안에 담긴 주소 값이 넘어가(반환) 변수에 담음 - 얕은 복사가 이루어짐

- 클래스 : 안에 담긴 주소 값이 넘어간다. - 얕은 복사가 이루어짐


[메소드 매개변수]

- 가변인자 : prinf()에서 써봄 // 가변은 변할 수 있다는 뜻 (몇 개의 인자가 들어올 지 모르니까)

메소드 호출해 메소드에 보낼 값은 인자, 이미 정의된 메소드로 데이터를 전달 받을 변수는 매개 변수


[매개변수가 없고 리턴 값이 있을 때]

반환 타입이라 return이 들어가야 함.

그 타입에 맞는 값을 반환시켜야 한다.

· return의 두 가지 결과 도출 :  반환 값이 있을 때와 없을 때.

 

[매개변수가 없고 리턴 값이 없을 때]

void가 들어가야 함.

return이 있어도 되고 없어도 됨

 

[매개변수가 있고 리턴 값이 있을 때]

반환 타입이라 return이 들어가야 함.

 

[매개변수가 있고 리턴 값이 없을 때]

void가 들어가야 함.

 

 

▼ 생성자 실습

 

1)

 

2) 

// static 변수는 클래스 변수 ≫ 클래스 이름 . 변수명 으로 작성해야 함.

 (다른 인스턴스 변수들은 this.이름 이지만 static 변수는 Trainee.score 으로 작성)

 

 


[setter 메소드] ★ 약속

:: 어떤 값을 받아 변경하려면 set필드명으로 만들어서 사용할 것. (ex.setName)

 

[getter 메소드]

:: 어떤 값을 반환하려면 get필드명으로 만들어서 사용할 것. (ex.getName)

반환형 : 반환할 자료형 타입


 

클래스 다이어그램 구성 보고 틀 잡고 설명에 따르기