ch06. 클래스
06-1. 객체 지향 프로그래밍과 클래스
[객체]
: 자신의 속성을 가지고 있으면서 식별 가능한 것
: 객체는 속성과 동작으로 구성 (속성 = 필드, 동작 = 메소드)
[객체 간의 상호작용]
: 객체는 각각 독립적으로 존재하면서 다른 객체와 상호작용하며 동작함
: 객체 간 상호작용 = 객체 간의 메소드 호출
: 객체 상호작용 수단 = 메소드
: 매개값을 주고 메소드 호출한 뒤 메소드가 반환값을 이용하는 구조
: 즉, 매개값과 리턴값을 통해서 데이터를 주고받으며 상호작용
[객체 간의 관계]
-집합 관계 : 부품 객체가 하나의 완성품 객체에 포함 되는 관계
-사용 관계 : 객체 간 상호작용하는 관계
-상속 관계 : 상위 부모 객체기반, 하위 자식 객체 생성 관계
[객체와 클래스]
: 설계도를 바탕으로 객체 생성 후 사용 가능
: 클래스 = 설계도
: 클래스 : 객체 생성을 위한 필드와 메소드 정의되어 있다.
: 인스턴스 : 해당 클래스로부터 만들어진 객체
: 하나의 클래스에서 여러 인스턴스 생성 가능
[클래스 선언]
public class 클래스 이름 {
}
: (클래스.java) 소스파일 생성 -> 컴파일 -> (클래스.class) 바이트코드파일 생성
: 소스파일 당 여러 클래스 선언 시, 선언한 클래스 개수만큼 (.class)파일 생성됨
: 일반적으로 소스파일 당 하나의 클래스 선언
[객체 생성과 클래스 변수]
클래스 변수 = new 클래스();
: new 연산자 : 클래스로부터 객체를 생성시키는 연산자
: new 연산자는 힙 영역에 객체 생성 시킨 후 객체의 번지를 리턴하고,
이 주소를 참조타입 클래스 변수에 저장하면 -> 비로소 변수를 통해 객체 사용 가능
: new 연산자로 객체 생성 후 리턴된 번지를 변수에 저장하여 객체 참조
: 클래스 하나 당 new연산자 사용한 만큼, 객체가 메모리에 생성됨
: 하나의 클래스로부터 생성되었어도 각자 객체는 고유 데이터 가지며 독립된 다른 객체
<클래스의 용도>
- 라이브러리용 클래스 多 : 다른 클래스에서 이용할 목적으로 설계
- 실행용 클래스 : 프로그램 실행 진입점 main() 메소드 제공 클래스
[클래스 구성 멤버] : 클래스는 객체가 가져야 할 구성멤버를 내부에 정의
- 필드: 객체의 데이터가 저장되는 곳
- 생성자: 객체 생성시 초기화 담당, new연산자로부터 호출되는 곳
- 메소드: 객체의 동작 정의하는 부분
06-2. 필드
[필드]
:객체의 고유 데이터 저장하는 곳
[필드 선언]
: 클래스 { } 내부에 존재 O
: 초깃값 지정되지 않은 필드 = 객체 생성 시 기본 초기값 자동 설정
[필드 사용] : 참조 객체 생성 -> 참조연산자로 필드 사용
: 클래스 외부에서 사용할 경우, 반드시 클래스로부터 객체 성성한 뒤 필드 사용 가능
: 생성자와 모든 메소드에서 사용 가능, (.)참조 연산자로 필드 접근 가능
06-3. 생성자
[생성자]
: new 연산자로 클래스로부터 객체 생성할 때 호출되어 객체 초기화 담당
: 필드 초기화 OR 메소드 호출하여 객체 사용할 준비하는 곳
[기본 생성자]
: 클래스 내부에 생성자 선언 생략 시 컴파일러에 의해 자동 추가되는 생성자
: 따라서 명시적으로 생성자 선언 안해도, new 연산자로 객체 생성 가능한 것
[명시적 생성자]
: 클래스 내부에 명시적으로 생성자 선언
: 객체를 다양한 값으로 초기화하여 생성할 목적
[생성자 선언]
클래스 ( 매개변수 ...) {
}
: 생성자는 클래스 이름과 동일하며, 리턴타입 없다.
: 선언된 생성자를 호출하여 객체 생성하여야 한다.
<필드 초기화 >
: 기본적으로 필드는 객체 생성 시 기본 초기값으로 자동 설정됨
: 특정값 초기화 원할 경우 방법 2가지
(1) 필드 선언 시 초깃값 주기
: 객체 생성 시점에 모든 객체들이 동일한 필드값 가짐
(2) 생성자에서 필드 초기화
: 객체 생성 시점에 외부에서 제공되는 다양한 데이터값으로 필드 초기화
: 생성자의 매개변수 통해 외부값을 필드값으로 받아서 필드로 전달
[생성자 필드 초기화] : this.필드
: 생성자에서 필드를 초기화할 경우,
생성자의 매개변수 이름은 통상적으로 필드와 동일한 이름을 사용
public Korean(String name, String ssn) { //생성자로 초기화할 필드 수 만큼 매개변수 만듬
this.name = name;
//받은 매개값 name은 내가 가지고 있는 ‘name’필드에 저장하겠다,
this.ssn = ssn;
}
[생성자 오버로딩]
: 매개변수를 달리하는 생서아르 여러 개 선언하는 것
**<주의>** 매개변수 타입, 개수, 순서 똑같으면 생성자 오버로딩 아님
[다른 생성자 호출] : this()
: 생성자 오버로딩으로 생기는 중복코드 제거 목적
: 필드 초기화 내용은 한 생성자에게 몰아주고, 나머지 생성자는 this() 통해 초기화 생성자 호출하여 사용
: this() 는 반드시 생성자 첫 줄에서만 허용 O
Car(String model, String color ){
this(model, color, 250);
}
Car(String model, String color, int maxSpeed) {
this.model = model;
this.color = color;
this.maxSpeed = maxSpeed;
06-4. 메소드
[메소드]
: 객체의 동작 코드 작성
리턴타입 메소드이름 ( 매개변수선언) { //선언부
//실행 동작 코드 작성 //실행 블록
}
[메소드 선언]
: 선언부 ( 리턴타입, 메소드이름, 매개면수선언)
<리턴타입>
- 리턴값 없는 메소드 선언
void 함수이름() { ... }
- 리턴값 있는 메소드 선언<매개변수 선언>
리턴타입 함수이름 () { ... }
: 메소드 실행에 필요한 데이터를 외부로부터 받기 위해 사용
: 메소드 호출 시, 매개변수의 타입과 개수 맞게 호출
<매개변수 개수 모를 경우>
→ 매개변수를 배열 타입으로 선언
(1) 배열 타입으로 선언 후, 메소드 호출 전 배열 생성한 뒤 호출 가능
int sum (int[] values) {
int sum = 0;
for(int i = 0; i<values.length ; i++) {
sum += values[i];
}
return sum;
(2) ... 로 선언, 값의 목록만 넘겨주기
: 이 경우, 메소드 호출 시 넘겨받은 값의 수에 따라 자동으로 배열 생성되어 매개값이 됨
: ... 로 선언된 매개변수도 배열타입
int sum2 (int ... values) {
int sum = 0;
for(int i= 0; i< values.length; i++) {
sum += values[i];
}
return sum;
[리턴문]
- 리턴값 있는 메소드 : 반드시 return값 지정
- 리턴값 없는 메소드 : 메소드 강제 종료시 return; 사용
[메소드 호출]
: 클래스 외부에서 호출할 경우,
클래스로부터 객체 생성한 뒤 ,참조변수 이용하여 메소드 호출
[메소드 오버로딩]
: 클래스 내부에 동일한 이름의 메소드 여러 개 선언하는 것
: 매개값을 다양하게 받아서 처리할 목적
**<주의> 매개변수 타입, 개수, 순서 중 하나라도 달라야 한다.**
06-5. 인스턴스 멤버와 정적 멤버
[클래스의 멤버]
- 인스턴스 멤버 : 객체 생성 후 사용O
: 객체 생성시 객체 가지고 있는 멤버
- 정적 멤버 : 객체 생성 없이도 사용O
: 클래스에 위치시켜서, 필요한 객체가 공유하는 멤버
[인스턴스 멤버와 this]
인스턴스 멤버: 객체 생성한 후 사용할 수 있는 필드와 메소드
: 객체에 소속된 멤버이므로, 객체 없이는 사용X
: 인스턴스 필드는 객체마다 따로 존재.
: 인스턴스 메소드는 메소드 영역에 저장되어, 객체가 있어야만 호출O
this : 객체 내부에서 인스턴스 멤버에 접근
: 매개변수와 필드 이름 동일한 경우 인스턴스 멤버인 필드임을 명시할 때 사용
: 매개변수와 필드 이름 다른 경우, 알아서 필드 이름으로 인식
[정적 멤버와 static]
정적 멤버: 클래스에 고정된 멤버. 객체 생성없이도 사용할 수 있는 필드와 메소드
<정적 멤버 선언>
정적 필드 : static 타입 필드 = 초기값;
정적 메소드 : static 리턴타입 메소드 (매개변수선언)
<정적 멤버 사용>
: 클래스가 메모리로 로딩되면 객체사용없이 정적 멤버 바로 사용 O
: 클래스이름으로 접근
- 정적 필드 사용 : 클래스.필드;
- 정적 메소드 사용: 클래스.메소드(매개값) ;
<정적 메소드 선언 시 주의>
: 내부에 인스턴스 멤버 사용 불가
: this 참조 불가
<정적 메소드 내부에서 인스턴스 멤버 사용하고 싶은 경우>
main() 메소드 =정적 메소드
: 객체 생성 후, 참조 변수로 접근
[필드 선언 판단 기준]
인스턴스 필드로 선언 – 객체마다 가지고 있는 데이터. 객체 마다 다른값 갖는 데이터
정적 필드로 선언 – 객체마다 가지고 있을 필요없는 ‘변하지 않는’ 공용데이터
[메소드 선언 판단 기준]
인스턴스 메소드 선언: 내부에 인스턴스 필드 사용하는 메소드
정적 메소드 선언: 인스턴스 필드값이 아닌, 외부의 매개값 만으로 메소드가 실행됨
[싱글톤] : private 접근 제한자
: 전체 프로그램에서 단 하나의 객체만 생성되도록 보장
: 단 하나의 객체 = 싱글톤
**<싱글톤 만들기>**
1) private 생성자() ; // 외부에서 생성자 호출하여 객체 생성 못하도록 막음
2) private 정적 타입 필드 선언 후, 자신의 객체 생성하여 초기화
//외부에서 필드값 변경 못하도록 막음
3) 싱글톤 외부에서 호출 O 정적 메소드: getInstance() 메소드 선언
// getInstance() 메소드 : 단 하나의 객체만 리턴. 여러 번 호출해도 동일한 객체 리턴
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton() {}
static Singleton getInstance() {
return singleton;
}
[final 필드]
: 초기값 저장되면 최종값이 되어 프로그램 실행 도중 수정 불가
(1) 인스턴스 final 필드
: 객체 생성 시 외부 데이터값으로 초기화할 경우,
: 생성자에서 초기값 지정
: 객체마다 final 필드 생성
: 생성자의 매개값을 통해 초기화 시 여러 가지 값으로 초기화는 가능하며
: 객체마다 저장함
(2) static final 필드 : 상수
: 불변의 값, 공용성
: 여러 가지 값으로 초기화 불가능
: 객체마다 저장할 필요가 없음
: 객체마다 존재하지 않으며, 클래스에만 존재
: 상수이름은 모두 대문자 작성이 관례.
: 혼합된 이름은 _언더바로 연결
06-6. 패키지와 접근 제한자
[패키지]
: 자바는 클래스를 체계적으로 관리하기 위해 패키지 사용
: 파일시스템의 폴더 기능 +클래스 유일 식별자 역할
: 패키지는 클래스의 일부
: 만약 클래스 이동해야 한다면, 패키지 전체를 이동시켜야 한다.
: 패키지 이름은 소문자 작성이 관례
[패키지 선언] : package
**package** 상위패키지.하위패키지;
[import문]
: 사용하고자 하는 클래스가 다른 패키지 소속일 경우,
import문으로 해당 패키지의 클래스를 가져와 사용할 것임을 컴파일러에게 알리는 기능
: import문은 패키지 선언과 클래스 선언 사이에 작성
import 상위패키지.하위패키지.클래스이름; //개별 클래스 가져옴
import 상위패키지.하위패키지.*; //해당 패키지 소속된 여러 클래스들을 가져옴
: <주의> 상위패키지 import 했다고 하위패키지까지 import 되는 것 아니다.
→ 자바는 패키지 전체 이름으로 패키지를 식별하기 때문에
com.hankook 상위패키지와 com.hankook.project 하위패키지를 서로 다른 패키지로 인식함
→ 따라서 상위패키지와 하위패키지 각각의 클래스 사용 원하면 import문 2개 사용
: <주의> 서로 다른 패키지에서 동일한 이름 가진 클래스들을 가져와 사용 시
→패키지 이름과 함께 클래스 전체 이름 기술해서 사용
sec06.exam02.hankook.Tire tire = new sec06.exam02.hankook.Tire();
sec06.exam02.kumgo.Tire tire4 = new sec.exam02.kumgo.Tire();
[접근 제한자]
: 클래스, 생성자, 필드, 메소드에 대한 접근 허용 범위를 다룬다.
- public 접근제한자: 모든 패키지에서 자유롭게 사용
- protected 접근제한자: 같은 패키지 내부 + 다른 패키지의 자식 클래스에서 사용
- default 접근제한자: 같은 패키지 내부에서만 사용
- private 접근제한자: 오직 클래스 블록 내부에서만 사용
[클래스의 접근제한] default/public
▶️**default** 접근 제한 : 같은 패키지에서만 사용O
class 클래스 { ... }
▶️**public** 접근 제한 : 모든 패키지에서 자유롭게 사용O
**public** class 클래스 {...}
- 같은 패키지 내부에서는 default클래스, public클래스 접근 제약 X
- 다른 패키지 상에서는 public클래스만 접근O
[생성자의 접근제한] private. protected. public. default
: new연산자로 생성자 호출하여 객체 생성할 수 있는 위치를 제한
▶️public 접근 제한 : 모든 패키지에서 사용 | public 생성자(...)
▶️**protected 접근 제한 : 같은 패키지 내부 + 다른 패키지의 자식 클래스 사용 | protected 생성자(...)**
▶️**default 접근 제한 : 같은 패키지 내부에서만 사용 | 생성자 (...)**
▶️private 접근 제한 : 오직 클래스 블록 내부에서만 사용 | private 생성자(...)
▶️**기본 생성자의 접근 제한 : 클래스 내부에 생성자 선언X**
→ 해당 클래스의 접근 제한과 동일
- 동일 패키지 내부에서는 private 생성자 제외 하고는 모두 호출 O
- 다른 패키지에서는 public 생성자만 호출 O
[필드와 메소드의 접근제한] public. protected .default. private
public : 모든 패키지에서 자유
protected : 같은 패키지 내부 + 다른 패키지의 자식 클래스
default : 같은 패키지 내부에서만
private : 오직 클래스 블록 내부에서만
- 클래스 내부에서는 접근 제한과 관계없이 필드, 메소드 모두 사용 O
- 같은 패키지 내부에서는 private 제외 모든 필드,메소드 사용 O
- 다른 패키지에서는 public 필드, 메소드만 사용 O
[Getter와 Setter 메소드]
: ‘메소드‘를 통해 객체 필드에 접근하는 방식
: 객체지향 프로그래밍에서는 객체의 무결성을 위해
객체의 필드를 외부에서 직접적으로 접근하는 것을 막는다.
: 필드는 private, 필드에 대한 메소드는 public
→ 외부에서 메소드를 통해 필드에 접근하도록 유도
▶️**Setter 메소드**
: 외부의 매개값을 자체 검증하여 유효한 값만 받아 내부 객체 필드값을 변경하는 메소드
: 내부필드값 변경 목적이므로 반환값 X
: 메소드 이름 : set + 필드이름
▶️**Getter 메소드**
: 외부로 내부 필드값 읽어서 반환하는 메소드
: 필드값 가공하여 외부에 반환하기도 함
: 메소드 이름 : get + 필드이름
단, boolean 타입의 필드에 대한 Getter 메소드 이름: is+필드이름
**<Getter/Setter 메소드 자동생성>**
필드 선언 후 -> [sourse]-[Generate Getters and Setters] 메유 선택
→ 선언된 필드에 대한 메소드 자동 생성 기능 있다.
'Java > [문법]_Java(자바)' 카테고리의 다른 글
ch08. 인터페이스 (0) | 2021.08.04 |
---|---|
ch07. 상속 (0) | 2021.08.03 |
ch05. 참조 타입 (0) | 2021.07.29 |
ch04. 흐름 제어문 (조건문과 반복문) (0) | 2021.07.29 |
ch03. 연산자 (0) | 2021.07.29 |