[ 제 6장 객체지향언어 1 ]
(프로그래밍언어 +객체지향개념)
특징
① 코드의 재사용성이 높다
② 유지보수 용이
③ 중복코드 제거
핵심 개념 ( 캡슐화, 상속, 추상화, 다향성 )
< 클래스와 객체 >
- 클래스
객체를 정의해 놓은 설계도 – 객체를 이용하기 위해
데이터(변수)+함수(메서드) :서로 관련된 데이터들을
하나로 저장할 수 있는 공간
사용자 정의 타입 – 사용자가 원하는 타입을 직접
만들 수 있음
- 객체 (iv 묶음) : 실제로 존재하는 것 ,
용도는 기능(변수)과 속성(메서드)에 따라 다름
- 클래스(설계도) --인스턴스화 -->인스턴스(객체)
- 객체생성 : 클래스명 참조변수명 = new 클래스명( );
- 객체배열(=참조변수의 배열) :
객체 배열 생성 후 반드시 객체를 생성해줄 것 !
타입[ ]배열이름= new타입[n]
< 변수의 종류 >
- 선언 위치에 따른 변수의 종류
1 영역
가) 클래스영역
① cv : 객체생성필요X, 아무 때나 사용가능,
클래스가 메모리에 올라갈 때 생성, 자동생성
② iv : 객체를 생성해야 사용가능
인스턴스가 생성 될 때 생성됨, 객체생성 필요
나) 메서드 영역
① lv : 클래스 이외의 영역 (메서드, 생성자, 초기화
블럭 내부)에서 선언되며 메서드 종료 시
자동제거됨, 변수선언문이 수행 됐을 때 생성
< 클래스 변수 와 인스턴스 변수 >
- 객체의 속성 :
숫자, 무늬 등 개별속성( iv ) 참조변수,변수이름
폭, 높이 등 공통속성( cv ) cv는 사용할 때 클래스 이름,변수 이름
- iv는 인스턴스가 생성될 때마다 생성되므로 각기 다른 값으로 유지할 수 있지만, cv는 하나의 저장공간을 공유하므로 항상 공통된 값을 가진다
<지역변수>
메서드 내에 선언된 변수 메서드 영역이 서로 다른 지역변수들은 이름이 중복 되어도 관계없다.
<메서드> = {명령문 묶음}
- 꼭 클래스 안에 있어야 한다
- 문장들을 작업단위로 묶어서 이름 붙인 것
- 값(입력)을 받아서 처리하고, 결과를 반환(출력)
- 메서드의 장점
1. 코드의 중복 줄일 수 있음
2. (한곳에 수행하기에)관리가 쉽다
3. 코드 재사용 가능
4. 코드가 간결해서 이해하기 쉬움
- 메서드 작성 : 반복되는 여러 문장을 메서드로 작성
하나의 메서드는 한가지 기능만 수행하도록 작성
- 메서드 = 선언부 + 구현부 로 구성
선언부 반환타입 메서드명(타입 변수명, …)
ex) int add (int x, int y)
구현부 {메서드 호출 시 실행 될 코드}
ex) { int result = x + y ; }
- 메서드 호출 : 메서드 이름(값1, 값2, …);
ex) int result=add(3,5);
- 메서드 실행흐름
객체생성->메서드호출->메서드 수행문 수행->호출한곳 반환
< return문 >
실행중인 메서드를 종료하고 호출한 곳으로 되돌아감
반환타입이 void가 아닌경우, 반드시 return문 필요
조건식(if문) 쓸 때 조건이 거짓일 경우에도 return필요
-반환값 : 반환타입 void가 아닌경우, 반환타입을 일치
아니면 자동형변환 가능 타입(int경우 byte, short, char)
-매개변수의 유효성 검사
적절하지 않은 값이 들어오면 매개변수의 값을 보정하던가, return문으로 작업을 중단하고 호출한 메서드로 되돌아가게 하는 코드를 반드시 넣어야 한다.
<기본형 매개변수와 참조형 매개변수>
기본형(8개)매개변수 : 변수의 값 읽기만 가능
참조형 매개변수 : 변수의 값 읽고 변경할 수 있음
- 호출 스택
메서드 수행에 필요한 메모리가 제공되는 공간
메서드가 호출되면 호출 스택에 메모리가 할당, 종료되면 해제
맨 위의 메서드만 실행 중, 나머지는 대기
- 참조형 반환타입
객체주소(0x100)를 반환한다
객체주소를 줬기 때문에 객체를 다룰 수 있게 됨
- 재귀호출
메서드가 자기자신을 호출해서 일을 시키는 것
< 클래스 메서드와 인스턴스 메서드 > iv사용여부
- 인스턴스 메서드 (객체 필요)
인스턴스 생성 후 “참조변수.메서드 이름()”으로 호출
인스턴스 멤버(iv, im)와 관련된 작업을 하는 메서드
메서드에서 인스턴스 변수 사용가능
- static 메서드
객체생성 없이 “클래스이름.메서드 이름()”으로 호출
인스턴스 멤버(iv, im)와 관계없는 작업을 하는 메서드
메서드 내에서 인스턴스 변수 사용불가(iv 사용하지 않으면 static 붙일 것)
-메서드 간 호출과 참조
static 메서드 – O –>인스턴스 메서드 불가능
static메서드는 iv 사용불가, 객체가 있을지 없을지 모르기에 불가능
인스턴스 메서드 – X–> static 메서드 가능
인스턴스 메서드가 호출 되어 이미 객체 생성(iv가 이미 존재)하기에 가능
< 오버로딩 >
한 클래스 안에 같은 이름의 메서드를 n 개 정의한 것
- 오버로딩 조건
1. 메서드 이름이 같아야 함
2. 매개변수의 개수 or 타입이 달라야 한다
3. 반환타입은 영향 X
< 생성자 >
인스턴스가 생성될 때마다 호출되는
”인스턴스 초기화 메서드”
- 생성자 조건
1. 생성자 이름이 클래스 이름과 같아야 함
2. 리턴 값이 없다 (void 안 붙임)
3. 모든 클래스는 반드시 하나이상의 생성자 가진다
4.생성자가 하나도 없을 때, 컴파일러가 자동추가 함
5.다른 생성자 호출 시 this()
6.생성자 첫 줄에 다른 생성자 호출 아니면
super()자동 삽입
< 기본 생성자 >
클래스이름( ){ } -> (매개변수){하는 일} 도 없음
매개변수가 없는 생성자
생성자 하나도 없을 때만 컴파일러 기본생성자 자동추가해줌
< 매개변수가 있는 생성자 >
인스턴스를 생성하는 동시에 원하는 값으로 초기화 할 수 있게 됨
인스턴스 생성 후 인스턴스 변수의 값을 변경하는 것보다 이게 코드가 더 간결함
< 생성자 this( ) >
조건
1. 생성자에서 같은 클래스의 다른 생성자를 호출할 때, 클래스이름 대신 this( )를 사용함
2. 다른 생성자 호출 시 첫 줄에서만 사용가능
(다른 생성자로 인해 호출 이전의 초기화 작업이 무의미 해지므로 첫 줄에서만 사용 가능)
< 참조변수 this >
인스턴스 변수(iv)와 지역변수(lv)의 이름이 같을 때 구분하려고 사용. this붙으면 iv, 안 붙여주면 매개변수와 가까운 lv가 된다
인스턴스 자신을 가리키는 참조변수(객체주소가 저장 되어있음)
인스턴스 메서드 사용가능 / static메서드에서 사용불가
< 변수의 초기화 >
멤버변수 (iv, cv)는 자동초기화(기본값으로)
지역변수(lv)는 우리가 수동으로 초기화(사용 전 반드시 초기화 필요)
< 멤버변수의 초기화와 시기, 순서 >
멤버변수의 초기화
1. 자동 초기화 “0”
2. 간단 초기화 “=”
3. 복잡초기화
A. { } (거의 안씀)
B. cv 에서는 static{ }
C. iv 에서는 생성자( ){ }
- 멤버변수의 초기화 시기와 순서
클래스변수 초기화 후 인스턴스 변수 초기화
클래스 초기화 | 인스턴스 초기화 | |||||
기본값 | 명시적 초기화 | 클래스 초기화 블록 | 기본값 | 명시적 초기화 |
인스턴스 초기화 블록 |
생성자 |
cv 0 | cv 1 | cv 2 | cv 2 iv 0 |
cv 2 iv 1 |
cv 2 iv 2 |
cv 2 iv 3 |
1 | 2 | 3 | 4 | 5 | 6 | 7 |
[ 제 7 장 객체지향언어 2 ]
< 상속 >
기존클래스로 새로운 클래스를 작성하는 것(코드의 재사용)
두 클래스를 부모와 자식으로 관계를 맺어주는 것
자손은 조상의 모든 멤버를 상속받는다.(생성자, 초기화 블록 제외)
자손의 변경은 조상에 영향을 미치지 않는다
자손의 멤버개수는 조상보다 적을 수 없다(같거나 크다)
< 포함 관계 >
클래스의 멤버로 다른 클래스 타입의 참조변수를 선언하는 것
작은 단위의 클래스를 만들고 이들을 조합해서 클래스를 만든다
클래스 간 관계 결정하기
1. 상속관계 : ~는 ~이다
2. 포함관계 : ~는 ~를 가지고 있다
< 단일 속성 >
Java는 단일속성(하나의 부모의 상속)만 허용
비중이 높은 클래스만 상속, 나머지 포함관계로 한다
< Object 클래스>
모든 클래스의 조상, 부모가 없는 클래스는 자동으로 Object클래스를 상속받음
모든 클래스는 Object클래스에 정의된 11개의 메서드를 상속받는다
< 메서드 오버 라이딩 >
상속받은 조상의 메서드를 자신에 맞게 변경하는 것
오버라이딩 조건
1. 선언부가 조상과 일치
( 이름,매개변수,반환타입 같음 )
2. 접근제어자를 조상클래스보다 좁은 범위로 변경할 수 없음
3. 예외는 조상메서드 보다 많이 선언할 수 없다
- 오버로딩 VS 오버라이딩 비교
오버로딩 : 자손에 없는 새로운 메서드를 정의
이름이 같고 매개변수가 다르다
오버라이딩 : 상속받은 메서드의 내용을 변경하는 것
< 참조변수 super >
객체 자신을 가리키는 참조변수 인스턴스메서드(생성자)내에서만 존재
조상클래스의멤버를 자손클래스멤버와 구별할 때 사용
< 조상의 생성자 super( ) >
조상의 생성자를 호출할 때 사용( 생성자와 초기화 블럭은 상속 안되니까)
조상의 멤버는 조상의 생성자를 호출해서 초기화
자손의 생성자는 자신이 선언한 변수만 초기화 가능
생성자의 첫 줄에 반드시 생성자를 호출해야 한다 그렇지 않으면 컴파일러가 생성자의 첫 줄에 super( )삽입-----모든 클래스이 조상이 Object
< 패키지 >
클래스는 클래스파일(*.class), 패키지는 폴더, 하위 패키지는 하위 폴더
클래스의 실제이름은 패키지를 포함(java.long.String)
패키지의 선언 : Package 패키지명;
같은 소스파일의 클래스들은 모두 같은 페키지에 속하게 된다
< 클래스패스(환경변수) >
클래스파일(*.class)위치를 알려주는 경로(path)
환경변수로 관리하며 경로간 구분은 ’ ; ‘을 사용
환경변수에 패키지 루트를 등록
< import 문 >
클래스를 사용할 때 패키지 이름을 생략가능
컴파일러에게 클래스가 속한 패키지를 알려준다
선언 : import 패키지명.클래스명;
이름이 같은 클래스가 속한 두 패키지를 import할때는 클래스 앞 패키지명
static import문
static 멤버 (static 메서드, cv)를 사용할 때, 클래스 이름을 생략하게 해줌
< 제어자 >
클래스와 클래스멤버(멤버변수,메서드)에 부가적인 의미부여
-접근제어자 : public, protected, (default), private
-그 외 : static, final, abstract
하나의 대상에 여러 제어자를 같이 사용가능(접근제어자는 한 개만)
접근제어자를 맨 왼쪽으로
- static : 클래스의 , 공통의
static은 멤버변수, 메서드, 초기화블럭에서 사용
(객체생성없이도)
static 메서드 내에서는 인스턴스 멤버들을
직접 사용할 수 없다.
- final : 마지막의, 변경될 수 없는
final은 어디든 붙일 수 있음. 어디에 붙느냐에 따라 기능이 달라짐
1. 클래스 : 변경, 확장불가능한 클래스. 상속계층도의 제일 마지막 자손없는 클래스
2. 변수(iv, lv) : 상수
3. 메서드 : 오버라이딩이 불가능한 메서드(변경될 수 없는)
- abstract : 추상의, 미완성의
1. 클래스 : 클래스 안에 추상메서드가 있음(미완성 설계도)
2. 메서드 : 선언부만 있고 {구현부}가 없는 메서드
3. abstract 클래스는 객체를 생성할 수 없고, 추상메서드를 갖고 있으니 상속받아서 완성해 줘야 한다
- 접근제어자
제어자 | 같은 클래스 |
같은 패키지 |
자손 클래스 |
전체 |
public | O | O | O | O |
protected | O | O | O | |
(default) | O | O | ||
private | O |
접근범위 public > protected > (default) > private
- 캡슐화와 접근제어자
접근제어자를 사용하는 이유
1. 외부로부터 데이터를 보호하기 위해(외부에서 메서드를 통해 간접접근 허용)
2. 외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해
< 다형성 >
다형성의 장점
1. 조상타입 참조변수로 자손타입 객체를 다루는 것
2. 하나의 배열에 여러 종류의 객체 저장
참조변수가 사용할 수 있는 멤버의 개수는 인스턴스의 멤버개수보다 같거나 적어야 한다
참조변수타입과 인스턴스타입은 보통 일치하지만 일치하지 않을 수도 있다
< 참조변수의 형변환 >
(리모컨을 변경 함으로서) 사용할 수 있는 멤버의 개수를 조절하는 것
조상,자손관계의 참조변수는 서로 형변환이 가능(형제관계는 없다)
리모컨 기능이 많은 쪽에서 적은 쪽으로 줄이기 안전
(자손 -> 조상 O)
작은 쪽을 늘리때는 안전하지 않으니 형 변환 필요
(조상 -> 자손 X)
< instanceof 연산자 >
참조변수의 형변환 가능여부 확인. 가능하면 true반환
형변환 전에 반드시 instanceof로 확인필요
주로 조건문에 사용
ex) if( 참조변수 instanceof 타입(클래스명) )
< 매개변수의 다형성 >
참조형 매개변수는 메서드 호출 시 자신과 같은 타입 또는 자손타입의 인스턴스를 넘겨줄 수 있다
< 여러 종류의 객체를 다루는 배열로 다루기 >
조상 타입의 배열에 자손타입객체를 담을 수 있다
다루고 싶은 객체들의 상속관계를 따져서 가장 가까운 공통조상 클래스타입의 참조변수 배열을 생성해서 객체들을 저장
< 추상클래스 >
미완성 메서드/ 미완성 메서드를 갖고 있는 클래스
다른 클래스 작성에 도움을 주기 위한 것. 인스턴스 생성 불가
상속을 통해 추상메서드 완성 후 인스턴스 생성가능
추상클래스를 상속받아 -> 추상 메서드의 {구현부} 완성 -> 완성된 설계도(객체생성 가능)
< 추상클래스의 작성 >
장점 1. 설계도를 쉽게 작성
2. 코드중복제거
3. 코드관리가 용이
구체화 된 코드보다 유연(변경에 유리)
추상화 : 클래스 간의 공통점을 찾아내서 공통의 조상을 만드는 작업
< 인터페이스 >
추상메서드의 집합, (모든 멤버 public)
구현된 것이 전혀 없는 설계도, 껍데기
- 추상메서드 vs 인터페이스
추상메서드 : 추상메서드를 가진 일반클래스
인터페이스 : 추상메서드 빼고 구현된 게 하나도 없음
- 인터페이스 선언
interface 인터페이스 이름 {
public static final 타입 상수이름 = 값 ; public abstract 메서드이름(메개변수목록) ; } |
인터페이스의 조상은 인터페이스만 가능(Object가 최고자상이 아님)
다중상속 가능 (추상메서드는 충돌해도 문제 X)
public, static, final, abstract 전부 생략가능
- 인터페이스의 구현
(인터페이스에 정의된 추상메서드를 완성하는 것)
class 클래스 이름 implements 인터페이스이름{
(인터페이스에 정의된 추상메서드를 모두 구현 해야함) } |
일부만 구현한 경우, 클래스의 앞에 abstract를 붙임
추상클래스와는 둘 다 추상메서드를 가진다는 공통점이 있지만 인터페이스는 iv를 가질 수 없다
< 인터페이스를 이용한 다형성 >
인터페이스도 구현클래스의 부모이다
인터페이스 타입의 매개변수는 인터페이스를 구현한 클래스의 객체만 가능
인터페이스를 메서드의 리턴 타입으로 지정할 수 있다
->안 맞으면 형변환
( 이 인터페이스를 구현한 놈을 반환하겠다는 뜻 )
객체에서 다른 객체를 참조 할 때 메서드를 거쳐서 간접적으로 접근 -> 캡슐화
< 인터페이스의 장점 >
1. 두 대상 (객체)간의 ‘연결, 대화, 소통’을 돕는 ‘중간역할’을 한다
2. 변경에 유리한 설계 가능
3. 개발시간을 단축할 수 있다
( I가 있기에 B완성 기다리지 않아도 된다 )
4. 표준화가 가능하다
5. 서로 관련 없는 클래스들을 관계 맺어줄 수 있다
6. 선언(껍데기)와 구현(알맹이)을 분리할 수 있다
A는 I하고만 관계 있음 B와는 관계 없음
알맹이 B가 C로 바뀌어도 A 코드 수정할 필요 없다
'공부 > JAVA' 카테고리의 다른 글
[1회차 01] 자바 간단 정리 (0) | 2024.05.09 |
---|---|
[java] 정석코딩 자바 문제 오답노트 (0) | 2024.04.04 |
[java] 자바의 정석 요약정리 8 ~ 9장 (0) | 2024.04.04 |
[java] 자바의 정석 요약정리 2 ~ 5장 (0) | 2024.04.04 |