본문 바로가기
코딩수업/AWS 클라우드환경 네이티브

8/9 자바(Java) 오버라이딩, GUI 맛보기, toString

by 인생즐겜러 2022. 8. 9.
728x90
반응형

AWS 클라우드환경 네이티브 수업 58일차

 

 

 

진행

1. 자바 클래스 활용 연습

(도형 그리기, 카드)

2. 오버라이딩

3. 클래스 연습문제

 

 

 

 

 

요약

1. 오버라이딩

2. Java GUI 맛보기

3. toString

 

 

 

 

 


 

 

 

 

 

오버라이딩

 

메소드 이름은 같고 매개변수만 다르게 메소드를 추가하는 오버로드와는 다르게

오버라이딩은 메소드의 동작만을 재정의 한다.

즉, 메소드 수정을 한다.

그렇기 때문에 클래스의 상속을 하고

그 후 메소드의 반환 타입, 메서드 이름, 매개 변수을 부모 클래스의 메소드와 같게 해야 한다.

 

접근 제한자 => 부모 클래스의 메소드보다 같거나 더 넓은 범위로만 지정 가능.

예외 클래스 => 부모 클래스의 메소드보다 같거나 더 좁은 범위로만 지정 가능.

 

자식 클래스는 부모 클래스의 private 멤버를 제외한 모든 것을 갖추고 있는 걸 잊지 말자.

 

구조는 아래와 같다.

 

클래스 상속 {
	@Override
	동일자료형 동일변수명(동일 매개변수){
		재정의하고자하는 기능
	}
}



예시.

public Class Parent {
  int CalCul(int num){ // 부모의 메소드
    return num;
 }
}
public Class Child extends Parent {
 @Override
 int CalCul(int num) { // 메소드 재정의
   System.out.print("이것이 " + num + ", 자식 메소드임");  
 }

  public static void main(String[] args) {
   Child ch = new Child();
   ch.CalCul(5); //오버라이딩된 자식 객체의 메소드 CalCul이 호출됨
}
}



결과
이것이 5, 자식 메소드임

 

 

 

 

 


 

 

 

 

 

자바 클래스 활용 연습

- 도형 그리기

 

자바 그래픽 메소드를 써야 도형을 그릴 수 있는데

이를 위한 최소한의 기본개념을 하나 읊고 코드를 보자.

 

 

 

1. 좌표계

좌표로 그림을 그릴 시 기준은 다음과 같다.

 

- 원점은 화면의 좌측 상단에 존재

- x좌표 값은 오른쪽으로 갈수록 증가

- y좌표 값은 아래로 갈수록 증가

(좌표 값에 소수점은 없고 오직 양의 정수만 있다.)

 

 

 

2. 선

- Graphics 클래스에 있는 drawLine() 메소드를 사용

- 선의 시작하는 점의 좌표 (x1, y1) 끝나는 점의 좌표(x2, y2)가 매개변수로 들어간다. 
  예를 들면 이런 모양이다.

   void drawLine(int x1, int y1, int x2, int y2) 

 

 

 

package object;

import javax.swing.JFrame;
import java.awt.Graphics;

class Point{
	
	int x;
	int y;
	
	Point(int x, int y){
		this.x = x;
		this.y = y;
	}

	Point(){
		this(0,0);
	}
}

// 원 클래스
class Circle{
	Point	center;
	int		r;
	
	Circle(){
		this(new Point(0,0), 100);
	}

	Circle(Point center,  int r){
		this.center = center;
		this.r		= r ;
	}
}

// 삼각형 클래스
class Triangle{
	Point[] p = new Point[3];
	
	Triangle(Point[] p) {
		this.p = p;
	}

	Triangle(Point p1, Point p2, Point p3 ) {
		p[0] = p1;
		p[1] = p2;
		p[2] = p3;
	}
}



public class Lecture extends JFrame {

	public static void main(String[] args) {
		Lecture win = new Lecture("도형 그리기");
		win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			
	}
	
