1. 객체지향 언어
- 객제지향 언어 = 프로그래밍 언어 + 객체지향 개념(규칙)
핵심 개념
- 캡슐화
- 상속
- 추상화
- 다형성
객체지향 프로그래밍
- 특징
- 다형성
- 정보 은닉
- 추상화
- 캡슐화
- 장점
- 유지보수의 용이
- 복잡한 대형 프로그램 작성 가능
2~4. 클래스와 객체
클래스
- 정의 - 객체를 정의해 놓은 것
- 용도 - 객체를 생성하는데 사용
- 개념
- 객체를 생성하기 위한 설계도 혹은 틀
- 연관되어 있는 변수와 메서드의 집합
객체
- 정의 - 실제로 존재하는 것. 사물 또는 개념
- 용도 - 객체가 가지고 있는 기능과 속성에 따라 다름
- 개념
- 클래스의 인스턴스화 : 클래스로부터 객체를 만드는 과정
- 클래스의 타입으로 선언되었을 경우 객체
- 클래스에 선언된 그대로 소프트웨어 상에 설계도로 구현한 대상
- 특징
- “클래스의 인스턴스” 라고도 불림
- OOP관점에서 클래스의 타입으로 선언되었을 때 객체라고 부름
객체의 구성요소 - 속성과 기능
- 객체 = 속성(변수) + 기능(메서드)
class Tv {
// 속성(변수)
String color;
boolean power;
int channel;
// 기능(메서드)
void power() {
power = !power;
}
void channelUp() {
channel++;
}
void channelDown() {
channel--;
}
}인스턴스
-
객체 : 모든 인스턴스를 대표하는 일반적 용어
-
인스턴스 : 특정 클래스로부터 생성된 객체(예:Tv인스턴스)
-
클래스 → 인스턴스화 → 인스턴스(객체)
-
개념
- 클래스의 인스턴스 : 클래스로부터 만들어진 객체
- 객체가 메모리에 할당되어 실제 사용될 때 인스턴스
- 설계도를 바탕으로 소프트웨어 상에 구현된 실체
- 즉, 객체를 소프트웨어 상에 실체화
- 실체화된 인스턴스는 메모리에 할당됨
-
특징
- OOP관점에서 객체가 메모리에 할당되어 실제 사용될 때 인스턴스라고 부름
- 인스턴스는 어떤 원본(추상적인 개념)으로부터 생성된 복제본을 의미
- 추성적인 개념과 구체적인 객체 사이의 관계에 초점을 맞출 경우에 사용
- 객체는 클래스의 인스턴스
- 실행 프로세스는 프로그램의 인스턴스
예시
/* 클래스 */
public class Animal {
...
}
/* 객체와 인스턴스 */
public class Main {
public static void main(String[] args) {
Animal cat, dog; // 클래스의 타입으로 '객체' 선언
// 인스턴스화
cat = new Animal(); // cat은 Animal 클래스의 '인스턴스'(객체를 메모리에 할당)
dog = new Animal(); // dog은 Animal 클래스의 '인스턴스'(객체를 메모리에 할당)
Animal rat = new Animal();
// 참조변수 rat 은 Animal 인스턴스를 가리키고 있다.
// 인스턴스는 오직 참조변수를 통해서만 다룰 수 있다.
}
}6~7. 객체의 생성과 사용
1. 객체의 생성
클래스명 변수명; // 클래스의 객체를 참조하기 위한 참조변수를 선언
변수명 = new 클래스명(); // 클래스의 객체를 생성 후, 객체의 주소를 참조변수에 저장
Tv t; // Tv클래스 타입의 참조변수 t를 선언
t = new Tv(); // Tv인스턴스를 생성한 후, 생성된 Tv인스턴스의 주소를 t에 저장2. 객체의 사용
t.channel = 7; // Tv인스턴스의 멤버변수 channel의 값을 7로 설정
t.channelDown(); // Tv인스턴스의 메서드 channelDown()을 호출
System.out.println("현재 채널은 " + t.channel + " 입니다.");- 하나의 인스턴스를 여러 개의 참조변수가 가리키는 경우 (가능)
- 여러 개의 인스턴스를 하나의 참조변수가 가리키는 경우 (불가능)
8. 객체배열
- 객체 배열 == 참조변수 배열
Tv t1, t2, t3;
Tv[] tvArr = new Tv[3]; // 길이가 3인 Tv타입 참조변수 배열
// 객체를 생성해서 배열의 각 요소에 저장
tvArr[0] = new Tv();
tvArr[1] = new Tv();
tvArr[2] = new Tv();9~10. 클래스의 정의
- 클래스 == 데이터 + 함수
- 변수 - 하나의 데이터를 저장할 수 있는 공간
- 배열 - 같은 종류의 여러 데이터를 하나로 저장할 수 있는 공간
- 구조체 - 서로 관련된 여러 데이터(종류 관계X)를 하나로 저장할 수 있는 공간
- 클래스 - 데이터와 함수의 결합(구조체 + 함수)
- 사용자 정의 타입 - 원하는 타입을 직접 만들 수 있다.
// 시간을 나타내고 싶은 타입이 없을 경우
class Time {
int hour;
int minute;
int second;
}
Time t = new Time();11. 선언위치에 따른 변수의 종류
class Variables {
// 클래스 영역
// 선언문만 가능 (변수 선언, 메서드 선언)
int iv; // 인스턴스 변수
static int cv; // 클래스 변수(static변수, 공유변수)
void method() {
// 메서드 영역
int lv = 0; // 지역변수
}
}| 변수의 종류 | 선언위치 | 생성시기 |
|---|---|---|
| 클래스 변수 (class variable) | 클래스 영역 | 클래스가 메모리에 올라갈 때 (프로그램을 실행했을 때) |
| 인스턴스 변수 (instance variable) | 클래스 영역 | 인스턴스가 생성되었을 때 |
| 지역변수 (local variable) | 클래스 영역 이외의 영역 (메서드, 생성자, 초기화 블럭 내부) | 변수 선언문이 수행되었을 때 |
12~13. 클래스 변수와 인스턴스 변수
멤버변수 : 클래스 영역에 선언된 변수
- 인스턴스 변수
- 클래스의 인스턴스를 생성할 때 만들어짐
- 인스턴스마다 고유한 값을 가짐
- 클래스 변수 (static 변수)
- 모든 인스턴스가 공통으로 공유 (공통된 메모리 공간을 참조)
- 객체 생성 없이 사용 가능
class Card {
// 인스턴스 변수 (개별 속성)
String kind; // 무늬
int number; // 숫자
// 클래스 변수 (공통 속성)
static int width = 100; // 폭
static int height = 250; // 높이
}
// 객체 생성
Card c = new Card();
// 인스턴스 변수 설정
c.kind = "HEART";
c.number = 5;
// 클래스 변수 수정 시 클래스.cv 로 작성
Card.width = 200;
Card.height = 300;14~16. 메서드란?
함수와 메서드의 차이
- 함수 Function
- 특정 작업을 수행하는 코드조각
- 독립된 기능을 수행하는 단위
- 클래스로부터 독립적
- 메서드 Method
- 클래스, 구조체, 열거형에 포함되어 있는 함수
- 다른말로 클래스 함수
14. 메서드란?
- 문장들을 묶어놓은 것.
- 작업단위로 문장들을 묶어서 이름 붙인 것
- 값(입력)을 받아서 처리하고, 결과를 반환(출력)
- 메서드의 장점
- 코드의 중복을 줄일 수 있음
- 코드의 관리가 쉬움
- 코드를 재사용할 수 있음
- 코드가 간결해서 이해하기 쉬워짐
- 메서드의 작성
- 반복적으로 수행되는 여러 문장을 메서드로 작성
- 하나의 메서드는 한 가지 기능만 수행하도록 작성
- 메서드 = 선언부 + 구현부
// 선언부
int add (int a, int b) {
// 구현부
int result = a + b;
return result;
}15. 메서드의 구현부
- 지역변수(lv) : 메서드 내에 선언된 변수
// 메서드 영역
int add (int a, int b) {
// a, b 는 매개변수
// a, b, result 는 지역변수
int result = a + b;
return result;
}
// 메서드 영역
int multiply (int a, int b) {
// a, b 는 매개변수
// a, b, result 는 지역변수
int result = a * b;
return result;
}17~19. 메서드호출
public class ArgumentParameter {
public static void main(String[] args) {
int argument = 10;
operation(argument); // 전달인자(Argument, 원본)
}
private static int operation(int parameter){ // 매개변수(Parameter, 복사본)
parameter += 10;
return parameter;
}
}Call by value
- 함수에 전달되는 데이터 타입이 Primitive 일 경우
- 함수가 호출될 때, 함수를 위한 임의의 메모리 공간이 생성됨
- Call by value 방식으로 호출 시 전달되는 변수의 값을 복사하여 함수의 인자로 전달함
- 복사된 인자는 함수 안에서 지역적으로 사용되는 local value의 특성을 가짐
- 즉, 함수 안에서 인자의 값(Parameter)이 변경되어도, 외부 변수의 값(Argument)은 변경 X
Call by reference
- 함수에 전달되는 데이터 타입이 Reference 일 경우
- Call by reference 방식으로 호출 시 전달되는 변수의 번지수를 전달함
- Argument 와 parameter 모두 같은 객체를 참조하게 됨
- 즉, 함수 안에서 인자의 값이 변경되면, 외부 변수의 값도 변경됨
22. 호출 스택(call stack)

