오늘은 JAVA에서 클래스, 인스턴스 변수들을 안전하게 사용하기 위한 접근 제어를 공부했다.
정보은닉이란?
-> 외부에서 인스턴스의 변수에 직접적인 접근을 막는 것이다.
방법은 변수 앞에 private을 선언하는 것이다. 그렇게 되면 그 변수는 그 인스턴스 안의 메소드를 이용해서만 접근 할 수 있다.
* 프로그램의 안전성을 높이기 위해 인스턴스 변수는 가급적 private으로 선언하자.
이러한 정보은닉은 접근제어 지시자를 통해 이루어진다.
접근제어 지시자는 private, public, protected, default 가 있다.
private는 위에서 말한 것처럼 외부에서 건들지 못하게 하는 것이고
public은 아무데서나 사용할 수 있도록 한다. 그래서 메소드에는 public을 많이 쓴다.
default는 변수 앞에 아무것도 적지 않았을 때인데 동일 패키지 내에서의 접근까지 허용한다.
protected 개념은 상속 개념을 이해해야하는데,
상속받은 클래스안의 변수를 이어받을 수 있다. private으로 선언된 변수가 있는 클래스를 상속 받았다면 그 속에 있는 그 변수는 사용하지 못하는 것이다. 하지만 protected로 선언된 변수는 상속 받고 난 후도 사용할 수 있다. 물론 외부에서 접근은 허용하지 않는다.
그렇다면 class에는 public? default? private? 어떤걸 사용할까??
상식적으로 private를 사용해 class를 선언한다면 왜 선언하는 걸까? 외부에서 접근을 못하므로 외부에서 인스턴스 생성을 허용하지 않는다. 사용하지 못하는 class가 될 뿐이다. 즉 class에서 private는 사용하지 않는다.
public으로 선언하면 어디서든 인스턴스 생성이 가능하다. 하지만 조건이 있다.
1. 하나의 소스파일에는 하나의 클래스만 public으로 선언해야한다.
2. public 클래스의 이름과 소스파일의 이름은 완전히 일치해야 한다.
-> 보통 외부로 노출시키고 싶은 class에 public을 붙인다.(라이브러리생성시)
캡슐화
-> class로 감싸는 것을 의미한다. 이 캡슐화는 정답이란 것이 없고 필요한 상황에 맞게 class 안에 필요한 메소드나 변수들을 구성하는 것이다.
문제 9-2
원을 의미하는 클래스를 정의하고 Circle 클래스 좌표 정보와 반지름길이 정보를 저장할 수 있게 한다. Ring 클래스도 정의한다. Ring 클래스는 내부원 외부원으로 구성된다.
public static void main(String[] args)
{
Ring ring=new Ring(1, 1, 4, 2, 2, 9);
ring.showRingInfo();
}
위 main 메소드를 이용해 링의 정보를 출력한다.
먼저 각 클래스 Circle, 클래스 Ring을 설계하고 위 main 메소드에 맞추어 설계하였다.
작성한 코드는 아래와 같다.
class Point
{
int xPos, yPos;
public Point(int x, int y)
{
xPos = x;
yPos = y;
}
public void showPointInfo() { System.out.println("["+xPos+", "+yPos+"]");}
}
class Circle
{
Point posit;
int r;
public Circle(int xi, int yi, int ri)
{
posit = new Point(xi, yi);
r = ri;
}
public void showCircleInfo()
{
System.out.println("radius : " + r);
posit.showPointInfo();
}
}
class Ring
{
Circle inner;
Circle outter;
public Ring(int x1, int y1, int r1, int x2, int y2, int r2)
{
inner = new Circle(x1, y1, r1);
outter = new Circle(x2, y2, r2);
}
public void showRingInfo()
{
System.out.println("Inner Circle Info...");
inner.showCircleInfo();
System.out.println("Outter Circle Info...");
outter.showCircleInfo();
}
}
class Problem92
{
public static void main(String[] args)
{
Ring ring = new Ring(1, 1, 4, 2, 2, 9);
ring.showRingInfo();
}
}
---------------------------------------------------------------------------------------------
위 코드의 결과로
(결과 화면)
아래와 같이 나왔다.
외부 원과 내부 원의 정보를 화면에 출력하였다.
클래스 변수, 클래스 메소드
static 선언이란?
-> static으로 선언된 변수는 변수가 선언된 클래스의 모든 인스턴스가 공유하는 변수다.
즉, static은 딱 하나만 존재하는 변수다.
모두 여기에 접근을 해서 사용하는 것이다.
그렇다면 접근 방법은 어떻게 할까??
방법은 3가지가 있다.
1. 내부에서 접근 : 다른 변수와 똑같이 다룬다.
2. 참조변수를 통한 접근 : 참조변수.변수
3. 클래스 이름을 통한 접근 : 클래스이름.변수
static 변수는 언제 초기화 될까?
-> static변수는 인스턴스를 생성하기도 전에 이미 메모리에 올라가 있다. 자바 가상머신에 올라가면서 static 변수는 초기화된다.
* static변수가 초기화되는 시점은 JVM에 의해서 클래스가 메모리 공간에 올라가는 순간이다.
* “그래서 static변수를 생성자를 통해서 초기화하는 실수를 범하면 안된다."
static을 메소드에 적용하게 되면??
인스턴스를 생성하지 않아도 static 메소드를 호출 할 수 있다.
static은 클래스가 메모리에 올라가는 순간 시작 되므로
인스턴스를 생성하지 않아도 바로 쓸수 있다.
보통 쓴다면 외부에서 쓰기 때문에
public과 같이 쓴다.
메소드 오버로딩은 무엇일가?
메소드 오버로딩이란
결론은 메소드 이름이 같아도 괜찮다.
다만, 메소드 이름이 같더라도 매개변수는 달라야한다.
매개변수가 다르다면
메소드 오버로딩으로 이름이 같아도 괜찮다.
(*생성자도 오버로딩이 가능하다.)
오버로딩의 중요성은 여기에 있다.
생성자도 오버로딩이 가능하다는 것이다.
그렇게 되면 이
생성자의 오버로딩으로 선언된 하나의 클래스로 다양한 형태의 인스턴스 생성이 가능하다.
생성된 오버로딩의 중복되는 내용은 this 라는 키워드를 사용해 해결한다.
(이와 관련된 예시는 단계별 프로젝트에서 진행하였다.)
String 클래스
-> 문자열 클래스다.
다만 C언어와 다른점은 String 클래스의 문자열은 바꿀수 없다..
또 같은 문자열이라면 기존에 있던 문자열을 같이 사용한다.
다시말하면 문자열은 상수형이다 처음 입력되는 값이 유지된다고 생각하면 된다.
* "문자열이 동일한 경우에는 하나의 String 인스턴스만 생성해서 공유하도록 한다"
문자열을 조금 유연하게 다루고 싶다면
StringBuilder 혹은 StringBuffer 클래스를 이용하는 것이 좋다.
문자열을 복사하는 법 (자바에서)
(하지만 자바에서는 문자열을 직접 복사할 필요를 못 느낄만큼 다른 것들을 많이 지원해 주고 있다.)
(문자열에 관한 예시도 다음 단계별 프로젝트에서 같이 진행하겠다.)
(* 참조 - 난 정말 JAVA를 공부한 적이 없다구요, 윤성우)
'Programing > JAVA 일지' 카테고리의 다른 글
| JAVA(7일차) - (1) 콘솔 입력, 출력, 배열 (0) | 2016.12.08 |
|---|---|
| JAVA(6일차) - (2) 전화번호 관리 프로그램1 (0) | 2016.12.08 |
| JAVA(5일차) - (2) 클래스 패스, 패키지 (0) | 2016.12.07 |
| JAVA(5일차) - (1) 클래스와 인스턴스 (0) | 2016.12.07 |
| JAVA(4일차) - 메소드, Recursive 메소드 (0) | 2016.12.06 |