본문 바로가기

Languages/Java

자바 클래스 활용 - 도형 프로그램 만들기 (수정 및 출력)

이번 글에서는 Java 클래스 예제로

간단한 수정 및 출력 기능 만든 과정을 소개합니다 !


초기 출력화면

 

서브 메서드 출력화면
기능별 메서드 출력 화면

 

클래스를 이용하여 수정과 출력을 하는 예제입니다

이용한 클래스 총 5개입니다

  • 메인 
  • 출력을 위한 Show class
  • 도형들의 정보를 모아둔 Shape class
  • 사각형 정보를 모아둔 Rectangle class
  • 삼각형 정보 Triangle class

 

클래스와  함께 짧은 설명  작성해보았습니다 

 

야매로 그려본 클래스 다이어그램
  • 메인 
메인

 

   설명   
 

  • 무한 루프를 돌며 메인 메서드를 실행함
  • 입력값을 받아 메서드를 호출함,
  • 3 또는 4 입력 show 객체를 함께 같이 파라미터로 넘겨준다
  • 9를 입력시 끝

   짧은 요약   

  • static Scanner : 메인 클래스내에서 전역으로 사용하기 위함.
  • switch - case 문이용 , case마다 break 는 필수
  • isLoop : case = 9 가 아닌이상 계속 반복
  • default : 원치않은 예외 처리
  • show 객체를 재사용하기위해 파라미터를 통해 넘겨주었다.

 


  • 서브 메서드 (reactangle)
reactangle

 

  • 서브 메서드 (triangle)
triangle

 

   설명   
 

  • 무한 루프를 돌며 메인 메서드를 실행함
  • 입력값을 받아 메서드를 호출함
  • 둘레 , 면적설정 , 컬러설정 , 정보확인 메서드 구현
  • 9를 입력시 끝

   짧은 요약   

  • Triangle t  = Triangel.getTrian(); 
             => Triangle 타입의 t 라는 변수에 Triangle 클래스가 가지고있는 getTrian() 리턴 값을 저장한다.
  • tmenu 에서의 입력값 오류 처리를 위해 try catch 문을 사용하였다.
    try로 정상적으로 실행하다가 입력 받을때에 별 이상한 값을 집어 넣으면 catch가 딱 잡아서 가져온다.
    오류 발생시 동작이 멈추게되어 잡고 진행할 수 있도록 nextLine()을 이용하여 버퍼를 비어주었다 
            => 일어나는 오류는 InputMismatchException 이다.
  • 각 case 에 맞게 t 객체에 있는 메서드들을 호출하여 실행한다
  • try / catch 둘 중 하나라도 끝나게 되면 finally를 만나 무조건 실행하고 끝이나게 된다.

 


 

  • 출력을 위한 Show class
Show class

 

   설명   
 

  • 모든 클래스에 반복적으로 들어가는 출력 문장들을 모아두었음
  • 메서드 명으로 가독성을 높임

 

  • 도형들의 정보를 모아둔 Shape class
Shape class

   설명   
 

  • 삼각형과 사각형에 공통적으로 들어가는 메서드와 변수를 만들어두었음
  • shape과 area 메서드는 오버로딩 오버라이딩을 위해 빈 메서드로 생성했음

  짧은 요약   

  • Shape 클래스의 객체는 단독으로 만들지 않는 클래스이다 . 
    Rectangle class / Triangle class 에서 상속받아 생성자를 통해 class 메서드와 변수를 사용한다
  • Shape() 오버로딩 한 이유는 따로 type을 설정하는 메서드를 만들어도 되지만 자식 클래스의 생성자에서
    쓸 내용이 없었기에 생성자끼리 오버라이딩을 해주었다 (뒤에서 더 설명함)
  • area()를 오버라이딩 한 이유는 Rectangle class / Triangle class  서로 다른 계산공식을 가지고 있기에
    자식 클래스 내부에서 재정의 하는 식으로 하였다 .
  • set과 관련된 메서드 내부에서는 this를 사용하였는데 this 는 자기자신 , 여기서는 Shape 클래스가 가지고
    있는 변수를 뜻하게 된다 . (추가로 class 내부 변수들은 파란색 변수명을 보인다)

  • 사각형 정보를 모아둔 Rectangle class