- 메서드 수행에 필요한 메모리가 제공되는 공간
- 메서드가 호출되면 호출스택에 메모리 할당, 종료되면 해제
23. 기본형 매개변수
- 기본형 매개변수 - 변수의 값을 읽기만 할 수 있다. (read only)
- 참조형 매개변수 - 변수의 값을 읽고 변경할 수 있다. (read & write)
class Data {
int x;
}
public class Ex6_6 {
public static void main(String[] args) {
Data d = new Data();
d.x = 10; // Data객체의 인스턴스 변수 초기화
System.out.println("main() : x = " + d.x);
change(d.x); // argument로 Data객체의 x를 준다.
System.out.println("After change(d.x)");
// 메서드 안에서는 d.x 와 같은 기본형 값을 리터럴로 사용했기 때문에 변함이 없음
System.out.println("main() : x = " + d.x);
}
static void change(int x) { // parameter로 Data객체의 x를 받지만 기본형은 리터럴로 전달
x = 1000; // 리터럴 x 를 1000 으로 변경
System.out.println("change() : x = " + x);
}
}24~25. 참조형 매개변수
- 기본형 매개변수 - 변수의 값을 읽기만 할 수 있다. (read only)
- 참조형 매개변수 - 변수의 값을 읽고 변경할 수 있다. (read & write)
class Data2 {
int x;
}
public class Ex6_7 {
public static void main(String[] args) {
Data2 d = new Data2();
d.x = 10; // Data2객체의 인스턴스 변수 x를 초기화
System.out.println("main() : x = " + d.x);
change(d);
System.out.println("After change(d.x)");
// 메서드가 객체를 참조하여 인스턴스 변수를 수정했기 때문에 변경사항이 생김
System.out.println("main() : x = " + d.x);
}
static void change(Data2 d) { // parameter로 참조형 Data2객체를 받음
d.x = 1000; // d객체의 인스턴스 변수를 직접 변경
System.out.println("change() : x = " + d.x);
}
}26~29. static 메서드, 인스턴스 메서드
인스턴스 메서드
- 인스턴스 생성 후,
‘참조변수.메서드이름()’으로 호출 - 인스턴스 멤버(iv, im)와 관련된 작업을 하는 메서드
- 메서드 내에서 인스턴스 변수(iv) 사용 가능
static 메서드
- 객체 생성 없이
‘클래스이름.메서드이름()’으로 호출 - 인스턴스 멤버(iv, im)와 관련없는 작업을 하는 메서드
- 메서드 내에서 인스턴스 변수(iv) 사용 불가
- 작성한 메서드 중 인스턴스 변수나 인스턴스 메서드를 사용하지 않는다면 static
30~31. 오버로딩(overloading)
- 한 클래스 안에 같은 이름의 메서드 여러 개 정의하는 것
오버로딩이 성립하기 위한 조건
- 메서드 이름이 같아야 한다.
- 매개변수의 개수 또는 타입이 달라야 한다.
- 반환 타입은 영향없다.
// 틀린 예시
// 반환 타입만 다르기 때문에 오버로딩이 아님 (중복 정의)
int add(int a, int b) {
return a + b;
}
long add(int a, int b) {
return (long)(a + b);
}
// 올바른 예시
// 매개변수의 타입이 다르기 때문에 오버로딩
long add(int a, long b) {
return a + b;
}
long add(long a, int b) {
return a + b;
}오버로딩의 올바른 예 - 매개변수는 다르지만 같은 의미의 기능수행
class MyMath3 {
int add(int a, int b) {
System.out.println("int add(int a, int b) - ");
return a + b;
}
long add(long a, long b) {
System.out.println("long add(long a, long b) - ");
return a + b;
}
int add(int[] a) {
System.out.println("int add(int[] a) - ");
int result = 0;
for (int i = 0; i < a.length; i++) {
result += a[i];
}
return result;
}
}32~35. 생성자, 기본 생성자
생성자 (constructor)
Time t = new Time();
t.hour = 12;
t.minute = 34;
t.second = 56;
Time t = new Time(12,34,56);- 개념
- 인스턴스가 생성될 때마다 호출되는 ‘인스턴스 초기화 메서드’
- 인스턴스 생성 시 수행 할 작업(iv 초기화)에 사용
클래스이름(타입 변수명, 타입 변수명, ...) {
// 인스턴스 생성 시 수행될 코드
// 주로 인스턴스 변수의 초기화 코드를 적는다.
}
class Card {
Card() { // 매개변수 없는 생성자
// 인스턴스 초기화 작업
}
Card(String kind, int number) { // 매개변수 없는 생성자
// 인스턴스 초기화 작업
}
}- 특징
- 이름이 클래스 이름과 같아야 한다.
- 리턴값이 없다. (void 안 붙임)
- 모든 클래스는 반드시 생성자를 가져야 한다.
기본 생성자 (default constructor)
class Data_1 {
int value;
}
class Data_2 {
int value;
Data_2(int x) { // 매개변수가 있는 생성자
value = x;
}
}
public class Ex6_11 {
public static void main(String[] args) {
Data_1 d1 = new Data_1();
Data_2 d2 = new Data_2(); // compile error 발생
}
}- 개념
- 매개변수가 없는 생성자
- 생성자가 하나도 없을 때만, 컴파일러가 자동 추가
매개변수가 있는 생성자
class Car {
String color;
String gearType;
int door;
Car() {} // 기본 생성자
Car(String c, String g, int d) { // 매개변수가 있는 생성자
color = c;
gearType = g;
door = d;
}
}
Car c = new Car();
c.color = "white";
c.gearType = "auto";
c.door = 4;
Car c = new Car("white", "auto", 4);36~37. 생성자 this(), 참조변수 this
생성자 this()
class Car2 {
String color;
String gearType;
int door;
Car2() {
this("white", "auto", 4);
}
Car2(String color) {
this(color, "auto", 4);
}
Car2(String color) {
door = 5; // 첫 줄에 쓰지 않아서 에러
Car(color, "auto", 4); // this를 쓰지 않아서 에러
}
Car2(String color, String gearType, int door) {
this.color = color;
this.gearType = gearType;
this.door = door;
}
}- 개념
- 생성자, 같은 클래스의 다른 생성자를 호출할 때 사용한다.
- 특징
- 다른 생성자 호출 시 첫 줄에서만 사용가능
참조변수 this
class Car2 {
String color;
String gearType;
int door;
Car2(String color, String gearType, int door) {
// this.color는 iv, color는 lv
this.color = color;
this.gearType = gearType;
this.door = door;
}
}- 개념
- 인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어 있다.
- 모든 인스턴스 메서드에 지역변수로 숨겨진 채로 존재한다.
- 특징
- 인스턴스 메서드(생성자 포함)에서 사용가능 (왜? this 는 인스턴스 변수를 의미하기 때문에)
- 지역변수(lv)와 인스턴스 변수(iv)를 구별할 때 사용
38~41. 변수, 멤버변수의 초기화
변수의 초기화
class InitTest {
// 자동 초기화
// 유지 기간이 비교적 길기 때문에 자동 초기화
int x; // 인스턴스 변수
int y = x; // 인스턴스 변수
void method1() {
// 수동 초기화
// 호출 스택 메모리는 재사용이 빈번하기 매번 자동 초기화 시 성능이 저하됨
// 지역변수는 메서드가 호출되서 작업하는 동안만 존재하기 때문에 생명 주기가 짧음
int i; // 지역변수
int j = i; // 에러. 지역변수를 초기화하지 않고 사용
}
}- 개념
- 지역변수(lv)는 수동 초기화 해야함 (사용 전 꼭!!!)
- 멤버변수(iv, cv)는 자동 초기화된다.
멤버변수의 초기화
- 클래스 변수 초기화 시점 : 클래스가 처음 로딩될 때 단 한 번
- 인스턴스 변수 초기화 시점 : 인스턴스가 생성될 때 마다
- 명시적 초기화(=) (간단한 초기화)
class Car {
int door = 4; // 기본형(primitive type) 변수의 초기화
Engine e = new Engine(); // 참조형(reference type) 변수의 초기화
}- 초기화 블럭 (복잡한 초기화)
- 인스턴스 초기화 블럭:
{ } - 클래스 초기화 블럭:
static { }
- 인스턴스 초기화 블럭:
class StaticBlockTest {
static int[] arr = new int[10]; // 명시적 초기화
static { // 클래스 초기화 블럭 - 배열 arr을 난수로 채운다.
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random() * 10) + 1;
}
}
}- 생성자 (복잡한 초기화)
Car(String color, String gearType, int door) { // 매개변수있는 생성자
this.color = color;
this.gearType = gearType;
this.door = door;
}