JAVA 객체 배열, 추상화, 인터페이스, 메모리 구조

김태헌·2022년 9월 18일
post-thumbnail

1. 객체배열

1-1. 객체배열

  • 일반 데이터 타입의 배열과 동일한 개념으로, 같은 클래스의 객체 여러
    개를 그룹화 할 수 있다.

  • 일반 데이터형의 배열 생성과 객체 배열 생성 비교

    일반 데이터 형 배열의 경우
    int[] data = new int[3];

    객체 배열의 경우
    Army[] data = new Army[3];

1-2. 각 경우에 대한 배열의 요소 할당 처리

  • 일반 데이터형은 단순히 값을 대입하지만, 객체 배열은 'new'를
    사용해서 객체를 할당해야 한다.

    	일반 데이터 형 배열의 경우
    	data[0] = 1;
    	data[2] = 2;
    	data[3] = 3;
    
    	객체 배열의 경우
    	data[0] = new Army();
    	data[1] = new Army();
    	data[2] = new Army();

1-3. 부모 클래스의 배열에 자식 클래스의 객체를 넣기

  • 배열의 생성이 부모 클래스로 지정되었을 경우, 모든 자식 클래스의
    객체들은 그 배열에 포함될 수 있다.

    	Unit[] unit = new Unit[3];
    	// 배열의 요소 할당 과정에서 암묵적 형변환이 이루어 진다.
    	unit[0] = new Army();
    	unit[1] = new Navy();
    	unit[2] = new AirForce();

1-4. 객체 배열의 활용

  • 일괄처리가 가능
    -> 서로 다른 객체를 부모 형태의 배열에 담게 되면, 반복문으로
    일괄처리가 가능하다.
    -> 이 때 배열의 각 요소를 통해 사용하는 메서드가 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];
    	}
  1. 추상화

2-1. 상속성과 다형성의 필요성

  • 상속성은 객체간의 공통적인 기능을 관리하기 위한 기법으로,
    코드의 재사용을 통하여 프로그램의 유지보수를 편리하게 한다.
  • 다형성(Override, Overload)은 서로 다른 기능이지만 메서드의 이름을
    공통되게 처리함으로서 전체 프로그램의 일관성을 유지하게 한다.

2-2. Override 처리의 문제 발생 가능성

  • '@Override' 키워드를 사용하지 않고 메서드를 재정의 하는 과정에서
    메서드 이름에 실수가 발생하더라도 에러가 아닌 새로운 메서드의
    정의로 인식되므로 의도하지 않은 실행결과를 가져올 수 있다.
  • '@Override' 키워드를 사용하더라도 자식 클래스를 구현하는 개발자의 실수로
    부모의 기능을 재정의 하지 않았다면, 다형성의 구현은 이루어지지 않게된다.

2-3. 상속 처리시, Override를 강제하기

  • 추상화 기법은 특정 클래스를 상속받은 경우, 부모의 특정 메서드들을
    무조건 재정의하도록 강제하는 기법이다.
  • 특정 메서드를 재정의하도록 강제함으로써, 자식 클래스들을 작성하기 위한
    가이드의 역할을 할 수 있다.
  • 즉, 추상화 기법은 java 클래스를 작성하기 위한 설계도를 소스코드
    형태로 제시하는 역할을 한다.

2-4. 추상 메서드 만들기

  • 추상 메서드를 정의하기 위해서는 'abstract' 키워드를 사용하여 메서드를
    정의한다.

  • 추상 메서드는 자식 클래스가 구현해야 하는 메서드의 가이드라이만 제시하기
    위한 목적으로 사용되기 때문에, 선언만 가능하고 구현부가 없다.

    	// 선언만 가능하고, 구현부를 위한 블록이 존재하지 않는다.
    	public abstract void move();