	// paint 사용
	public void paint(Graphics g ) {
		
		Point[] p = {
				new Point(100, 100),
				new Point(140, 50),
				new Point(200, 100)
		};
		Triangle	t = new Triangle(p);
		Circle		c = new Circle(new Point( 100, 100), 500);
		
        
       
		// 원을 그린다.
		// 왼쪽 상단 센터점을 잡고 오른쪽과 아래로의 범위를 잡는다.
		g.drawOval(c.center.x, c.center.y, c.r, c.r);
		
        
		
		// 직선 3개로 삼각형을 그린다. 각 직선의 좌표는 시작점과 끝점이다.
		g.drawLine(t.p[0].x, t.p[0].y, t.p[1].x, t.p[1].y );
		g.drawLine(t.p[0].x, t.p[0].y, t.p[2].x, t.p[0].y );
		g.drawLine(t.p[2].x, t.p[0].y, t.p[1].x, t.p[1].y );
		
	}
	
	Lecture(String title){
		super(title);
		setLocation(200, 100);
		setSize(700, 700);
		setVisible(true);
	}
}

 

결과는 아래와 같다.

 

 

 

 

 

 

 


 

 

 

 

 

※ 참고 1 - awt.Graphics  / swing.JFrame

이런 게 있다~ 정도만 알고 넘어갈 것.

 

위의 예에서 import가 된 아래의 두 개가 무엇인지 알아보자.

 

java.awt.Graphics

javax.swing.JFrame

 

 

 

AWT 와 Swing 모두 Java의 GUI 프레임워크를 말한다.

AWT GUI는 자바 GUI 의 시조새 같은 존재고 Swing은 나중에 나온만큼 훨씬 쓸만하도록 설계되어 있다.

 

AWT 는 비트맵 이미지 형식으로 그려지고
프레임상에서 컴포넌트가 아닌 그림적인 요소를 지정한다.

 

Graphics의 기능은 아래와 같다.

색상 선택하기

문자열 출력

도형 그리기

도형 칠하기

이미지 출력

클리핑

문자열 그리기

void drawString(String str, int x, int y)

(x,y) 영역에 str 문자열 그리기

현재 색과 현재 폰트로 출력

 

JFrame은 윈도우창을 제공해주는 클래스다.

 

 

 

 

 


 

 

 

 

 

※참고 2 - win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)

이런 게 있다~ 정도만 알고 넘어갈 것.

 

JFrame 사용 시 거의 따라가는 메소드이다.

이것을 사용하지 않았을 시에는 JFrame 으로 윈도우창(그림 그리는 창)을 x로 닫기를 해도

눈에만 안보이지 프로세스에는 남아있다.하지만 이 메소드에 괄호 안 필드 값까지 넣은 것을 사용하면 종료 시 프로세스까지 종료시킬 수 있다.

 

 

 

 

 

 


 

 

 

 

 

※참고 3 - public void paint(Graphics g )

이런 게 있다~ 정도만 알고 넘어갈 것.

 

그래픽 출력 이벤트는 그림을 그리려 할 때 발생하는 이벤트를 말한다.

이 그래픽 이벤트가 발생할 때 호출하는 메소드가 바로 paint() 메소드.

실제 그림을 그리는 것은 paint() 메소드의 매개변수를 통해 전달되는 Grphics 객체다.

 

 

 

 

 

 

 


 

 

 

 

 

toString

 

모든 클래스의 가장 최상위 클래스는 무조건 Object 클래스이다.

어떤 클래스를 만들던지 자바 컴파일러가 그렇게 만든다.

 

toString은 Object 클래스 안에 있는 메소드이다.고로 어느 클래스서든 사용이 가능하다.

 

toString의 기능은

객체가 가지고 있는 정보나 값들을 문자열로 만들어 리턴한다.

이 메소드는 어느 자료형에서 사용하냐에 따라 결과값이 약간 다르다.String 자료형  =>  자신이 가진 값을 그대로 리턴File 자료형  =>  자신이 가진 해당 경로값을 리턴

 

