이번엔 객체지향에 대해 공부한걸 정리하겠다.
JAVA가 객체지향 언어이기 때문에 우린 객체지향을 이해할 필요가 있다. 객체지향은 현실을 프로그램화해서 컴퓨터 내에 그대로 존재하게 만들려는 발상에서 시작했다.
객체
객체지향을 이해하려면 일단 객체에 대해 이해해야한다.
수업에서는 객체에대해 이해하려 하지말고 프로그램상 객체에대해서만 이해하면 공부하다보면 알아서 객체가 이해된다고 설명한다.(바로 객체를 이해할려는 행동은 안 좋다는 뜻)
그럼 프로그램에서 객체는 뭘까 우린 객체를 만들기 위해 클래스 라는것을 사용합니다.
클래스는 무엇일까?
클래스 : 객체를 정의해 놓은 것, 객체를 생성할 때 사용한다.
객체 : 실제로 존재하는 사물 또는 개념
그렇다면 클래스는 실제로 존재하는 사물 또는 개념을 프로그램상에 정의해놓은 것을 뜻합니다.
클래스는 변수와 메서드로 정의 되는데, 변수와 메서드를 기능과 속성에 따라 합해둔 것을 클래스 라고 정의합니다.
클래스명 변수명 = new 클래스명();
위와같은 방법으로 객체를 선언하고 생성할 수 있다.
배열 선언은 만약 Tv객체를 여러개 생성하고자 할 때 다음과 같이 선언함과 동시에 생성할 수 있다.
Tv[] tvArr = new Tv[3];
변수와 메서드
위 이미지에서 보이듯 변수의 종류는 3가지이다.
위치는 코드상 다음과 같다.
class Obj4_1 {
int iv; // 인스턴스 변수
static int cv; // 클래스 변수(static 변수, 공유 변수)
void method() {
int lv;
lv = 30;
// 지역변수는 자동으로 초기화가 되지 않기 때문에 사용하려면 반드시 초기화 필요
System.out.println("lv 지역 변수 = " + lv);
}
}
클래스 변수는 객체를 생성하지 않아도 클래스 이름으로 호출해서 사용할 수 있지만 인스턴스 변수는 객체를 생성했을 때만 사용할 수 있으며, 지역변수는 함수내에서만 불러서 사용할 수 있다.
클래스변수는 Obj4_1.cv로 사용할 수 있지만 인스턴스변수는 앞과 같은 방법으로 사용하려고 하면 에러가 발생한다.(Obj4_1.iv // 에러)
Obj4_1 obj = new Obj4_1();으로 객체를 생성해준뒤에 생성된 객체의 이름인 obj를 이용해 불러서 사용할 수 있다.
obj.iv와같이 사용된다.
메서드는 함수를 의미한다. 함수는 반환타입 함수명(타입 변수명){ //코드
return 반환값;}
의 형태로 진행된다. 만약 반환값이 없는 함수의 경우 void를 사용한다.
호출스택
호출스택이란 메서드를 호출했을 때 메서드가 사용될 메모리를 의미한다. 메서드가 호출되면 호출스택에 올라가서 실행되고, 실행이 끝나면 다시 호출스택에서 지워지게 된다.
기본형 매개변수와 참조형 매개변수
매개변수란 함수에()안에 들어가는 변수를 말하는데 전달인자라고도 이해할 수 있지만 전달인자는 값이기 때문에 지금 설명하는 매개변수로 설명하면 기본형 밖에 설명하지 못 한다.
참조형 매개변수는 주소값을 가리키는 것이라고 C++를 배울때 포인터 개념으로 처음 배웠던 기억이 있다. 매우 어려웠다.
기본형은 값만 받아서 받아온 매개변수의 값을 바꿔도 넣은 변수 자체의 값은 바뀌지 않고 말 그대로 "값"만 함수가 받아오는 것이지만,
참조형 매개변수는 주소값을 넣어줘서 넣어주는 변수 자체를 만질 수 있게 해준다.
static메서드
static메서드는 클래스변수와 비슷하게 객체생성없이 클래스이름만으로 호출해서 사용이 가능하다.
클래스이름.메서드이름();와 같이 이용할 수 있는데, 우리가 쓰는 Math.random()같은 Math도 static메서드이다.
오버로딩
오버로딩은 수용량 이상을 쌓다, 라는 뜻인데 같은 형태의 함수로 매개변수 타입, 위치, 개수를 다르게하여 같은 이름함수로 여러 기능을 구현할 수 있도록 해주는 기능을 말한다.
우리가 가장 흔히 아는 println도 이런 오버로딩을 이용해 만들어진다.
이렇게 println함수 이름 하나만으로 많은 종류의 매개변수를 대응할 수 있다.
생성자
생성자는 인스턴스가 생성될때마다 "무조건" 호출되는 인스턴스 초기화 메서드이다.
생성자는 클래스이름()로 만들수 있는데, 지금까지 만들지 않아도 동작했던 이유는 컴파일러가 생성자가 존재하지 않는 클래스에는 기본생성자로 아무 매개변수도 갖지않은 생성자를 기본으로 만들어준다. 그러므로 지금까지 생성자를 만들지 않고 코드를 실행해도 에러가 없던것은 컴파일러가 생성자를 만들고 호출한 뒤 실행되는 장면을 우리가 보고 있던것이다. 인스턴스 변수가 자동으로 0 이나 초기값으로 설정되던것도 이런이유에서이다.
따라서 생성자를 만드는 습관을 들여서 에러를 최대한 줄이고자 해야한다. 생성자는 값이 존재해야하는 인스턴스 변수를 객체생성과 동시에 초기화 시켜주는데 사용된다.
this, this()
this 는 기본적으로 자기자신을 의미한다.
따라서 리턴할 때도 this로 자기자신을 리턴할 수도 있고, this.변수명 으로 자기자신을 호출해서 사용할 수 도 있으며, this()는 자기 자신의 기본 생성자를 불러 사용할 수도 있다.
변수의 초기화
변수의 초기화 방법은 크게 3가지가 있는데, 명시적 초기화, 초기화 블럭, 생성자 초기화 이렇게 세가지 이다.
명시적 초기화는 기본적으로 선언과 동시에 변수를 초기화 하는데 가장 간단한 방법이다.
class Tv11_1 {
boolean power = false; // 기본형 변수의 초기화
int channel = 1; // 기본형 변수의 초기화
Audio audi = new Audio(); // 참조형 변수의 초기화, 참조형은 객체주소 or null 로 초기화!!
// 참조형의 기본값은 null 입니다!!
...
}
남은 두가지 방법은 복잡 초기화라고 하는데 위 초기화 방법보다 복잡하고, 다양하게 초기화 가능하다.
두번째 방법으로는 초기화 블럭을 이용한 초기화 방법인데, 아래와 같다.
class Tv11_2 {
static boolean power;
int channel;
// 클래스 초기화 블럭
static
{
power = false;
}
// 인스턴스 초기화 블럭
{
channel = 1;
}
...
}
세번째 방법으로는 가장 잘 알고있는 생성자를 이용한 초기화이다.
class Tv11_3 {
// 속성 : 변수 선언
boolean power; // 전원상태
int channel; // 채널
String color; // 색깔
long price; // 가격
// 위 속성에서 필수로 초기값이 필요한 값들을 초기화 해주는 기본 생성자
Tv11_3() {
this.power = false;
this.channel = 1;
}
...
}