'Code/JAVA'에 해당되는 글 62건
상속_2(다형성, 추상 클래스)
다형성
- 같은 타입이지만 실행 결과가 다양한 객체를 이용할 수 있는 성질. 코드 측면에서 보면 하나의 타입에 여러 객체를 대입함으로써 다양한 기능 이용할 수 있게 해줌
-부모 클래스로 타입 변환 가능 -> 부모 타입에 모든 자식 객체가 대입 될 수 있음
ex) public class car { //Tire : 부모 클래스
Tire t1 = new Hankook(); //자식 타입이 부모 타입으로 자동 타입 변환
Tire t2 = new Kumho();
}
- 타입 변환 : 데이터 타입을 다른 데이터 타입으로 변환하는 행위, 자식 타입은 부모 타입으로 자동 타입 변환이 가능
- 자동 타입 변환 : 프로그램 실행 도중에 자동적으로 타입 변환이 일어나는 것
부모 클래스 변수 = 자식 클래스 타입();
-> 자식은 부모의 특징과 기능 상속받기 때문에 부모와 동일하게 취급될 수 있
ex) Cat cat = new Cat(); Animal animal = cat; -> Animal animal = new Cat();
이렇게 부모 타입으로 자동 타입 변환되면 부모 클래스에 선언된 필드와 메소드만 접근 가능
but, 메소드가 자식 클래스에서 오버라이딩되었다면, 자식 클래스의 메소드가 대신 호출 --> 다형성과 관련
- 강제 타입 변환(casting) : 부모 타입을 자식 타입으로 변환하는 것. 자식 타입이 부모 타입으로 자동 변환 후, 다시 자식 타입으로 변환할 대 강제 타입 변환 사용
ex) Parent parent = new Child();
Child child = (Child) parent;
- 객체 타입 확인(instanceof) : 좌항은 객체가 오고 우항은 타입이 옴, 자항의 객체가 우항의 인스턴스이면/우항타입으로 객체 생성된다면 true, 아니면 false. 주로 매개값의 타입 조사할 때 사용
ex) boolean result = 좌항(객체) instanceof 우항(타입)
- 실체 클래스 : 객체를 직접 생성할 수 있는 클래스
- 추상(abstract) 클래스 : 실체 간에 공통되는 특성 추출. 클래스들의 공통된 특성을 추출해서 선언한 클래스
객체를 직접 생성해서 사용할 수 없음
1. 실체 클래스들의 공통된 필드와 메소드의 이름을 통일할 목적
2. 실체 클래스를 작성할 때 시간을 절약
- 추상 클래스 선언 : public abstract class 클래스 {}
일반 클래스처럼 필드, 생성자, 메소드 선언 가능
- 추상 메소드 : 추상 클래스에서만 선언 가능, 선언부만 있고 {} 없는 형태 -> 자식 클래스는 반드시 추상 메소드를 재정의해서 실행 내용 작성해야함
'Code > JAVA' 카테고리의 다른 글
| 배열 예제_2차원 배열 (0) | 2019.06.18 |
|---|---|
| 배열 예제_숫자 출력 (0) | 2019.06.18 |
| 상속_1(상속, override, final) (0) | 2019.06.18 |
| 클래스_5(패키지) (0) | 2019.06.18 |
| 클래스 예제_계산기 (0) | 2019.06.18 |
상속_1(상속, override, final)
상속(nheritance)
부모가 자식에게 물려주는 행위.
자식은 상속을 통해 부모가 물려준 것을 자연스럽게 이용 가능. 상위 클래스, 하위 클래스
부모 클래스에서 private 접근 제한을 갖는 필드와 메소드는 상속 대상에서 제외, 부모와 자식 클래스가 다른 패키지 내에 존재한다면 default 접근 제한 갖는 필드와 메소드도 상속 대상에서 제외
- 클래스 상속 : 자식 클래스 선언 할 때 어떤 부모 클래스를 상속받을 것인지 결정하고 선택된 부모 클래스는 extends 뒤에 기술. 다중 상속 허용 안 함
- 부모 생성자 호출 : 부모 객체가 먼저 생성되고 자식 객체가 그 다음에 생성됨 -> 모든 객체는 클래스의 생성자 호출해야만 생성됨
- super() : 부모의 기본 생성자 호출, 즉 첫번째 생성자 메소드 호출함. 매개변수 있을 시 같은 타입의 부모 생성자 호출
메소드 재정의 : 상속된 일부 메소드는 자식 클래스에서 다시 수정해서 사용해야 함. -> 메소드 오버라이딩
@Override : 상속된 메소드의 내용이 자식 클래스와 맞지 않을 경우, 자식 클래스에서 동일한 메소드를 재정의 하는 것
메소드를 오버라이딩 되었다면 부모 객체의 메소드는 숨겨지기 때문에, 자식 객체에서 메소드 호출하면 오버 라이딩 된 자식 메소드 호출됨
- 부모 메소드와 같은 시그너처(리턴 타입, 메소드 이름, 매개 변수 리스트) , 접근 제한을 더 강하게 오버라이딩 불가, 새로운 예외(Exception)를 throw 할 수 없음
부모 메소드 호출
- super() : 자식 클래스에서 부모 클래스 메소드 오버라이딩 하게 되면, 부모 클래스의 메소드 숨겨지고, 오버라이딩 된 자식 메소드만 사용 -> super. 부모 메서드();
- 부모 객체 참조하기 때문에 부모 메소드 직접 접근 가능
- final : 클래스, 필드, 메소드 선언 시 사용할 수 있음. 해당 선언이 최종 상태, 수정될 수 없음
- final 클래스 : 상속 할 수 없음
-> 부모 클래스 될 수 없고 자식 클래스 만들 수 없음 ex) public final class 클래스 이름{}
- final 메소드 : 오버 라이딩할 수 없음 -> 부모에서 선언된 메소드는 자식 클래스에서 재정의 할 수 없음 ex) public final 리턴 타입 메소드 () {}
- protected : public과 default 접근 제한의 중간 쯤 위치, 같은 패키지 내에서는 접근 제한 없지만 다른 패키지에서는 자식 클래스만 접근 허용
'Code > JAVA' 카테고리의 다른 글
| 배열 예제_숫자 출력 (0) | 2019.06.18 |
|---|---|
| 상속_2(다형성, 추상 클래스) (0) | 2019.06.18 |
| 클래스_5(패키지) (0) | 2019.06.18 |
| 클래스 예제_계산기 (0) | 2019.06.18 |
| 클래스 예제 (0) | 2019.06.18 |
클래스_5(패키지)
패키지(package)
자바에서 클래스를 체계적으로 관리하기 위한 것, 클래스를 저장관리하는 폴더, 클래스를 유일하게 만들어주는 식별자 역할 -> 상위클래스.하위클래스.클래스
- 패키지 선언 ; package 상위패키지.하위패키지; ex) com.samsung.projectname;
- import : 같은 패키지에 속하는 클래스는 아무 조건 없이 사용 가능하지만, 다른 패키지 속하는 클래스 이용 시 import 패키지명;
- 접근 제한자 : 데이터 보호하기 위해
적용대상 접근할 수 없는 클래스
| public | 클래스, 필드, 생성자,메소드 없음 |
| protected | 필드, 생성자, 메소드 자식 클래스가 아닌 다른 패키지에 소속된 클래스 |
| default | 클래스, 필드, 생성자, 메소드 다른 패키지에 소속된 클래스 |
| private | 필드, 생성자, 메소드 모든 외부 클래스 |
- 클래스 접근 제한
클래스 선언할 때 같은 패키지 내에서만 사용할 지, 다른 패키지에서도 사용할 지 -> 클래스는 public, default 두가지
default : 클래스 접근 제한 없으면 기본으로 가지고 있음. 같은 패키지 내에서 사용 가능, 다른 패키지 불가
public : 같은 패키지뿐만 아니라 다른 패키지에서도 아무런 제한 없이 사용 가능
'Code > JAVA' 카테고리의 다른 글
| 상속_2(다형성, 추상 클래스) (0) | 2019.06.18 |
|---|---|
| 상속_1(상속, override, final) (0) | 2019.06.18 |
| 클래스 예제_계산기 (0) | 2019.06.18 |
| 클래스 예제 (0) | 2019.06.18 |
| 클래스_4(싱글톤, final) (0) | 2019.06.18 |
클래스 예제_계산기
사용자가 입력 받은 값으로 연산하는 계산기를 만들 것이다.

