인터페이스는 콤마( , ) 로 연결하여 여러 개를 동시에 상속 받을 수 있다.
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.count = 5;
Artilce.category = "공지사항";
Article 클래스 내부에서 접근하는 경우
count = 6;
cetegory = " 공지 사항";
클래스에서 정의하는 일반 메서드들은 객체의 생성과 동시에 동적 메모리 영역에서 활성화 된다.
-> 동적 메모리 영역의 입장에서는 고정 메모리 영역의 자원들은 항상 존재한다.
-> 고정 메모리 영역의 자원들은 동적 메모리의 자원들이 항상 존재하는 것이라는 보장을 받지 못한다.
그러므로 객체의 생성과 상관 없이 static 변수에 접근하기 위한 메서드를 만들 필요가 있을 때,
메서드의 정의 과정에서 static 키워드를 사용하면 static 자원에 접근하기 위한 메서드를 만들 수 있다.
public static void setCount( int count ) {
Article.count = count;
}
메모리 영역의 차이 때문에 static 메서드는 동적 메모리 영역의 멤버변수를 사용하거나, static이 아닌
일반 멤버함수를 호출할 수 없다.
package staticobject;
//하나의 게시물을 표현하기 위한 JavaBeans
public class Article {
/*
* static은 모든 객체가 공유하는 값이다. static값은 클래스 이름을 통해서
* 접근해야 하며, 객체의 생성 여부에 상관 없이 사용이 가능하다.
*/
//전체 게시물의 수를 표현하기 위한 데이터
private static int count = 0;
// 모든 게시물은 하나의 카테고리 안에 존재한다고 가정한다.
// 게시물의 분류를 구별하기 위한 데이터
private static String category;
private int num; // 글 번호
private String title; // 글 제목
private String regDate; // 작성일자
public Article(int num, String title, String regDate) {
super();
this.num = num;
this.title = title;
this.regDate = regDate;
/*
* 이 클래스에 대한 객체 생성 -> 게시물 신규 등록
* 게시물이 새로 등록될 때 마다, 전체 글 수를 의미하는
* count 변수가 1씩 증가한다.
* 전체 게시물 수는 모든 객체가 공유하는 값이므로,
* static으로 생성되어야 한다.
*/
count++;
}
public static int getCount() {
return count;
}
public static void setCount(int count) {
Article.count = count;
}
public static String getCategory() {
return category;
}
public static void setCategory(String category) {
Article.category = category;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getRegDate() {
return regDate;
}
public void setRegDate(String regDate) {
this.regDate = regDate;
}
@Override
public String toString() {
return "글 분류 = " + category
+ ", 전체 글 수 = " + count
+ ", Article [num= "+ num
+ ", title=" + title
+ ", regDate=" + regDate + "]";
}
}
package staticobject;
public class Calc {
// ------------------------ 싱글톤 객체 생성을 위한 준비 시작
/*
* static이 적용된 자원은 메모리의 고정영역에 생성되기 때문에, 클래스
* 자체의 객체나, 그 안에 포함된 멤버변수, 메서드와는 메모리 상에서 구별된다고 볼 수 있다.
* 그러므로 Calc 클래스 안에 static 형태로 Calc 클래스의 객체를 정의하더라도
* 코드상의 논리적인 연관관계를 위해 하나의 파일에서 정의하는 것일 뿐, 실제로는
* Calc 클래스 자체어서 독립된 객체가 되는 것이다.
* Calc 클래스 이외의 여러 곳에서 new 연산자를 사용해 객체 할당이 가능하다면
* SingleTon이라는 개념 자체가 성립되지 않으므로, 외부에서 이 객체에 직접적인
* 접근을 못하도록 은닉시킨다.
*/
private static Calc current;
//객체가 할당되지 않은 경우에만 할당하도록 하여 중복 할당을 방지한다.
public static Calc getInstance() {
if ( current == null ) {
current = new Calc();
}
return current;
}
// 객체에 null을 대입하면 메모리에서 삭제된다.
public static void freeInstance() {
current = null;
}
// 기본 생성자를 private 형태로 정의하면 객체 생성자가 은닉처리되어
// 외부에서 new 연산자를 사용한 객체할당이 금지된다.
private Calc() { }
//------------------------- 싱글톤 객체 생성을 위한 준비 끝
public int plus ( int x, int y ) {
return x + y;
}
public int minus ( int x, int y ) {
return x - y;
}
}
package staticobject;
public class Main01 {
public static void main(String[] args) {
Article.setCategory("자유게시판");
Article a1 = new Article(1, "첫번째 게시물", "2022-08-18");
Article a2 = new Article(2, "두번째 게시물", "2022-08-19");
Article a3 = new Article(3, "세번째 게시물", "2022-08-20");
System.out.println(a1.toString());
System.out.println(a2.toString());
System.out.println(a3.toString());
System.out.println("---------------------");
Article.setCategory("공지사항");
System.out.println(a1.toString());
System.out.println(a2.toString());
System.out.println(a3.toString());
}
}
package staticobject;
public class Main02 {
public static void main(String[] args) {
// Calc c1 = new Calc();
// int a = c1.plus(20, 10);
//
// Calc c2 = new Calc();
// int b = c1.minus(20, 10);
// Calc c3 = new Calc();
// int c = c3.plus(20, 10);
// int d = c3.minus(20, 10);
/*
* 싱글톤 객체 사용하기
* - getInstance() 메서드를 사용하여 객체를 리턴받는 형식으로 사용한다.
* - 여러 객체를 리턴받더라도 모두 하나의 static 객체를 참조하게 되기 때문에
* 전역 객체 하나만이 메모리에 할당되게 된다.
*/
Calc c = Calc.getInstance();
int e = c.plus(20, 10);
System.out.println(e);
System.out.println( Calc.getInstance().minus(20, 10));
}
}