풀스택 과정 day13_Java
2022.3.24.(목)
추상화
인터페이스
Static
1. 추상화
1-1. 상속성과 다형성의 필요성
- 상속성은 객체 간의 공통적인 기능을 관리하기 위한 기법으로
코드의 재사용을 통하여 프로그램의 유지보수를 편리하게 한다.
- 다형성( Override, Overload )은 서로 다른 기능이지만
메서드의 이름을 공통되게 처리함으로써 전체 프로그램의
일관성을 유지하게 한다.
1-2. Override 처리의 문제 발생 가능성
- '@Override' 키워드를 사용하지 않고 메서드를 재정의 하는
과정에서 메서드 이름에 실수가 발생하더라도 에러가 아닌
새로운 메서드의 정의로 인식되므로 의도하지 않은 실행결과를
가져올 수 있다.
- '@Override' 키워드를 사용하더라도 자식 클래스를 구현하는
개발자의 실수로 인하여 부모의 기능을 재정의 하지 않았다면
다형성의 구현은 이루어지지 않게 된다.
1-3. 상속 처리 시, Override를 강제하기
- 추상화 기법은 특정 클래스를 상속받은 경우, 부모의 특정
메서드들을 무조건 재정의하도록 강제하는 기법이다.
- 특정 메서드를 재정의하도록 강제함으로써, 자식 클래스들을
작성하기 위한 가이드의 역할을 할 수 있다.
- 즉, 추상화 기법은 java 클래스를 작성하기 위한 설계도를
소스코드 형태로 제시하는 역할을 한다.
1-4. 추상 메서드 만들기
- 추상 메서드를 정의하기 위해서는 'abstract' 키워드를
사용하여 메서드를 정의한다.
- 추상 메서드를 자식 클래스가 구현해야 하는 메서드의
가이드라인만 제시하기 위한 목적으로 사용되기 때문에,
선언만 가능하고 구현부가 없다.
// 일반 메서드
public void sayHello( ); {
... 구현부 ...
};
// 추상 메서드
// 선언만 가능하고, 구현부를 위한 블록이 존재하지 않는다.
public abstract void sayHello( );
1-5. 추상 메서드를 포함한 클래스
- 추상 메서드를 하나 이상 포함하고 있는 클래스는 반드시
'추상 클래스'로 정의되어야 한다.
- 추상 클래스 'abstract' 키워드를 사용하여 정의할 수 있다.
// 추상 클래스의 정의
public abstract class Hello {
public abstract void sayHello( );
}
- 추상 클래스는 객체를 생성할 수 없고, 반드시 상속을 통해서만 사용될 수 있다.
즉, 추상 클래스는 다른 자식 클래스를 위한 '가이드라인'의 역할을 한다.
< 추상 메서드 sayHello를 포함한 추상 클래스 Hello >
< 추상 메서드의 Override >
1-6. 공통 기능과 설계 제기를 모두 처리하기
- 추상 클래스는 생성자, 멤버변수, 일반 메서드 등을 포함할 수 있다.
- 즉, 공통 기능과 가이드라인을 모두 정의하여 다른 클래스에게 상속된다.
public abstract class Hello {
// 멤버변수 선언
private String msg;
// 생성자
public Hello( String msg ) { this.msg = msg; }
// 일반 메서드
public String getMsg( ) { return this.msg };
public void setMsg( String msg ) { this.msg = msg; }
// 선언만 되고, 구현부를 위한 블록이 존재하지 않는다.
public abstract void sayHello( );
}
< 추상 메서드를 포함한 부모 클래스 Unit >
< 추상 메서드를 Override한 자식 클래스 Army >
< 추상 메서드를 Override한 자식 클래스 Navy >
< 추상 메서드를 Override한 자식 클래스 AirForce >
< 추상 메서드 예제의 실행값 >
- Navy, AirForce Class 생성, Unit 상속,
- main( ) 포함 클래스 생성, 각각의 객체 생성 후, 메서드( attack( ), move( ) ) 호출
2. 인터페이스
public abstract class Unit {
public abstract void attack( ); // 공격
public abstract void shield( ); // 방어
public abstract void walk( ); // 걷기
public abstract void run( ); // 뛰기
public abstract void jump( ); // 점프
public abstract void pickup( ); // 아이템 줍기
}
- 추상 클래스인 Unit의 기능을 용도별로 분할하여 나누어 놓고,
주인공과 몬스터가 각각의 기능 중에서 자신에게 필요한 것들만
상속 받도록 하는 방법을 필요로 한다.
2-1. 추상 클래스의 한계
- 자바 클래스 간의 상속에서는 하나의 부모만 존재할 수 있기 때문에,
앞의 상황에서 요구하는 다중 상속의 구현은 불가능하다.
2-2. Interface란?
- 완벽한 추상화를 구현하기 위한 java Class의 한 종류이다.
- 다중 상속이 가능하기 때문에 용도별로 세분화 하여 필요한 요소만 상속할 수 있다.
추상 클래스
-> 멤버변수, 생성자, 메서드, 추상 메서드를 포함할 수 있다.
-> 이 클래스를 상속받는 자식 클래스는 다른 클래스를 상속받을 수 없다.
-> 객체의 생성이 불가능하다.
인터페이스
-> 추상 메서드만 포함할 수 있다.
-> 인터페이스는 다중 상속이 가능하다.
-> 객체의 생성이 불가능하다.
< 인터페이스 생성 이유 : 공통된 메서드나 수행될 동작을 인터페이스로 만들어 상속 받기 위해서 >
2-3. 인터페이스 상속을 위한 implements 키워드
- 인터페이스의 상속은 implements 키워드를 사용한다.
- 인터페이스도 추상화를 구현하고 있기 때문에, 인터페이스를 상속받는 클래스는
인터페이스 내의 모든 메서드들을 반드시 재정의 해야 한다.
< attack( ) 메서드와 shield( ) 메서드를 가지는 Unit interface >
< Unit을 상속 받는 User 클래스 >
2-4. 인터페이스 다중 상속
- 인터페이스는 콤마( , )로 연결하여 여러 개를 동시에 상속받을 수 있다.
public class Monster implements Fight, Move {
}
- 필요한 경우 다른 클래스와 동시에 상속받을 수 있다.
public class Monster extends User implements Fight, Move {
}
< interface의 사용 예 >
< pickup( ) 메서드를 가지는 Action interface >
< attack( ) 메서드와 shield( ) 메서드를 가지는 Fight interface >
< walk( ) 메서드와 run( ) 메서드, jump( ) 메서드를 가지는 Move interface >
< Action과 Fight, Move interface를 모두 상속 받는 Character 클래스 >
< Fight와 Move interface를 상속 받는 Monster 클래스 >
< Character와 Monster 클래스의 메서드 실행 >
3. Static
// 하나의 게시물을 표현하기 위한 클래스
// 요청사항 : 전체 글 수, 카테고리 정보
public class Article {
private int count; // 전체 글 수
private String category; // 카테고리
private int num; // 글 번호
private String title; // 제목
private String regDate; // 날짜
}
- 멤버변수는 모든 객체가 독립적으로 가지는 고유 데이터이기 때문에
게시물의 수라는 공유 데이터를 모든 게시물이 갖게 된다.
- 즉, 각각의 객체가 중복된 데이터를 갖게 된다.
3-1. 객체 간의 공유 자원을 표현하는 static 키워드
- 클래스를 설계할 때, 멤버변수 중 모든 객체에서 공통적으로 사용해야 하는 값에
static을 붙인다.
public class Article {
private static int count; // 전체 글 수
private static String category; // 카테고리
private int num; // 글 번호
private String title; // 제목
private String regDate; // 날짜
}
- static이 붙은 멤버변수는 객체의 갯수에 상관 없이 단 하나만 생성되며,
이를 모든 객체가 공유하기 때문에 메모리를 효율적으로 사용할 수 있다.
< 객체 간의 공유 자원을 이용하기 위한 static >
< static 사용 후의 모형도 >
3-2. 컴퓨터의 메모리 구조
- 코드영역(고정 영역)
-> 프로그램의 코드가 저장되는 영역
이 영역에 저장된 명령어들을 CPU가 하나씩 가져가 실행한다.
- 데이터 영역(고정 영역)
-> 전역변수와 static으로 선언되는 변수가 할당된다.
이 영역에 할당되는 변수들은 프로그램 시작과 동시에 메모리 공간이 할당되어
종료될 때 까지 남아있게 된다.
- 힙 영역(동적 영역)
-> 프로그래머가 원하는 시점에 변수를 할당하고, 소멸시키는 영역
메모리 동적 할당시 사용된다. 객체가 생성되는 영역이다.
- 스택 영역(동적 영역)
-> 함수가 실행될 때 사용되는 파라미터와 지역변수에 대한 메모리 공간
함수의 종료와 함께 소멸된다.
3-3. 하나의 프로그램이 사용하는 메모리 영역
- 고정 영역
-> 프로그램이 실행되면 실행 파일이 메모리에 로드되면서,
실행파일의 용량만큼 RAM을 사용한다.
-> 실행 파일의 크기는 변할 수 없으므로 이 영역의 크기는 고정 크기를 갖는다.
- 동적 영역
-> 프로그래머가 new 키워드를 사용해서 객체나 배열을 생성하면 사용된다.
( 힙 영역 )
-> 또 다른 경우는 메서드가 호출되는 동안 사용될 파라미터와 지역변수가
생성된다.( 스택 영역 )
-> 메서드가 종료되거나 객체가 더 이상 사용되지 않으면 생성된 변수나
객체는 메모리에서 사라지므로, 이 영역은 유동적인 크기를 갖게 된다.
3-4. static 데이터의 생성 위치
- static 데이터는 메모리의 고정 영역 중 데이터 영역에 생성되고,
일반 멤버변수나 객체는 동적 영역 중 Heap 메모리 영역에 생성된다.
3-5. 프로그램이 메모리를 사용하는 순서
- 최초 실행시 고정 영역에 실행 파일만큼의 메모리를 점유한다.
- 프로그램이 각종 동작을 수행하는 동안 동적 영역을 사용한다.
3-6. 멤버변수와 static 멤버변수의 차이
- static 변수는 프로그램의 실행과 동시에 객체의 생성 여부와 상관 없이
이미 존재하기 때문에 소스코드에서는 특정 클래스 안에 명시하지만,
그 클래스를 통해서 생성되는 객체나 그 안에 포함되는 멤버변수와는 다른 존재이다.
- 객체가 생성되지 않았더라도 이미 존재하고 있기 때문에 static 변수는 객체의
이름을 통해 접근하는 것이 아니라, 클래스의 이름을 통해서 접근해야 한다.
- 단, static 변수가 선언된 클래스 안에서는 변수 이름으로 직접 접근이 허용된다.
- Article 클래스 및 다른 클래스에서 접근하는 경우
Article.count = 9;
Article.category = "공지사항";
- Article 클래스에서 접근하는 경우
count = 15;
category = "Q&A게시판";
3-7. static 변수와 static 메서드
- 클래스에서 정의하는 일반 메서드들은 객체의 생성과 동시에
동적 메모리 영역에서 활성화 된다.
-> 동적 메모리 영역의 입장에서는 고정 메모리 영역의 자원들은 항상 존재한다.
-> 고정 메모리 영역의 자원들은 동적 메모리의 자원들이 항상 존재하는
것이라는 보장을 받지 못한다.
- 그러므로 객체의 생성과 상관 없이 static 변수에 접근하기 위한 메서드를
만들 필요가 있는데, 메서드의 정의 과정에서 static 키워드를 사용하면
static 자원에 접근하기 위한 메서드를 만들 수 있다.
public class Article {
private static int count;
public static void setCount( int count ) {
Article.count = count;
}
public static int getCount( ) {
return Article.count;
}
}
3-8. static 메서드 사용시의 제약 사항
- 메모리 영역의 차이 때문에 static 메서드는 동적 메모리 영역의
멤버변수를 사용하거나, static이 아닌 일반 멤버함수를 호출할 수 없다.
고정 영역
-> static 변수와 static 멤버함수가 생성된다.
-> 이 영역의 자원들은 프로그램이 실행되는 동안 항상 존재한다.
-> 동적 메모리 영역의 자원들은 항상 존재하는 것이 아니기 때문에
static 멤버함수는 동적 메모리 영역의 멤버변수를 사용하거나,
static이 아닌 일반 멤버함수를 호출할 수 없다.
동적 영역
-> 객체, 객체 안의 멤버변수, 메서드, 메서드가 호출되었을 때 사용되는
지역변수 등이 생성된다.
-> 이 영역의 자원들은 생성과 제거가 유동적으로 반복된다.
-> static 자원은 항상 존재하는 것이므로 동적 영역에서는 static 변수를
활용하거나, static 멤버함수를 호출할 수 있다.
Author And Source
이 문제에 관하여(풀스택 과정 day13_Java), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@doby98/풀스택-과정-day13Java저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)