위 사진은 결과로 출력되어야 할 모습이다.
조건 :
사용자에게 숫자와 연산자 입력 받기
클래스 객체를 만들어 메소드 호출하기
연산 + - * / 를 메소드로 만들기
계속 계산할 수 있는 반복문 사용하기
아래는 문제의 최종 소스이다.
|
import java.util.Scanner;
public class Calculator {
private int num1; private String ch; private int num2;
public Calculator(int n1, String c, int n2) { num1 = n1; ch = c; num2 = n2; }
public void setNum1(int num) {num1= num;} public void setNum2(int num) {num2= num;} public void setChar(String c) {ch= c;}
public int getNum1() {return num1;} public int getNum2() {return num2;} public String getChar() {return ch;}
int add() {return num1+num2;} int sub() {return num1-num2;} int div() {return num1/num2;} int mul() {return num1*num2;}
public static void main(String[] args) {
Scanner input = new Scanner(System.in); //Scanner 생성 int result = 0; //최종 계산값 저장 변수 String yn; //연산자 저장 변수
do { System.out.print("첫번째 숫자 입력 : "); int num1 = input.nextInt();
System.out.print("게산할 연산자 입력 : "); String ch = input.next();
System.out.print("두번째 숫자 입력 : "); int num2 = input.nextInt();
Calculator c = new Calculator(num1, ch, num2);
switch(ch) { //연산자 비교 case "+": System.out.println(c.add());break; case "-": System.out.println(c.sub());break; case "*": System.out.println(c.mul());break; case "/": System.out.println(c.div());break; default: System.out.println("연산자를 잘못입력하였습니다.");break; }
System.out.println("계속 계산하시겠습니까?"); yn = input.next();
}while(yn.equals("y") || yn.equals("Y")); //y 혹은 Y 입력 시 반복 } }
|
'Code > JAVA' 카테고리의 다른 글
| 상속_1(상속, override, final) (0) | 2019.06.18 |
|---|---|
| 클래스_5(패키지) (0) | 2019.06.18 |
| 클래스 예제 (0) | 2019.06.18 |
| 클래스_4(싱글톤, final) (0) | 2019.06.18 |
| 클래스_3(정적, 인스턴스) (0) | 2019.06.18 |
클래스 예제
앞에서 설명한 필드, 생성자, 메소드를 이용하여 클래스 객체 만들기 입니다.
클래스 이름 : ClassExam1
필드 : name, age
생성자 : ClassExam1 (매개변수 2개) 로 객체 생성 될 때 자동으로 호출 및 필드 초기화
set : 필드 값 변경할 수 있는 메소드
get : 필드 값 불러올 수 있는 메소드
set과 get은 클래스 객체 만든 후 사용 가능 -> 객체이름.set / .get

'Code > JAVA' 카테고리의 다른 글
| 클래스_5(패키지) (0) | 2019.06.18 |
|---|---|
| 클래스 예제_계산기 (0) | 2019.06.18 |
| 클래스_4(싱글톤, final) (0) | 2019.06.18 |
| 클래스_3(정적, 인스턴스) (0) | 2019.06.18 |
| 클래스_2(필드, 생성자,메소드) (0) | 2019.06.18 |
클래스_4(싱글톤, final)
싱글톤(singleton) : 단 하나의 객체만 만들도록 보장해야하는 경우
-> 외부 클래스에서 new 연산자로 생성자를 호출 할 수 없어야함
생성자 앞에서 private 사용하면 된다
- ex) public class 클래스 이름{
private static 클래스 이름 singleton = new 클래스 이름();
private 클래스 이름(){}
static 클래스 이름 getInstance(){
return singleton
}
}
- main에서 사용 할 때 : 클래스이름 변수1 = 클래스이름.getInstance(); -> 두개 만들어도 하나만 생성되서 같은 객체가 됨
final : 최종적이란 뜻. 필드에 초기값 저장되면 최종적인 값이 되어 수정 불가 ex) final 타입 필드 [=초기값];
- 초기값 주는 법 : 1. 필드 선언 시 주는 방법 2. 생성자에 주는 방법
상수(static final) : 불변의 값. 대문자로 사용 ex) static final 타입 변수 [=초기값];
-<이것이 자바다1>. 한빛 미디어
'Code > JAVA' 카테고리의 다른 글
| 클래스 예제_계산기 (0) | 2019.06.18 |
|---|---|
| 클래스 예제 (0) | 2019.06.18 |
| 클래스_3(정적, 인스턴스) (0) | 2019.06.18 |
| 클래스_2(필드, 생성자,메소드) (0) | 2019.06.18 |
| 클래스_1(클래스와 객체) (0) | 2019.06.18 |
클래스_3(정적, 인스턴스)
static : 정적 = 고정된
- 정적 멤버 : 클래스에 고정된 멤버로, 객체를 생성하지 않고 사용할 수 있는 필드와 메소드 -> 정적 필드, 정적 메소드
- 정적 멤버 선언 : 필드와 메소드 선언 시 static 키워드를 추가적으로 붙이면 된다 ex) static 타입 필드 [=초기값];
- 정적 vs 인스턴스 : 객체마다 가지고 있어야 할 데이터라면 인스턴스, 객체마다 가지고 있을 필요성 없는 공용 데이터라면 정적
- 인스턴스 : 필드 값 변경 필요할 경우, 정적 : 오로지 값 변경 없이 사용할 경우)
- 정적 : 클래스가 메모리로 로딩되면 정적 멤버를 바로 사용할 수 있고 도트(.) 연산자로 접근 ex)클래스.필드
* 정적 멤버를 클래스 이름으로 접근하지않고 객체 참조 변수로 접근했을 경우 경고 뜸
정적 메소드와 정적 블록 선언할 때 객체 없어도 실행 되기 때문에, 내부에서 인스턴스 필드나 메소드 사용 불가
또한 자신의 참조인 this 키워드도 사용 불가
-<이것이 자바다1>. 한빛미디어
'Code > JAVA' 카테고리의 다른 글
| 클래스 예제 (0) | 2019.06.18 |
|---|---|
| 클래스_4(싱글톤, final) (0) | 2019.06.18 |
| 클래스_2(필드, 생성자,메소드) (0) | 2019.06.18 |
| 클래스_1(클래스와 객체) (0) | 2019.06.18 |
| 열거 타입 (0) | 2019.06.18 |
클래스_2(필드, 생성자,메소드)
앞에 클래스_1 과 이어서 설명합니다.
1. 필드
- 필드 선언 : 타입 필드 [ = 초기값 ];
- 필드 사용 : 필드값을 읽고 변경하는 작업. 클래스 내부의 생성자나 메소드에서 사용할 경우 단순히 필드 이름 읽고 변경하지만, 외부에서 사용할 경우 우선적으로 클래스로부터 객체 생성 후에 필드를 사용해야 함
2. 생성자
new 연산자에 의해 생성자가 성공적으로 실행되면 힙(heap) 영역에 객체가 생성되고 객체의 주소가 리턴됨
- 기본 생성자 : 모든 클래스는 생성자 반드시 존재, 하나 이상 가질 수 있음.
[public] 클래스() {}
- 생성자 선언 : 클래스(매개변수 선언 ,,,,){} -> 메소드와 비슷하지만, 리턴 타입 없고 클래스와 이름 동일
- 필드 초기화 : 클래스로 부터 객체 생성될 때 필드는 기본 초기값으로 자동 설정됨
만약 다른 값으로 초기화 할 경우 1. 필드 선언할 때 초기값 주는 방법 2. 생성자에서 초기값을 주는 방법
- 생성자 오버로딩 (overloading) : 매개변수 달리하는 생성자를 여러개 선언하는 것
매개변수 수를 변경하거나, 데이터 타입을 변경하거나
- 다른 생성자 호출(this()) : 자신의 다른 생성자를 호출하는 코드. 반드시 생성자의 첫번째 줄에서만 허용 됨.호출되는 생성자의 실행 끝나면 원래 생성자로 돌아와 다음 실행문 실행
ex) this("superman", 0, "은색");
3. 메소드
- 메소드 선언 : 선언부(리턴타입, 메소드 이름, 매개변수선언) 과 실행 블록
- 리턴 타입 : 메소드가 실행 후 리턴하는 값의 타입. 리턴 값 있을 수도(리턴하는 데이터 타입) 없을 수도(void) 있음
- 메소드 이름 :자바 식별자 규칙에 맞게 작성하면 됨
- 매개 변수 선언 : 메소드가 실행할 때 필요한 데이터를 외부로부터 받기 위해 사용된다
- 리턴(return) 문 : 리턴값 있는 메소드 : 리턴문 사용하여 값을 지정해서 반환해야 함. 리턴문 실행되면 메소드 종료
- 메소드 호출 : 클래스 내/외부의 호출에 의해 실행. 클래스 외부에서 호출 시 객체를 생성한 후, 참조 변수를 이용하여 메소드 호출
- 메소드 오버로딩 : 클래스 내에 같은 이름의 메소드 여러개 선언하는 것 -> 조건 : 매개변수 타입, 개수, 순서 중 하나가 달라야함
- 인스턴스 멤버 : 객체(인스턴스) 생성한 후 사용할 수 있는 필드와 메소드 -> 인스턴스 필드, 인스턴스 메소드 / 객체 없이 사용 불가
- this : 객체 내부에서도 인스턴스 멤버에 접근하기 위해 this 사용 -> 매개 변수 이름이 필드와 동일 한 경우, 인스턴스 멤버인 필드임을 명시하고자 사용
-<이것이 자바다1>. 한빛 미디어
'Code > JAVA' 카테고리의 다른 글
| 클래스_4(싱글톤, final) (0) | 2019.06.18 |
|---|---|
| 클래스_3(정적, 인스턴스) (0) | 2019.06.18 |
| 클래스_1(클래스와 객체) (0) | 2019.06.18 |
| 열거 타입 (0) | 2019.06.18 |
| 배열 (0) | 2019.06.18 |
클래스_1(클래스와 객체)
클래스
- 객체란?
: 물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중에서 자신의 속성을 가지고 있는 다른 것과 식별 가능한 것 속성과 동작 -> 필드와 메소드
- 객체 모델링 : 객체를 소프트웨어 객체로 설계하는 것/ 현실 세계의 객체의 속성고 동작을 추려내어 소프트웨어 객체의 필드와 메소드를 정의하는 것
- 객체들은 각각 독립적으로 존재하고, 다른 객체와 서로 상호작용하면서 동작
-> 메소드 / 객체가 다른 객체의 기능을 이용하는 것 : 메소드 호출
메소드는 도트(.) 연산자 이용해 필드와 메소드 접근할 때 사용
- 객체는 개별적으로 사용할 수 있지만, 대부분 다른 객체와 관계를 맺고 있다.
1. 집합관계 : 하나는 부품이고 하나는 완성품에 해당
2. 사용관계 : 객체 간의 상호작용. 객체는 다른 객체의 메소드를 호출하여 원하는 결과를 얻어낸다.
3. 상속관계 : 상위(부모) 객체를 기반으로 하위(자식) 객체를 생성하는 관계 / 대부분 상위: 종류, 하위 : 구체적인 사물
객체 지향 프로그래밍의 특징
1. 캡슐화(Encapsulation) : 객체의 필드, 메소드를 하나로 묶고, 실제 구현 내용을 감추는 것. 외부 객체는 객체 내부의 구조를 알지 못하며, 객체가 노출해서 제공하는 필드와 메소드만 이용할 수 있음
-> why? 외부의 잘못된 사용으로 인해 객체가 손상되지 않도록
2. 상속(Inheritance) : 부모 역할의 상위 객체와 자식 역할의 하위클래스가 있음 -> 상위 객체는 자기가 가지고 있는 필드와 메소드를 하위 객체에 물려주어 하위 객체가 사용할 수 있도록 함
-> 재사용, 효율적, 개발 시간 절약, 유지보수 최소화
3. 다형성(Polymorphism) : 같은 타입이지만 실행 결과가 다양한 객체를 이용할 수 있는 성질
자바에서는 부모 클래스 또는 인터페이스 타입 변환 허용 ex) 부모 타입에는 모든 타입의 자식 객체가 대입될 수 있고, 인터페이스 타입에는 모든 구현 객체가 대입될 수 있다.
객체와 클래스
- 객체 : 하나의 설계도
- 클래스 : 객체를 생성하기 위한 필드와 메소드 정의 됨, 클래스로부터 만들어진 객체를 해당 클래스의 인스턴스(instance)라고 함
1. 클래스 설계 -> 2. 설계된 클래스를 가지고 사용할 객체 생성해야 함 -> 3. 생성된 객체 사용
main() 메소드 없는 크래스는 객체 생성 과정을 거쳐 사용해야 함
- 클래스 선언
: 하나 이상의 문자로 이루어져야 함. 첫번째 글자 숫자 올 수 없음. '$','_' 외의 특수문자 사용 불가, 자바 키워드 불가
- 객체 생성 : new 클래스();
new : 클래스로부터 객체를 생성시키는 연산자. -> 생성된 객체는 메모리 힙(heap) 영역에 생성됨
힙 영역에 객체 생성 후 객체 주소 리턴 -> 객체 사용할 수 있음 ex) 클래스 변수; 변수 = new 클래스();
- 실행 클래스 : main 가지고 있는 실행 클래스
- 라이브러리 클래스 (API) : 다른 클래스에서 사용할 목적으로 이루어 짐
- 클래스의 구성 멤버 : 필드, 생성자, 메소드
1. 필드 : 객체의 고유 데이터, 부품 객체, 상태 정보 저장하는 곳. 선언 형태는 변수와 비슷하지만 필드를 변수라고 부르지 않음. 생성자와 메소드 내에서만 사용. 종료되면 자동 소멸
2. 생성자 : new 연산자로 호출되며 특별한 중괄호 {} 블록임.
역할 : 객체 생성 시 초기화 담당 - 필드 초기화 or 메소드 호출해서 객체 사용할 준비, 클래스 이름과 같고 리턴 타입 없음
3. 메소드 : 객체의 동장에 해당하는 중괄호{} 블록
메소드 호출하면 중괄호 블록에 있는 모든 코드 일괄적으로 실행. 필드 읽고 수정하는 역할 + 다른 객체 생성해 다양한 기능을 하기도 함
- <이것이 자바다1>. 한빛 미디어
'Code > JAVA' 카테고리의 다른 글
| 클래스_3(정적, 인스턴스) (0) | 2019.06.18 |
|---|---|
| 클래스_2(필드, 생성자,메소드) (0) | 2019.06.18 |
| 열거 타입 (0) | 2019.06.18 |
| 배열 (0) | 2019.06.18 |
| 참조 타입 (0) | 2019.06.18 |
열거 타입
열거 타입 : 한정된 값만 가지는 데이터 타입, 하나의 상수를 저장하는 데이터 타입
- 열거 타입 선언 : public enum 열거타입이름 {}
//이름은 첫문자 대문자로 하고, 나머지 소문자, 열거 상수는 대문자로, 여러 상수는 _로 연결
- 열거 타입 변수 : 열거타입 변수; //사용에 있어서 변수 이름을 통해서 접근 가능 ex) Week today = Week.SUNDAY;
* 캘린더 : 사용자 컴퓨터의 날짜 및 요일, 시간을 프로그램에서 사용할 수 있도록 하기 위해
Calendar now = Calendar.getInstance(); -> 메소드가 리턴하는 Calendar 객체 얻음
now.get() 을 통하여 년,월,일,여일,시간,분,초 얻을 수 있음>get(Calendar.YEAR) / (Calendar.Month)+1 / Calendar.DAY_OF_MONTH(일), ....
- 열거 객체의 메소드 java.lang.Enum
String name() : 열거 객체의 문자열 리턴
int ordinal() : 열거 객체의 순번(0부터 시작)을 리턴 ex)열거값이 위치한 인덱스 int로 반환
int compareTo() : 열거 객체를 비교해서 순번 차이를 리턴 ex)day1.compareTo(day2) : 인덱스 차이를 반환
열거타입.valueOf(String name) : 주어진 문자열의 열거 객체를 리턴
ex)Week weekDay = week.valueOf("SUNDAY") -> weekDay = week.SUNDAY 열거 객체를 참조하는 것과 같음
열거타입.values() 모든 열거 객체들을 배열로 리턴
ex)Week[] days = Week.values(); -> days 가 Week enum에 있는 값들을 그래도 배열로 저장
'Code > JAVA' 카테고리의 다른 글
| 클래스_2(필드, 생성자,메소드) (0) | 2019.06.18 |
|---|---|
| 클래스_1(클래스와 객체) (0) | 2019.06.18 |
| 배열 (0) | 2019.06.18 |
| 참조 타입 (0) | 2019.06.18 |
| Scanner를 통한 데이터 입력하기 (0) | 2019.06.18 |