2-5. 추상 메서드를 포함한 클래스

  • 추상 메서드를 하나 이상 포함하고 있는 크래스는 반드시 '추상 클래스'로
    정의되어야 한다.

  • 추상 클래스는 'abstract' 키워드를 사용하여 정의할 수 있다.

    // 추상 클래스의 정의
    public abstract class Hello{
    public abstract void move();
    }

  • 추상 클래스는 객체를 생성할 수 없고, 반드시 상속을 통해서만 사용될 수
    있다. 즉 추상 클래스는 다른 자식 클래스를 위한 '가이드라인'의 역할을 한다.

2-6. 공통 기능과 설계 제시를 모두 처리

  • 추상 클래스는 생성자, 멤버변수, 일반 메서드등을 포함할 수 있다.

  • 즉 공통 기능과 가이드라인을 모두 정하여 다른 클래스에게 상속된다.

    public abstract class Hello{
    // 멤버변수
    private String msg;

    // 생성자
    public Hello( String msg ){ this.msg = msg; }
    
    // 일반 메서드
    public String getMsg(){ return this.msg; }
    
    // 선언만 되고, 구현부를 위한 블록이 존재하지 않는다.
    public abstract void sayHello();

    }

3. 인터페이스

3-1.추상 클래스의 한계

  • 자바 클래스 간의 상속에는 하나의 부모만 존재할 수 있기 때문에,
    앞의 상황에서 요구하는 다중 상속의 구현은 불가능하다.

3-2. Interface란?

  • 완벽한 추상화를 구현하기위한 java Class의 한 종류이다.
  • 다중 상속이 가능하기 때문에 용도별로 세분화 하여 필요한 요소만 상속할
    수 있다.

3-3. 비교

  • 추상클래스
    -> 멤버변수, 생성자, 메서드, 추상메서드를 포함할 수 있다.
    -> 이 클래스를 상속받는 자식 클래스는 다른 클래스를 상속받을 수
    없다.
    -> 객체의 생성이 불가능하다

  • 인터페이스
    -> 추상메서드만 포함할 수 있다.
    -> 인터페이스는 다중 상속이 가능하다.
    -> 객체의 생성이 불가능하다.

3-4. 인터페이스 상속을 위한 implements 키워드

  • 인터페이스의 상속은 implements 키워드를 사용한다.
  • 인터페이스도 추상화를 구현하고 있기 때문에, 인터페이스를 상속받는
    클래스는 인터페이스 내의 모든 메서드들을 반드시 재정의 해야 한다.

3-5. 인터페이스의 다중 상속

  • 인터페이스는 콤마(,)로 연결하여 여러 개를 동시에 상속 받을 수 있다.

    public class Monster implements Fight, Move{

    }

  • 필요한 경우 다른 클래스와 동시에 상속받을 수 있다.

    public class Monster extends User implements Fight, Move{

    }

4. Static

public class Article{
	private static int count;		// 전체 글 수
	private static String category;	// 카테고리

	private int num;		// 글 번호
	private String title;		// 글 제목
	private String regDate;		// 날짜
}
  • 멤버변수는 모든 객체가 독립적으로 갖는 고유 데이터이기 때문에
    게시물의 수라는 공유 데이터를 모든 게시물이 갖게 된다.
  • 즉, 각각의 객체가 중복된 데이터를 갖게 된다.
  • 클래스를 설계할 때, 멤버변수 중 모든 객체에서 공통적으로 사용해야
    하는 값에 static 을 붙인다.
  • static이 붙은 멤버변수는 객체의 개수에 상관 없이 단 하나만 생성되며,
    이를 모든 객체가 공유하기 때문에 메모리를 효율적으로 사용할 수 있다.

