일반 데이터 타입의 배열과 동일한 개념으로, 같은 클래스의 객체 여러
개를 그룹화 할 수 있다.
일반 데이터형의 배열 생성과 객체 배열 생성 비교
일반 데이터 형 배열의 경우
int[] data = new int[3];
객체 배열의 경우
Army[] data = new Army[3];
일반 데이터형은 단순히 값을 대입하지만, 객체 배열은 'new'를
사용해서 객체를 할당해야 한다.
일반 데이터 형 배열의 경우
data[0] = 1;
data[2] = 2;
data[3] = 3;
객체 배열의 경우
data[0] = new Army();
data[1] = new Army();
data[2] = new Army();
배열의 생성이 부모 클래스로 지정되었을 경우, 모든 자식 클래스의
객체들은 그 배열에 포함될 수 있다.
Unit[] unit = new Unit[3];
// 배열의 요소 할당 과정에서 암묵적 형변환이 이루어 진다.
unit[0] = new Army();
unit[1] = new Navy();
unit[2] = new AirForce();
일괄처리가 가능
-> 서로 다른 객체를 부모 형태의 배열에 담게 되면, 반복문으로
일괄처리가 가능하다.
-> 이 때 배열의 각 요소를 통해 사용하는 메서드가 Override되어
있을 경우, 부모의 메서드가 아니라 자신이 재정의한 기능을 뜻한다.
for( int i = 0; i<unit.length; i++ ){
unit[i].attack();
}
원래의 기능으로 복귀하기
-> 배열의 각 요소가 확장한 기능을 사용하기 위해서는
원래의 클래스 형태로 명시적 형변환이 이루어 져야 한다.
-> 하지만 반복적으로 처리되는 과정에서 몇 번째 요소가 어떤 클래스에서
최초 생성 되었는지를 판단하기란 쉽지 않다.
instanceof 연산자
-> instanceof 연산자는 어떤 객체에 대한 출처를 판단하여
boolean 형으로 결과를 반환한다
if( unit[0] instanceof Army ){
Army temp = (Army)unit[0];
}
추상 메서드를 정의하기 위해서는 'abstract' 키워드를 사용하여 메서드를
정의한다.
추상 메서드는 자식 클래스가 구현해야 하는 메서드의 가이드라이만 제시하기
위한 목적으로 사용되기 때문에, 선언만 가능하고 구현부가 없다.
// 선언만 가능하고, 구현부를 위한 블록이 존재하지 않는다.
public abstract void move();
추상 메서드를 하나 이상 포함하고 있는 크래스는 반드시 '추상 클래스'로
정의되어야 한다.
추상 클래스는 'abstract' 키워드를 사용하여 정의할 수 있다.
// 추상 클래스의 정의
public abstract class Hello{
public abstract void move();
}
추상 클래스는 객체를 생성할 수 없고, 반드시 상속을 통해서만 사용될 수
있다. 즉 추상 클래스는 다른 자식 클래스를 위한 '가이드라인'의 역할을 한다.
추상 클래스는 생성자, 멤버변수, 일반 메서드등을 포함할 수 있다.
즉 공통 기능과 가이드라인을 모두 정하여 다른 클래스에게 상속된다.
public abstract class Hello{
// 멤버변수
private String msg;
// 생성자
public Hello( String msg ){ this.msg = msg; }
// 일반 메서드
public String getMsg(){ return this.msg; }
// 선언만 되고, 구현부를 위한 블록이 존재하지 않는다.
public abstract void sayHello();
}
추상클래스
-> 멤버변수, 생성자, 메서드, 추상메서드를 포함할 수 있다.
-> 이 클래스를 상속받는 자식 클래스는 다른 클래스를 상속받을 수
없다.
-> 객체의 생성이 불가능하다
인터페이스
-> 추상메서드만 포함할 수 있다.
-> 인터페이스는 다중 상속이 가능하다.
-> 객체의 생성이 불가능하다.
인터페이스는 콤마(,)로 연결하여 여러 개를 동시에 상속 받을 수 있다.
public class Monster implements Fight, Move{
}
필요한 경우 다른 클래스와 동시에 상속받을 수 있다.
public class Monster extends User implements Fight, Move{
}
public class Article{
private static int count; // 전체 글 수
private static String category; // 카테고리
private int num; // 글 번호
private String title; // 글 제목
private String regDate; // 날짜
}
코드영역(고정영역)
-> 프로그램의 코드가 저장되는 영역
이 영역에서 저장된 명령어들을 CPU가 하나씩 가져가 실행한다.
데이터영역(고정영역)
-> 전역변수와 static으로 선언된 변수가 할당된다.
이 영역에 할당되는 변수들은 프로그램 시작과 동시에 메모리 공간이
할당되어 종료될 때까지 남아있게 된다.
힙영역(동적 영역)
-> 프로그래머가 원하는 시점에 변수를 할당하고 소멸 시키는 여역
메모리 동적 할당시 사용된다.객체가 생성되는 영역이다.
스택 영역(동적 영역)
-> 함수가 실행될 때 사용되는 파라미터와 지역변수에 대한 메모리 공간.
함수의 종료와 함께 소멸된다.
고정영역
-> 프로그램이 실행되면 실행파일이 메모리에 로드 된다.
실행파일의 용량만큼 메모리를 사용한다.
-> 실행파일의 크기는 변할 수 없으므로 이 영역의 크기는 고정 크기를
갖는다.
동적영역
-> 프로그래머가 new 키워드를 사용해서 객체나 배열을 생성하면
사용된다. (힙영역)
-> 메서드가 호출되는 동안 사용될 파라미터와 지역변수가 생성된다.
(스택영역)
-> 메서드가 종료되나 객체가 더이상 사용되지 않으면 생성된 변수나
객체는 메모리에서 사라지므로, 이 영역은 유동적인 크기를 갖게 된다.
static 변수는 프로그램의 실행과 동시에 객체의 생성 여부와 상관 없이
이미 존재하기 때문에 소스 코드에는 특정 클래스 안에 명시하지만,
그 클래스를 통해서 생성되는 객체나 그 안에 포함되는 멤버변수와는
다른 존재이다.
객체가 생성되지 않더라도 이미 존재하고 있기 때문에 static 변수는
객체의 이름을 통해 접근하는 것이 아니라, 클래스의 이름을 통해서
접근해야 한다.
단, static 변수가 선언된 클래스 안에서는 변수 이름으로 직접 접근
허용된다.
- Article 클래스 및 다른 클래스에서 접근하는 경우
Article.coutn = 5;
Article.category = "공지사항";
- Article 클래스 내부에서 접근하는 경우
count = 6;
category = "공지사항";
클래스에서 정의하는 일반 메서드들은 객체의 생성과 동시에 동적 메모리
영역에서 활성화 된다.
-> 동적 메모리 영역의 입장에서는 고정 메모리 영역의 자원들은
항상 존재한다.
-> 고정 메모리 영역의 자원들은 동적 메모리의 자원들이 항상 존재하는
것이라는 보장을 받지 못한다.
그러므로 객체의 생성과 상관 없이 static 변수에 접근하기 위한 메서드를
만들 필요 있을때, 메서드의 정의 과정에서 static키워드를 사용하면
staic 자원에 접근하기 위한 메서드를 만들 수 있다.
public staic void setCount(int count){
Article.count = count;
}
메모리 영역의 차이 때문에 static 메서드는 동적 메모리 영역의 멤버변수를
사용하거나, static이 아닌 일반 함수를 호출할 수 없다.