마지막으로

이 메소드는 자동으로 호출된다.

 

무슨 의미냐면

 

' 클래스변수이름.toString() '

' 클래스 변수이름'

 

첫번째처럼 일일히 toString 메소드를 붙이지 않고 변수만 써도 동작을 한다.

 

 

 

아래의 예를 보며 확인해보자.

 

package object;


class Card{
	static final int	KIND_MAX	= 4;	// 카드의 무늬 수
	static final int	NUM_MAX	= 13;		// 무늬별 카드 수
	
	static final int	SPADE	= 4;
	static final int	DIAMOND	= 3;
	static final int	HEART	= 2;
	static final int	CLOVER	= 1;
	
	int kind;
	int number;
	
	Card(){
		this(SPADE, 1);
	}

	Card(int kind, int number){
		this.kind	= kind;
		this.number	= number;
	}
	
    // toString을 오버라이딩한다.
	@Override
	public String toString() {
		String kind		= "";
		String number	= "";
		
		switch(this.kind) {
		case 4:
			kind	= "SPADE";
			break;
		case 3:
			kind	= "DIAMOND";
			break;
		case 2:
			kind	= "HEART";
			break;
		case 1:
			kind	= "CLOVER";
			break;
		}
		
		switch(this.number) {
		case 13:
			number	= "K";
			break;
		case 12:
			number	= "Q";
			break;
		case 11:
			number	= "J";
			break;
		default:
			number	= this.number + "";
		}
		
		return "카드의 무늬 : " + kind + ", 카드의 숫자 : " + number;
	}

}


// Deck 생성
class Deck{
	final int CARD_NUM = 53;
	Card c[] = new Card[CARD_NUM];
	
	Deck() {
		int i = 0;
		
		for(int k = Card.KIND_MAX ; k > 0 ; k--) {
			for(int n = 1 ; n <Card.NUM_MAX + 1 ; n++) {
				c[i++] = new Card(k, n);
				
			}
		}
	}
	
	Card pick(int index) {
		if( 0 <= index && index < CARD_NUM)
			return c[index];
		else
			return pick();
	}
	
	Card pick() {
		int index = (int)(Math.random()*CARD_NUM);
		return pick(index);
	}
	
	void shuffle() {
		for(int n = 0 ; n < 1000 ;  n++ ) {
			int i = (int)(Math.random()*CARD_NUM);
			Card temp;
			temp	= c[0];
			c[0]	= c[i];
			c[i]	= temp;
		}
	}
}


public class Lecture2 {

	public static void main(String[] args) {
		
		// 덱 만든 후 바로 첫 카드 뽑기
		Deck d = new Deck();
		Card c = d.pick(0);
		System.out.println(c);
		
		
		// 셔플 후 첫 카드 뽑기
		d.shuffle();
		c	= d.pick(0);
		System.out.println(c);

	}
}



결과
카드의 무늬 : SPADE, 카드의 숫자 : 1
카드의 무늬 : HEART, 카드의 숫자 : K

 

위의 예에서 Card 클래스의 String 타입에서 toString을 오버라이딩해서 사용했다.

문자열로 리턴을 받고 싶었기 때문에!

 

그리고 마지막 출력을 하는 구문에서 

 

System.out.println(c.toString());

System.out.println(c);

 

첫번째처럼 사용하지 않고

두번째처럼 사용해도 자동으로 toString이 실행되는 것을 볼 수 있다.

 

 

 

1. toString 사용 결과

카드의 무늬 : SPADE, 카드의 숫자 : 1
카드의 무늬 : HEART, 카드의 숫자 : K



2. toString 사용 하지 않은 결과

object.Card@5305068a
object.Card@2ff4acd0

 

 

 

 

 


 

 

 

 

 

연습문제1.

아래와 같은 과일 장사가 가능한 출력이 나오도록 코딩하라.

 

