객체 지향 언어란?
객체지향이론의 기본 개념은 '실제 세계는 사물(객체)로 이루어져 있으며, 발생하는 모든 사건들은 사물간의 상호작용이다.'라는 것이다. 실제 사물의 속성과 기능을 분석한 다음, 데이터(변수)와 함수로 정의한 것이다.
객체 지향 언어 주요특징
- 코드의 재사용성이 높다.
- 코드의 관리가 용이하다.
- 신뢰성이 높은 프로그래밍을 가능하게 한다.
객체지향개념 4가지
상속 | 캡슐화 | 추상화 | 다형성 |
클래스와 객체
클래스 |
|
객체 |
|
+정리하자면 클래스와 객체의 관계는 제품 설계도와 제품의 관계라고 할 수 있다. 예를 들면, TV 설계도(클래스)는 TV라는 제품(객체)을 정의한 것이며, TV(객체)를 만드는데 사용된다. 클래스는 단지 객체를 생성하는데 사용될 뿐, 객체 그 자체는 아니다. 우리가 원하는 기능의 객체를 사용하기 위해서는 먼저 클래스로부터 객체를 생성하는 과정이 선행되어야 한다.
*클래스로부터 객체를 만드는 과정을 클래스의 인스턴스화(instantiate)라고 하며, 어떤 클래스로부터 만들어진 객체를 그 클래스의 인스턴스(instance)라고 한다.
객체의 구성요소
객체는 속성과 기능의 집합이다. 객체가 가지고 있는 속성과 기능을 그 객체의 멤버(구성원, member)라 한다.
속성 | 멤버변수(member variable), 특성(attribute), 필드(field), 상태(state) |
기능 | 메서드(method), 함수(function), 행위(behavior) |
ex) TV
위에서 분석한 내용을 토대로 TV 클래스를 만들면 다음과 같다.
인스턴스 생성과 사용
인스턴스는 참조변수를 통해서만 다룰 수 있으며, 참조변수의 타입은 인스턴스의 타입과 일치해야한다.
위의 TV 클래스를 이용하여 인스턴스를 생성해보자!
class Tv{
String color;
boolean power;
int channel;
void power() {power= !power;}
void channelUp(){++channel;}
void channelDown(){--channel;}
}
public class TvTest {
public static void main(String[] args) {
Tv t1 = new Tv();
t1.color = "black";
t1.power = false;
t1.channel = 5;
t1.power();
t1.channelDown();
t1.channelUp();
t1.channelUp();
System.out.println("t1 color : "+t1.color); // t1 color : black
System.out.println("t1 power : "+t1.power); // t1 power : true
System.out.println("t1 channel : "+t1.channel); // t1 channel : 6
Tv t2 = new Tv();
System.out.println("t1 channel : "+t1.channel); // t1 channel : 6
System.out.println("t2 channel : "+t2.channel); // t2 channel : 0
t2 = t1;
t1.channel = 7;
System.out.println("t1 channel을 7로 변경");
System.out.println("t1 channel : "+t1.channel); // t1 channel : 7
System.out.println("t2 channel : "+t2.channel); // t2 channel : 7
}
}
객체 배열
객체 배열은 참조변수들을 하나로 묶은 참조 변수 배열이다. 객체 배열 안에 객체가 저장되는 것은 아니고, 객체의 주소가 저장된다.
*여기서 주의해야 할 점!
객체 배열을 생성하는 것은 그저 객체를 다루기 위한 참조 변수들이 만들어진 것일 뿐 아직 객체가 저장되지 않은 상태다!
객체를 생성해서 객체 배열의 각 요소에 저장하는 것을 잊으면 안 된다.
Tv[] tvArr = new Tv[3]; // 참조변수 배열(객체 배열)을 생성
// 객체를 생성해서 배열의 각 요소에 저장
// 방법1)
tvArr[0] = new Tv();
tvArr[1] = new Tv();
tvArr[2] = new Tv();
// 방법2)
Tv[] tvArr = {new Tv(), new Tv(), new Tv()};
// 방법3)
for(int i=0; i<tvArr.length; i++) {
tvArr[i] = new Tv();
}
변수와 메소드
- 선언 위치에 따른 변수의 종류
* 클래스 변수(cv) : 객체 생성 필요 X, iv에 static 변수를 함께 선언한 것, 언제나 사용 가능.
'클래스이름.클래스변수'
* 인스턴스 변수(iv) : 객체 생성 필요
- 메서드
- 정의 : 특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것이다. 어떤 값을 입력하면 이 값으로 작업을 수행해서 결과를 반환한다.메서드에 넣을 값(입력)과 반환하는 결과(출력)만 알면 되는 것이다. 내부적으로 어떤 과정을 거치는 지는 전혀 몰라도 된다. 그래서 메서드를 내부가 보이지 않는 '블랙박스'라고도 한다.
- 메서드를 사용하는 이유
- 높은 재사용성
- 중복된 코드의 제거
- 프로그램의 구조화
기본형 매개변수와 참조형 매개변수
기본형 매개변수 | 변수의 값을 읽기만 할 수 있다. (read only) |
참조형 매개변수 | 변수의 값을 읽고 변경할 수 있다. (read & write) |
- 참조형 반환타입
class Data {int x;}
public class ReferenceReturnEx {
public static void main(String[] args) {
Data d = new Data();
d.x = 10;
Data d2 = copy(d);
System.out.println("d.x = "+d.x);
System.out.println("d2.x = "+d2.x);
}
static Data copy(Data d){
Data tmp = new Data(); // 새로운 객체 tmp를 생성한다.
tmp.x = d.x; // d.x의 값을 tmp.x에 복사한다.
return tmp; // 복사한 객체이 주소를 반환한다.
}
}
copy 메소드가 호출된 직후부터 종료까지의 과정을 단계별로 나타내면 다음과 같다.
① copy 메소드를 호출하면서 참조변수 d의 값이 매개변수 d에 복사된다.
② 개로운 객체를 생성한 다음, d.x에 저장된 값을 tmp.x에 복사한다.
③ copy 메서드가 종료되면서 반환한 tmp의 값은 참조변수 d2에 저장된다.
④ copu 메서드가 종료되어 tmp가 사라졌지만, d2로 새로운 객체를 다룰 수 있다.
"반환타입이 '참조형'이라는 것은 메서드가 '객체의 주소'를 반환한다는 것을 의미한다."
클래스 메서드(static 메서드)와 인스턴스 메서드
- 클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다.
- 클래스 변수(static 변수)는 인스턴스를 생성하지 않아도 사용할 수 있다.
- 클래스 메서드(static 메서드)는 인스턴스 변수를 사용할 수 없다.
- 메서드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려한다.
- 인스턴스 변수를 필요로 하지 않는다면 static을 붙이자. 메서드 호출시간이 짧아지므로 성능이 향상된다. static을 안 붙인 메서드(인스턴스 메서드)는 실행 시 호출되어야 할 메서드를 찾는 과정이 추가적으로 필요하기 때문에 시간이 더 걸린다.
- 클래스의 멤버변수 중 모든 인스턴스에 공통된 값을 유지해야하는 것이 있는지 살펴 보고 있으면, static을 붙여준다.
- 작성한 메서드 중에서 인스턴스 변수나 인스턴스 메서드를 사용하지 않는 메서드에 static을 붙일 것을 고려한다.
[참고]
Java의 정석 3판 (남궁성 저)
'공부 > 자바' 카테고리의 다른 글
생성자(Constructor) (0) | 2024.05.29 |
---|---|
오버로딩(overloading) (0) | 2024.05.29 |
배열 선언과 초기화 (0) | 2024.05.26 |
조건문과 반복문 (0) | 2024.05.25 |
연산자 (0) | 2024.05.24 |