Rectangle class

   설명   
 

  • 야매로 싱글톤 패턴을 사용해보았습니다
    메인에서 객체 생성후 넘겨줄 수도 있지만, 메서드 내에서 
      => 삼각형이나 사각형을 생성 후 width, height , color 등 적용시킨 후 
      => 메인으로 나갔다가 다시 들어와도 같은 객체를 재사용하기 위해서
  • area를 자식 클래스 Rectangle 에서 재정의하여 사용

  짧은 요약   

  • private static Rectangle ins = null : 읽을 수 있게 풀이 하자면
       외부에서 접근이 불가한 전역 Rectangle 타입의 ins 라는 변수에 null 이라는 값을 지정해준것이다 
  • 생성자도 private으로 외부에서 객체 생성을 하지 못 하게 막아두었다
       클래스를 사용하려면 클래스의 인스턴스(객체) 를 만들어야 하는데 원래는 인스턴스 생성은 계속해서 할 수 있지만
       이 글에서는 단 하나의 인스턴스만 있어야 해서 이런 식으로 접근 해보았다 . 이런 것을 싱글톤패턴이라고 부른다
  • 외부에서 객체 생성을 할 때는 원래 new Rectangle(); 이런식으로 했겠지만 생성자를 private 으로 차단해두었기에
    생성을 하려면 Rectangle.getRect() 메서드를 통해 아까 생성한 ins 라는 변수의 값을 확인하여 객체 생성이 되었다면
    ins 인스턴스의 주소를? 넘겨주게된다 
  • area 메서드를 자식 클래스에서 정의하였다 , Rectangle의 area() 와 Triangle 의 area() 메서드는 달라지게 된다

 


  • 삼각형 정보 Triangle class
Triangle class
  •    설명   
    • 야매로 싱글톤 패턴을 사용해보았습니다
      메인에서 객체 생성후 넘겨줄 수도 있지만, 메서드 내에서 
        => 삼각형이나 사각형을 생성 후 width, height , color 등 적용시킨 후 
        => 메인으로 나갔다가 다시 들어와도 같은 객체를 재사용하기 위해서
    • area를 자식 클래스 Triangle 에서 재정의하여 사용
  •   짧은 요약   : 위 Rectangle 요약과 같다

 
 

  하면서 알게된 내용 

  • 클래스 상속 / 오버라이딩 / 오버로딩 
  • 싱글톤 비슷하게 사용해보는 법
  • try catch로 오류가 나도 예외처리로 종료되지 않게 하는 법
  • nextLine() 으로 입력값을 받아서 한 글자씩 버퍼에 저장함 
  • 이래도 되는지는 모르지만 메서드 파라미터에 변수가 아닌
    Scanner 메서드를 바로 넣어 사용해보니까 실행이 됐음 이건 확인 해봐야할듯함 

 

더보기

// 전체코드 

package JavaCode;

import java.util.InputMismatchException;
import java.util.Scanner;

public class ClassTest {

static Scanner sc = new Scanner(System.in);

public static void main(String[] args) {

boolean isLoop = true;
while (isLoop) {
Show show = new Show();
int menu = sc.nextInt();

switch (menu) {

case 3:
triangle(show);
break;
case 4:
rectangle(show);
break;
case 9:
isLoop = false;
break;
default:
System.out.println("유효하지 않은 입력값입니다.");
}
}
}

static void triangle(Show s) {
// 삼각형 싱글톤 인스턴스 생성
Triangle t = Triangle.getTrian();

boolean isRunning = true;

while (isRunning) {

s.showTriangleMenu();
try {
int tMenu = sc.nextInt();

switch (tMenu) {
case 1:
s.showChangeShape();
t.setChangeShape(sc.nextDouble(), sc.nextDouble());
t.area();
break;
case 2:
s.showChangeColor();
sc.nextLine();
t.setChangeColor(sc.nextLine());
break;
case 3:
t.getShowInfo();
break;
case 9:
System.out.println("triangle 메서드 종료");
isRunning = false;
return;
default:
System.out.println("유효하지 않은 입력값입니다.");
}
} catch (InputMismatchException e) {
System.out.print("입력 오류발생 ! : ");
System.err.println(e);
sc.nextLine();
} finally {
System.out.println("========================");
}
}
}

static void rectangle(Show s) {
// 사각형 싱글톤 인스턴스 생성
Rectangle t = Rectangle.getRect();

boolean isRunning = true;

while (isRunning) {

s.showRectangleMenu();
// 잘못된 값이 들어올 때 InputMismatchException 오류가 발생하는 것을 확인
// try문을 사용해보고 싶어서 try / catch / finally 사용
try {
int rMenu = sc.nextInt();
switch (rMenu) {
case 1:
s.showChangeShape();
t.setChangeShape(sc.nextDouble(), sc.nextDouble());
t.showRectangle();
break;
case 2:
t.area();
break;
case 3:
s.showChangeColor();
sc.nextLine();
t.setChangeColor(sc.nextLine());
break;
case 4:
t.getShowInfo();
break;
case 9:
System.out.println("Rectangle 메서드 종료");
isRunning = false;
return;
default:
System.out.println("유효하지 않은 입력값입니다.");
}
} catch (InputMismatchException e) {
// nextLine()을 사용하면 한 글자씩 버퍼에 저장을 하기 때문에
// 잘못된 값이 들어오면 비어줘야 해서 
// catch시 nextLine() 으로 비어주었다
System.out.print("오류발생 !!! : ");
System.err.println(e);
sc.nextLine();
} finally {
System.out.println("========================");
}
}
}
}