==================================================================
1.사과구매  2.오렌지구매  3.구매자 님의 현황  4.판매자등록  0.종료
원하시는 번호를 고르세요 : 4
=======================================================================
1.사과  2. 오렌지
원하시는 판매 물품을 고르세요 : 1
판매할 사과의 갯수 : 10
사과의 가격 : 1000
판매자님 잔액 : 0
사과 판매자로 등록 되었습니다.
==================================================================
1.사과구매  2.오렌지구매  3.구매자 님의 현황  4.판매자등록  0.종료
원하시는 번호를 고르세요 : 4
=======================================================================
1.사과  2. 오렌지
원하시는 판매 물품을 고르세요 : 1
판매할 사과의 갯수 : 100
사과의 가격 : 2000
판매자님 잔액 : 0
사과 판매자로 등록 되었습니다.
==================================================================
1.사과구매  2.오렌지구매  3.구매자 님의 현황  4.판매자등록  0.종료
원하시는 번호를 고르세요 : 4
=======================================================================
1.사과  2. 오렌지
원하시는 판매 물품을 고르세요 : 2
판매할 오렌지의 갯수 : 50
오렌지의 가격 : 1500
판매자님 잔액 : 0
오렌지 판매자로 등록 되었습니다.
==================================================================
1.사과구매  2.오렌지구매  3.구매자 님의 현황  4.판매자등록  0.종료
원하시는 번호를 고르세요 : 4
=======================================================================
1.사과  2. 오렌지
원하시는 판매 물품을 고르세요 : 2
판매할 오렌지의 갯수 : 100
오렌지의 가격 : 2500
판매자님 잔액 : 5000
오렌지 판매자로 등록 되었습니다.
==================================================================
1.사과구매  2.오렌지구매  3.구매자 님의 현황  4.판매자등록  0.종료
원하시는 번호를 고르세요 : 1
=======================================================================
현재 소지 금액을 말씀해주세요 : 100000
=======================================================================
현재 사과 판매자 정보는 다음과 같습니다.
0번 판매자 => 남은 갯수 : 10 / 사과 가격 : 1000
1번 판매자 => 남은 갯수 : 100 / 사과 가격 : 2000
=======================================================================
원하시는 판매자번호를 누르세요 : 0
=======================================================================
얼마만큼을 구입하시겠습니까? : 1000
=======================================================================
[0번 사과 판매자]
남은 사과 갯수 : 9
사과 판매 수익 : 1000

==================================================================
1.사과구매  2.오렌지구매  3.구매자 님의 현황  4.판매자등록  0.종료
원하시는 번호를 고르세요 : 2
=======================================================================
현재 소지 금액을 말씀해주세요 : 99000
=======================================================================
현재 오렌지 판매자 정보는 다음과 같습니다.
0번 판매자 => 남은 갯수 : 50 / 오렌지 가격 : 1500
1번 판매자 => 남은 갯수 : 100 / 오렌지 가격 : 2500
=======================================================================
원하시는 판매자번호를 누르세요 : 1
=======================================================================
얼마만큼을 구입하시겠습니까? : 50000
=======================================================================
[1번 사과 판매자]
남은 오렌지 갯수 : 80
오렌지 판매 수익 : 55000

==================================================================
1.사과구매  2.오렌지구매  3.구매자 님의 현황  4.판매자등록  0.종료
원하시는 번호를 고르세요 : 3
[과일 구매자]
현재	잔액 : 49000
사과	갯수 : 1
오렌지	갯수 : 20
==================================================================
1.사과구매  2.오렌지구매  3.구매자 님의 현황  4.판매자등록  0.종료
원하시는 번호를 고르세요 :

 

 

 

답은 자유롭습니다.
아래는 참고만 하세용~



package object;

import java.util.Scanner;

// 변수 설정
class Variation{
	
	public static Scanner typing = new Scanner(System.in);
	
	int apple ;
	int orange ;
	int appleProfit = 0 ;
	int orangeProfit = 0 ;
	int applePrice ;	
	int orangePrice ;

