1. 아래의 접근제한자에 대하여 설명하시오.
- private
- protected
- default
- public
- 접근 강도: public < protected < default < private
- private: 자기 클래스 내부에서만 접근 가능한 접근제한자.
- proteted: 자기 패키지내에서만 접근 가능한 접근제한자. 외부 패키지에서는 호출만 가능하다.
- default: 접근 제한자를 따로 설정하지 않았을 때 자동지정되는 접근제한자. 자기 패키지내에서만 접근 가능하다.
- public: 자기 혹은 다른 패키지까지 모두 접근가능한 접근제한자.
2. 지역변수에 접근제한자를 붙이지 않는 이유는?
: 지역 변수의 특성상 메소드 내에서 선언되고 값이 초기화가 되기 때문에 해당 범위내에서만 메모리가 움직이는 특성을 가진다. 그런데 여기서 접근제한자를 통해 해당 정보를 은닉하면 값을 참조할 수 없기에 이를 따로 붙이지 않는다.
3. 캡슐화에 대하여 설명하시오.
3-1. 정의
: 메인에서 생성자를 통해 객체를 생성할 때 기능을 그대로 가져오되 해당 로직(소스코드)을 볼 필요 없이 구현하는 것.
3-2. 캡슐화의 의의
: 메인에서 해당 클래스가 아닌 속하는 메소드를 가져와서 출력하기에 보안성 및 사용성에 초점을 둔다.
// 캡슐화를 사용하지 않을 때
public class SubOne {
public void subFirst { ... }
public class SubTwo {
public void subSecond { ... }
}
public class Main {
public static void main(String[] args) {
SubOne sub1 = new SubOne();
SubTwo sub2 = new SubTwo(); // 객체를 따로 생성해야 하므로 메모리 낭비를 하게 된다.
sub1.subFirst();
sub2.subSecond(); // 비슷한 성질을 가진 기능을 각각 다른 클래스에서 호출해야 하므로 가독성이 떨어진다.
}
}
// 캡슐화를 사용할 때
public class Sub {
public void subFirst { ... }
public void subSecond { ... }
}
public class Main {
public static void main(String[] args) {
Sub sub = new Sub(); // 객체를 한 번만 생성할 수 있어, 메모리를 아낄 수 있다.
sub.subFirst();
sub.subSecond(); // 비슷한 성질을 가진 여러 메소드들을 한 클래스에서 호출할 수 있기에 가독성이 향상된다.
}
}
4. 랜덤 숫자 맞추기 게임을 짜시오.
4-1. 랜덤 숫자 맞추기 메인 클래스
import java.util.Random;
import java.util.Scanner;
public class UADMain {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Random random = new Random();
int com = random.nextInt(50) + 1; // 컴퓨터가 숫자 선정
int cnt = 0; // 기회 카운트
while (cnt < 10) { // 10번 기회내에 숫자를 맞추지 못하면 게임종료.
System.out.print("1부터 50까지의 숫자를 입력해주세요: ");
int user = scanner.nextInt();
UAD uad = new UAD(user, com);
uad.setUser(user);
uad.setCom(com);
if (uad.getResult() == 0) { // 정답 체크
System.out.println("정답입니다!");
break;
} else if (uad.getResult() == 1) {
System.out.println("틀렸습니다. UP!");
cnt ++;
continue;
} else if (uad.getResult() == 2) {
System.out.println("틀렸습니다. DOWN!");
cnt ++;
continue;
}
}
System.out.println();
System.out.println("GAME OVER!");
scanner.close();
}
}
4-2. 랜덤 숫자 맞추기 알고리즘 클래스
public class UAD {
private static int com; // 값이 새로 초기화되지 않고 매 번 참조만 하기 때문에 클래스 변수
private int user; // 값이 새로 초기화되어 매 번 참조를 하기 때문에 인스턴스 변수
public UAD(int user, int com) {
this.user = user;
UAD.com = com;
}
public int getUser() {
return user;
}
public boolean setUser(int user) { // 입력 값 유효성 검사
this.user = user;
Integer wnum = new Integer(user); // int -> Integer로 박싱하여 객체 비교
if (!(wnum instanceof Integer)) {
System.out.println("올바르지 않은 숫자 값 입니다. 다시 입력해주세요.");
return false;
} else {
return true;
}
}
public int getCom() {
return com;
}
public void setCom(int com) {
UAD.com = com;
}
public int getResult() {
int result = 0;
if (user < com) { // UP
result = 1;
} else if (user > com) { // DOWN
result = 2;
} else if (user == com) { // CORRECT
result = 0;
}
return result;
}
}
5. static 변수의 다른 용어 3가지는?
- 클래스 변수
- 정적 변수
- 공유 변수
6. 자바의 메모리 영역을 3가지로 나누고, 해당 영역에 들어가는 정보를 말하여 보시오.
: JVM(Java Virtual Machine)의 메모리 영역은 Method Area, Call Stack, Heap으로 나뉜다.
- Method Area(메소드 영역)메인 클래스에서 프로그램 실행 중 ‘.class’ 파일을 분석하는 JVM이 클래스에 대한 정보를 저장하는 곳으로 클래스 변수를 선언 했을 경우 이 또한 포함하여 Method Area에 저장된다.
- Call Stack(호출 스택)메소드 작업에 필요한 메모리 공간을 제공하는 곳으로 메소드 호출시 해당 공간에 호출된 메소드를 위한 메모리가 할당되어 메소드가 작업을 수행하는 동안 지역변수 및 매개변수들과 연산의 중간 결과 등을 저장하는데 사용된다. 또한 메소드가 작업을 마치면 할당 되었던 메모리 공간은 가비지 컬렉션(Garbage Collection)에 의해 반환(pop)되어 버려진다.
- Heap(힙)인스턴스가 생성되는 공간으로 프로그램 실행 중 생성되는 모든 인스턴스가 이곳에 생성된다.
7. static 변수의 접근 방법은?
: main 메소드에서 최초로 생성자에 따라 객체를 할당할 때, static 키워드로 모든 인스턴스가 공유되어 이후 계속 객체가 생성되어도 지속적으로 참조를 할 수 있는 특성을 지닌다.
// 메인 클래스
class ClassVar {
public static void main(String[] args) {
InstSnt cnt1 = new InstCnt();
InstSnt cnt1 = new InstCnt();
/*
인스턴스 생성 : 1
인스턴스 생성 : 2
*/
}
}
// InstSnt 클래스
class InstCnt {
private static int instNum = 0; // 클래스 변수(여기서 static이 없으면 인스턴스 변수가 된다.)
InstCnt() {
instNum ++;
System.out.println("인스턴스 생성 : " + instNum);
}
}
단, static 변수(클래스 변수)는 생성자를 통해 초기화를 해선 안된다.
// 메인 클래스
InstCnt.instNum -= 15; // '.instNum'을 통해 클래스 변수로 바로 접근한다.
// '-= 15'를 하면 값이 리셋되지 않고(참조) 연산하여 출력된다.
//InstCnt 클래스
static int instNum = 100; // 클래스 변수 선언.
8. 클래스 변수의 활용의 예를 드시오.
8-1. 값의 참조가 목적인 변수
// 생성자를 통해 객체를 여러개 할당하여도 값은 공유되어 새로 초기화 되지 않는다.
// 참조 횟수가 많은 경우, 메모리의 낭비를 막기위해 클래스 변수로 생성한다.
static double classVar = 10;
8-2. 값의 공유가 목적인 변수
static double PI = 3.14; // 변동되지 않는 값을 공유할 때 사용할 수 있다.
9. 스태틱 함수에 인스턴스 변수가 올 수 없는 이유는?
: 스태틱 함수(Static Method)의 특성상 객체의 생성 없이 호출이 가능하나 객체에서는 호출을 할 수 없다.
그 이유는 JVM 메모리 구조에서 스태틱 함수(클래스 함수)가 Method Area에 먼저 생성되고
인스턴스 변수는(메소드도 포함) 생성자에 의해 객체가 생성되는 시기(Heap에서 인스턴스가 생성될 때)에 생성 되므로 둘의 생성 시기가 달라(서순이 안맞아) 접근이 불가능하다.
따라서, 스태틱 함수인 main 메소드에 객체를 통해 호출해야 하는 인스턴스 변수의 특성상 이를 불러오면 컴파일 에러가 난다.
class Main {
public static void main(String[] args) {
InstCnt instCnt = new InstCnt();
System.out.prinln(instCnt.instNum); // 컴파일 에러!
}
}
class InstCnt {
int instNum = 10; // 인스턴스 변수
InstCnt(int instNum) {
this.instNum = instNum;
}
}
10. 아래의 프로그램을 작성 하시오.
다음 멤버를 가지고 직사각형을 표현하는 Rectangle 클래스를 작성하라.
- int 타입의 x, y, width, height 필드: 사각형을 구성하는 점과 크기 정보. x, y, width, height 값을 매개변수로 받아 필드를 초기화하는 생성자
- int square() : 사각형 넓이 리턴
- void show() : 사각형의 좌표와 넓이를 화면에 출력
- boolean contatins(Rectangle r) : 매개변수로 받은 r이 현 사각형 안에 있으면 true 리턴
10-1. 추상화
: 여러 시작 점을 기준으로 길이에 맞는 사각형들을 그린 뒤 이를 포함하는지의 여부를 구현하는 문제이다.
따라서, 점 p1과 점 p2간 유클리드 거리(Euclidean Distance)를 도출하여 이에 대한 판별식을 두고 중첩이 되는지 확인한다.
10-2. 사각형 메인 클래스
public class RectangleMain {
public static void main(String[] args) {
Rectangle r = new Rectangle(2, 2, 8, 7);
Rectangle s = new Rectangle(5, 5, 6, 6);
Rectangle t = new Rectangle(1, 1, 10, 10);
r.show();
System.out.println("s의 면적은 "+s.square());
if(t.contains(r)) System.out.println("t는 r을 포함합니다.");
if(t.contains(s)) System.out.println("t는 s를 포함합니다.");
}
}
10-3. 사각형 알고리즘 클래스
public class Rectangle {
private int x, y, width, height;
Rectangle(int x, int y, int width, int height) {
this.x = x; this.y = y; this.width = width; this.height = height;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y= y;
}
public void setWidth(int width) {
this.width= width;
}
public void setHeight(int height) {
this.height = height;
}
public int square() {
return width*height;
}
public void show() {
System.out.println("(" + x + "," + y + ")에서 크기가 " + width + " X "+ height + "인 사각형");
}
private double eucDis(Rectangle r) { // 유클리드 거리
return Math.sqrt(Math.pow(Math.abs(r.x-x), 2) + Math.pow(Math.abs(r.y-y), 2));
}
public boolean contains(Rectangle r) { // 판별식을 통해 true 혹은 false로 리턴 값 도출
boolean result = true;
if ((eucDis(r) <= height) && (eucDis(r) <= width)) {
result = true;
} else if (eucDis(r) <= (Math.sqrt(Math.pow(height, 2) + Math.pow(width, 2)))) {
result = true;
} else {
result = false;
}
return result;
}
}
'WebDev > 본과정' 카테고리의 다른 글
String 클래스의 메소드 및 배열 기초 (0) | 2021.05.12 |
---|---|
오버로딩과 String (0) | 2021.05.11 |
패키지와 접근제한자 (0) | 2021.05.11 |
클래스의 생성자 (0) | 2021.05.11 |
메소드 심화 및 클래스 기초 (0) | 2021.04.30 |
최근댓글