클래스란 '객체를 정의해 놓은 것' 또는'객체의 설계도 또는 틀'이며, 속성과 기능으로 정의되어 있다.
객체는 클래스에 정의된 대로 생성된다.
프로그래밍 관점에서 클래스의 정의와 의미
위의 정의는 '객체지향이론'의 관점에서 내린 정의이고, 프로그래밍 관점에서 클래스의 정의는 다음과 같다.
1. 클래스 - 데이터와 함수의 결합
2. 클래스 - 사용자 정의 타입 : 프로그래밍 언어에서 제공하는 자료형 외에 프로그래머가 서로 관련된 변수들을 묶어서 하나의 타입으로 새로 추가하는 것
클래스로부터 객체를 만드는 과정을 '클래스의 인스턴스화'라고 하며,
어떤 클래스로부터 만들어진 객체를 그 클래스의 인스턴스라고 한다.
속성 : 멤버변수, 특성, 필드, 상태
기능 : 메서드, 함수, 행위
클래스명 변수명; // 클래스의 객체를 참조하기 위한 참조변수 선언
변수명 = new 클래스명(); // 클래스의 객체를 생성 후, 객체의 주소를 참조변수에 저장
Tv= t;
t = new TV();
객체 배열 안에 객체가 저장되는 것은 아니고,
객체의 주소가 저장된 배열이다.
객체 배열은 참조변수들을 하나로 묶은 참조 변수 배열인 것이다.
변수의 종류는 선언 위치에 따라 달라진다.
인스턴스 변수
클래스의 인스턴스를 생성할 때 만들어진다. 인스턴스마다 고유한 상태를 유지해야하는 속성의 경우, 인스턴스변수로 선언한다.
클래스 변수
static을 앞에 붙이기만 하면 된다. 모든 인스턴스가 공통된 저장공간을 공유하게 된다. 한 클래스의 모든 인스턴스들이 공통적인 값을 유지해야하는 속성의 경우, 클래스변수로 선언해야한다.
지역 변수
메서드 내에 선언되어 메서드에서만 사용 가능하며, 메서드가 종료되면 소멸되어 사용할 수 없게 된다.
메서드는 특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것이다.수학에서 함수와 유사하다.
메서드는 선언부와 구현부로 이루어져있다.
메서드의 이름, 매개변수 선언, 반환타입으로 구성되어있다.
후에 변경사항이 발생하지 않도록 신중히 작성해야한다.
선언부 다음에 오는 괄호{}를 메서드의 구현부라고 하는데, 여기에 메서드 호출 시 수행될 문장들을 넣는다.
메서드의 반환타입이 void가 아닌 경우, 구현부{} 안에 반드시 return 반환값이 포함되어야한다.
이 값의 타입은 반환타입과 일치하거나 적어도 자동 형변환이 가능한 것이어야 한다.
변수의 값을 읽기만 할 수 있다.
기본형 매개변수는 복사본이 변경된 것이라 원본에는 아무런 영향도 미치지 못한다.
변수의 값을 읽고 변경할 수 있다.
복사본이 아닌 원본의 주소를 받음으로써, 원본에 영향을 미칠 수 있다.
반환타입이 참조형이라는 것은 메서드가 객체의 주소를 반환한다는 것을 의미한다.
메서드의 내부에서 메서드 자신을 호출하는 것을 '재귀호출'이라 한다.
반복문과 마찬가지로 종료 조건을 붙이지 않는 이상, 무한 호출되는 불상사가 발견한다.
참고로 반복문이 있음에도 불구하고 재귀호출을 사용하는 이유는 '논리적 명확성'때문이다. (예를 들어, 피보나치 수열, 팩토리얼 등을 반복문으로 작성하는 것 보다는 재귀함수 호출이 더 논리적으로 직관적이다.)
하지만 재귀함수 호출은 반복문보다 메모리 (함수가 실행될 메모리 영역이 계속 추가되므로), 호출시간 등이 걸리는 단점이 있다.
인스턴스 메서드는 변수와 관련된 작업을 하는, 즉 메서드의 작업을 수행하는데 인스턴스 변수를 필요로 하는 메서드이다.
인스턴스와 관계 없는(인스턴스 변수나 인스턴스 메서드를 사용하지 않는) 메서드
클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다.
클래스 변수(static변수)는 인스턴스를 생성하지 않아도 사용할 수 있다.
클래스 메서드(static 메서드)는 인스턴스 변수를 사용할 수 없다.
메서드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려한다.
같은 클래스에 속한 멤버들 간에는 별도의 인스턴스를 생성하지 않고도 서로 참조 또는 호출이 가능하다.
단, 클래스 멤버가 인스턴스 멤버를 참조 또는 호출하고자 하는 경우에는 인스턴스를 생성해야 한다.
한 클래스 내의 같은 이름의 메서드를 여러 개 정의하는 것을 오버로딩이라 한다.
오버로딩의 조건
1. 메서드 이름이 같아야 한다.
2. 매개변수의 개수 또는 타입이 달라야 한다.
int add(int a, int b){return a+b;}
int add(long a, long b){return a+b;}
매개변수의 개수가 고정적이지 않아도 메서드 선언이 가능하다.
가변인자는 '타입.. 변수명'과 같은 형식으로 선언한다.
public PrintStream printf(String format, Object ... args} {...}
//단, 가변인자가 있다면 매개변수의 마지막 순서로 적어줘야한다.
생성자는 인스턴스가 생성될 때 호출되는 '인스턴스 초기화 메서드'이다.
생성자의 조건
1. 생성자의 이름은 클래스와 같아야 한다.
2. 생성자는 리턴 값이 없다.
생성자는 한 클래스에 하나만 존재할 수 있다.
따라서 따로 클래스에 정의된 생성자가 하나도 없을 때에는 컴파일러에 의해 기본 생성자가 추가된다.
new 연산자와 생성자의 차이점
new는 인스턴스를 생성할 때에 사용하는 것,
생성자는 인스턴스변수들을 초기화하기 위해 사용되는 것.
생성자라는 이름 자체때문에 혼동하지 말자.
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);
//아래쪽 코드처럼 매개변수를 갖는 생성자를 사용하는 것이 보다 직관적이고 간결하다!
생성자 간에도 서로 호출이 가능하다. 단 조건이 있다.
생성자 간에 호출하기 위한 조건
1. 생성자의 이름으로 클래스이름 대신 this를 사용한다.
2. 한 생성자에서 다른 생성자를 호출할 때에는 반드시 첫 줄에서만 호출이 가능하다.
Car(String c,String g, int d){
color=c;
gearType=g;
door = d;
}
Car(Car c) {
this(c.color,c.gearType,c.door);
//위의 생성자와 같은 의미다.
}
this와 this()의 차이점
this - 인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어있다.
this() - 생성자, 같은 클래스의 다른 생성자를 호출할 때 사용
인스턴스 생성 시 결정해야 할 것
1. 클래스 - 어떤 클래스의 인스턴스를 생성할 것인가
2. 생성자 - 선택한 클래스의 어떤 생성자로 인스턴스를 생성할 것인가
지역변수는 사용하기 전에 반드시 초기화를 해야한다.
(멤버 변수: 클래스변수, 인스턴스변수 와 배열의 초기화는 선택적이다.)
멤버변수의 초기화는 지역변수와 달리 여러 방법이 존재한다.
가장 기본적인 초기화 방법
class Car{
int door=4; // 기본형 변수의 초기화
Engine e = new Engine(); //참조형(e) 변수의 초기화
//...
}
인스턴스 변수의 초기화에는 주로 새엇ㅇ자를 사용한다.
클래스 초기화 블럭은 클래스 변수의 초기화에 사용된다.
ㄴ 인스턴스 초기화 블럭 앞에 단순히 static을 덧붙이기만 하면 된다
인스턴스 초기화 블럭은 인스턴스 변수의 복잡한 초기화에 사용된다.
ㄴ 단순히 클래스 내에 블럭{}을 만들고 그 안에 코드를 작성하면 된다.
class InitBlock {
static { /* 클래스 초기화블럭입니다. */}
{/* 인스턴스 초기화블럭 입니다.*/}
//...
}
인스턴스 초기화 블럭은 모든 생성자에서 공통으로 수행돼야 하는 코드를 넣는데 사용한다.
{ //인스턴스 초기화 블럭. 아래 두 개 생성자에서 공통적으로 수행되어야 하는 코드
count++;
serialNo = count;
}
Car() {
color="White";
gearType="Auto";
}
Car(String color,String gearType){
this.color=color;
this.gearType=gearType;
}