	int BuyerApple = 0 ;
	int BuyerOrange = 0 ;
	int BuyerMoney ;
	
	
	// default 생성자
	Variation(){
	}	
	
	// 구매자 생성자
	Variation(int BuyerMoney){
		this.BuyerMoney = BuyerMoney;
	}	
	
	// 사과 판매자 생성자
	Variation(int apple, int applePrice, int appleProfit){
		this.apple = apple;
		this.applePrice = applePrice;
		this.appleProfit = appleProfit;	
	}	
	
	// 오렌지 판매자 생성자
	Variation(int orange, int orangePrice, int orangeProfit, int a){
		this.orange = orange;
		this.orangePrice = orangePrice;
		this.orangeProfit = orangeProfit;	
	}
	
}


// 초기 메뉴판
class Menu{
	
	public void MenuView() {
		System.out.println("==================================================================");
		System.out.println("1.사과구매  2.오렌지구매  3.구매자 님의 현황  4.판매자등록  0.종료");
		System.out.print("원하시는 번호를 고르세요 : ");	
	}
}



// 판매자 등록
class seller {
		
	final int MAX_CNT = 100 ;
	Variation[] AplSellerStorage = new Variation[MAX_CNT];
	Variation[] OriSellerStorage = new Variation[MAX_CNT];
	int appleIndex = 0;
	int orangeIndex = 0;

	public void sellerMenu() {	

		while(true) {
			System.out.println("=======================================================================");
			System.out.println("1.사과  2. 오렌지");
			System.out.print("원하시는 판매 물품을 고르세요 : ");
			
			int sellerChoice = Variation.typing.nextInt();

			
			if(sellerChoice == 1 || sellerChoice == 2) {
				switch(sellerChoice){
					case 1 : {
						System.out.print("판매할 사과의 갯수 : ");		
						int apple = Variation.typing.nextInt();	
						System.out.print("사과의 가격 : ");		
						int applePrice = Variation.typing.nextInt();		
						System.out.print("판매자님 잔액 : ");		
						int appleProfit = Variation.typing.nextInt();	
						
						AplSellerStorage[appleIndex++] = new Variation( apple, applePrice, appleProfit);
						System.out.println("사과 판매자로 등록 되었습니다.");
						break;
					}
		
					case 2 : {
						System.out.print("판매할 오렌지의 갯수 : ");		
						int orange = Variation.typing.nextInt();	
						System.out.print("오렌지의 가격 : ");		
						int orangePrice = Variation.typing.nextInt();		
						System.out.print("판매자님 잔액 : ");		
						int orangeProfit = Variation.typing.nextInt();	
						
						OriSellerStorage[orangeIndex++] = new Variation( orange, orangePrice, orangeProfit, 1 );
						System.out.println("오렌지 판매자로 등록 되었습니다.");			
						break;
					}
				}
				break;
			} else {
				System.out.println("다시 입력 부탁 드립니다.");
				continue;
			}
		}
	}
} // class seller - End



// 메뉴 선택
class Function extends seller{
	
	Variation Vari1 = new Variation();

	// 사과 구매
	public void choice1(){
		
		System.out.println("=======================================================================");
		System.out.print("현재 소지 금액을 말씀해주세요 : ");
		Vari1.BuyerMoney = Variation.typing.nextInt();
		
		System.out.println("=======================================================================");
		System.out.println("현재 사과 판매자 정보는 다음과 같습니다.");
		
		for(int i = 0 ; i < appleIndex ; i++) {
			System.out.print(i + "번 판매자 => ");	
			System.out.println("남은 갯수 : " + AplSellerStorage[i].apple + " / 사과 가격 : " + AplSellerStorage[i].applePrice);	
		}

		System.out.println("=======================================================================");
		System.out.print("원하시는 판매자번호를 누르세요 : ");
		int Index = Variation.typing.nextInt();
		
		
		
		
		while(true) {
			System.out.println("=======================================================================");
			System.out.print("얼마만큼을 구입하시겠습니까? : ");
			int money = Variation.typing.nextInt();
			int num = money/AplSellerStorage[Index].applePrice;
			
			
			if( AplSellerStorage[Index].apple < num ) {
				System.out.println("판매할 수보다 많습니다. 다시 입력해주십시요");
				continue;
			} else {
				AplSellerStorage[Index].apple -= num;
				AplSellerStorage[Index].appleProfit += AplSellerStorage[Index].applePrice * num;

				System.out.println("=======================================================================");
				System.out.println("[" + Index + "번 사과 판매자]");
				System.out.println("남은 사과 갯수 : " + AplSellerStorage[Index].apple);
				System.out.println("사과 판매 수익 : " + AplSellerStorage[Index].appleProfit);
				System.out.println();
				
				Vari1.BuyerMoney -= AplSellerStorage[Index].applePrice * num;
				Vari1.BuyerApple += num;
				break;
			}		
		}
	} // choice1 - End

	
	