//shape 상속을 받은 사각형 클래스
class Rectangle extends Shape {

/*
 * 정처기를 하며 공부한 ,,, 디자인 패턴 중 딱 알고있는 코드 싱글턴 패턴을 적용해보았습니다.
 */

private static Rectangle ins = null;

// 생성자를 private 를 적용하여 외부에서 생성하지 못 하게 막아뒀음
private Rectangle() {
super("사각형");
}

/*
 * 왜 싱글톤을 적용시켜 보았는가 => 메인에서 객체 생성후 넘겨줄 수도 있지만, 메서드 내에서 
 * => 삼각형이나 사각형을 생성 후 width, height , color 등 적용시킨 후 
 * => 메인으로 나갔다가 다시 들어와도 같은 객체를 재사용하기 위해서
 * 
 * 사실 그냥 한 번 적용시켜 보고싶었습니다
 * 
 * 메인 메서드에서 객체 생성을 하지 않고 직접 클래스내에 이 메서드를 호출하여 
 * 1회만 객체 생성하여서 같은 객체만 사용하게 했음
 */
public static Rectangle getRect() {
if (ins == null) {
ins = new Rectangle();
}
return ins;
}

// 둘레
void showRectangle() {
System.out.println((height + width) * 2);
}

// 면적 (오버라이딩)
void area() {
System.out.println(height * width);
}
}

//shape 상속을 받은 삼각형 클래스
class Triangle extends Shape {

// singleton
private static Triangle ins = null;

private Triangle() {
super("삼각형");
}

public static Triangle getTrian() {
if (ins == null) {
ins = new Triangle();
}
return ins;
}

// 면적 (오버라이딩)
public void area() {
System.out.println(height * width / 2);
}

}

class Shape {
String type;
double height;
double width;
String color = "white";

// 생성자
public Shape() {}
// 생성자 (오버로딩)
public Shape(String type) {
this.type = type;
}

void area() {}
// 변수 값 재설정
public void setChangeShape(double height, double width) {
this.height = height;
this.width = width;
}
// 변수 값 재설정
void setChangeColor(String color) {
this.color = color;
}
// 변수 값 보여주기
void getShowInfo() {
System.out.println("type : " + type);
System.out.println("height : "+ height);
System.out.println("widht : " + width);
System.out.println("color : " + color);
}
}

class Show {

public Show() {
System.out.println("==== 도형 프로그램 =====");
System.out.println("3. 삼각형");
System.out.println("4. 사각형");
System.out.println("9. 프로그램 종료");
System.out.print("#사용자 : ");
}

void showChangeShape() {
System.out.println("=== 세부 사항 입력 ===");
System.out.println("=== height , width===");
System.out.print ("#사용자 :");
}

void showChangeColor() {
System.out.println("=== 세부 사항 입력 ===");
System.out.println("=== color ===");
System.out.print("#사용자 :");
}

void showTriangleMenu() {
System.out.println("1. 삼각형 면적 지정하기");
System.out.println("2. 삼각형 색칠하기");
System.out.println("3. 삼각형 정보 확인");
System.out.println("9. 메인으로");
System.out.print("#사용자 : ");
}

void showRectangleMenu() {
System.out.println("1. 사각형 둘레 지정하기");
System.out.println("2. 사각형 면적 확인하기");
System.out.println("3. 사각형 색칠하기");
System.out.println("4. 사각형 정보 확인");
System.out.println("9. 메인으로");
System.out.print("#사용자 : ");
}
}

 

내가 생각하는 클래스의 형태로 만들어보았는데 

 

이게 맞는지 아닌지는 나도 모르겠다 !!!

 

아니면 다시 알아가면 되니까요 ~!