4-1. 컴퓨터의 메모리 구조

  • 코드영역(고정영역)
    -> 프로그램의 코드가 저장되는 영역
    이 영역에서 저장된 명령어들을 CPU가 하나씩 가져가 실행한다.

  • 데이터영역(고정영역)
    -> 전역변수와 static으로 선언된 변수가 할당된다.
    이 영역에 할당되는 변수들은 프로그램 시작과 동시에 메모리 공간이
    할당되어 종료될 때까지 남아있게 된다.

  • 힙영역(동적 영역)
    -> 프로그래머가 원하는 시점에 변수를 할당하고 소멸 시키는 여역
    메모리 동적 할당시 사용된다.객체가 생성되는 영역이다.

  • 스택 영역(동적 영역)
    -> 함수가 실행될 때 사용되는 파라미터와 지역변수에 대한 메모리 공간.
    함수의 종료와 함께 소멸된다.

4-2. 하나의 프로그램이 사용하는 메모리영역

  • 고정영역
    -> 프로그램이 실행되면 실행파일이 메모리에 로드 된다.
    실행파일의 용량만큼 메모리를 사용한다.
    -> 실행파일의 크기는 변할 수 없으므로 이 영역의 크기는 고정 크기를
    갖는다.

  • 동적영역
    -> 프로그래머가 new 키워드를 사용해서 객체나 배열을 생성하면
    사용된다. (힙영역)
    -> 메서드가 호출되는 동안 사용될 파라미터와 지역변수가 생성된다.
    (스택영역)
    -> 메서드가 종료되나 객체가 더이상 사용되지 않으면 생성된 변수나
    객체는 메모리에서 사라지므로, 이 영역은 유동적인 크기를 갖게 된다.

4-3. static 데이터의 생성 위치

  • static 데이터는 메모리의 고정영역 중 데이터영역에 생성되고,
    일반 멤버변수나 객체는 동적영역중 Heap 메모리 영역에 생성된다.

4-4. 프로그램이 메모리를 사용하는 순서

  • 최초 실행시 고정 영역에 실행파일만큼의 메모리를 점유한다.
  • 프로그램이 각종 동작을 수행하는 동안 동적 영역을 사용한다.

4-5. 멤버변수와 static 멤버변수의 차이

  • static 변수는 프로그램의 실행과 동시에 객체의 생성 여부와 상관 없이
    이미 존재하기 때문에 소스 코드에는 특정 클래스 안에 명시하지만,
    그 클래스를 통해서 생성되는 객체나 그 안에 포함되는 멤버변수와는
    다른 존재이다.

  • 객체가 생성되지 않더라도 이미 존재하고 있기 때문에 static 변수는
    객체의 이름을 통해 접근하는 것이 아니라, 클래스의 이름을 통해서
    접근해야 한다.

  • 단, static 변수가 선언된 클래스 안에서는 변수 이름으로 직접 접근
    허용된다.

    	- Article 클래스 및 다른 클래스에서 접근하는 경우
    
    		Article.coutn = 5;
    		Article.category = "공지사항";
    
    	- Article 클래스 내부에서 접근하는 경우
    
    		count = 6;
    		category = "공지사항";

4-6. static 데이터에 접근하기 위한 메서드

  • 클래스에서 정의하는 일반 메서드들은 객체의 생성과 동시에 동적 메모리
    영역에서 활성화 된다.
    -> 동적 메모리 영역의 입장에서는 고정 메모리 영역의 자원들은
    항상 존재한다.
    -> 고정 메모리 영역의 자원들은 동적 메모리의 자원들이 항상 존재하는
    것이라는 보장을 받지 못한다.

  • 그러므로 객체의 생성과 상관 없이 static 변수에 접근하기 위한 메서드를
    만들 필요 있을때, 메서드의 정의 과정에서 static키워드를 사용하면
    staic 자원에 접근하기 위한 메서드를 만들 수 있다.

    	public staic void setCount(int count){
    		Article.count = count;
    	}
  • 메모리 영역의 차이 때문에 static 메서드는 동적 메모리 영역의 멤버변수를
    사용하거나, static이 아닌 일반 함수를 호출할 수 없다.

profile
개발자 과정 국비 수료 중

0개의 댓글