	// 오렌지 구매
	public void choice2(){
		
		System.out.println("=======================================================================");
		System.out.print("현재 소지 금액을 말씀해주세요 : ");
		Vari1.BuyerMoney = Variation.typing.nextInt();
		
		System.out.println("=======================================================================");
		System.out.println("현재 오렌지 판매자 정보는 다음과 같습니다.");
		
		for(int i = 0 ; i < orangeIndex ; i++) {
			System.out.print(i + "번 판매자 => ");	
			System.out.println("남은 갯수 : " + OriSellerStorage[i].orange + " / 오렌지 가격 : " + OriSellerStorage[i].orangePrice);	
		}

		System.out.println("=======================================================================");
		System.out.print("원하시는 판매자번호를 누르세요 : ");
		int Index = Variation.typing.nextInt();
		
		
		while(true) {
			
			System.out.println("=======================================================================");
			System.out.print("얼마만큼을 구입하시겠습니까? : ");
			int money = Variation.typing.nextInt();
			int num = money/OriSellerStorage[Index].orangePrice;
			
			
			if( OriSellerStorage[Index].orange < num ) {
				System.out.println("판매할 수보다 많습니다. 다시 입력해주십시요");
				continue;
			} else {
				OriSellerStorage[Index].orange -= num;
				OriSellerStorage[Index].orangeProfit += OriSellerStorage[Index].orangePrice * num;

				System.out.println("=======================================================================");
				System.out.println("[" + Index + "번 사과 판매자]");
				System.out.println("남은 오렌지 갯수 : " + OriSellerStorage[Index].orange);
				System.out.println("오렌지 판매 수익 : " + OriSellerStorage[Index].orangeProfit);
				System.out.println();
				
				Vari1.BuyerMoney -= OriSellerStorage[Index].orangePrice * num;
				Vari1.BuyerOrange += num;
				break;				
			}
		}
	} // choice2 - End
	
	
	
	// 구매자 현황
	public void choice3(){
		System.out.println("[과일 구매자]");
		System.out.println("현재	잔액 : " + Vari1.BuyerMoney);
		System.out.println("사과	갯수 : " + Vari1.BuyerApple);
		System.out.println("오렌지	갯수 : " + Vari1.BuyerOrange);
	}
	
	// 판매자 등록
	public void choice4(){
		
		sellerMenu();
		
	}
} // class Function extends seller - End



// 메인
public class Practice2 {

	public static void main(String[] args) {
		
		Menu m = new Menu();
		Function function = new Function();
		
		
		while(true) {
			m.MenuView();
			
			int choice = Variation.typing.nextInt();

			if( 0 <= choice && choice < 5 ) {
				switch(choice){
					case 1: {
						function.choice1() ;
						break;
					}
					case 2: {
						function.choice2() ;
						break;
					}
					case 3: {
						function.choice3() ;
						break;
					}
					case 4: {
						function.choice4() ;
						break;
					}
					case 0: return ;				
					
				}
			} else {
				System.out.println("번호를 다시 입력해주세요");
				continue;
			}
		}
	}
}

 

 

 

728x90
반응형

댓글