AWS 클라우드환경 네이티브 수업 56일차
진행
1. 자바 초기화
2. 클래스를 이용한 간단한 입출력 프로그램 만들기
요약
1. 자바 초기화 및 초기화 순서
2. 참고 - nextInt() 과 nextLine() 을 연이어 쓰는 이유
3. 접근제어자(public, protected, default, private)
4. final
초기화 및 초기화 순서
초기화는 말그대로 선언한 객체에 최초로 값을 넣어주는 것을 말한다.
이것이 필요한 이유는
클래스 내에서 선언 시에는 컴파일러가 자동으로 초기값을 넣어주지만
메소드 내에서 선언 시에는 값이 할당이 되지 않으면서 에러가 나기 때문이다.
초기화의 방법은 아래와 같이 3가지가 있다.
1. 명시적 초기화
2. 생성자를 이용한 초기화 (8/4 생성자 참고)
3. 초기화 블록을 이용한 초기화
1. 명시적 초기화
static int classVar = 10; // 클래스 변수의 명시적 초기화
int instanceVar = 20; // 인스턴스 변수의 명시적 초기화
3-1. 초기화 블록(클래스 블록)
static {
vari = 10;
}
3-2. 초기화 블록(인스턴트 블록)
{
sample = 0;
}
초기화 순서
클래스 초기화
: 처음 static 메모리를 올릴 때 한번만 실행된다.
기본값 => 명시된 초기화 순으로 초기화 된다.
인스턴스 초기화
: 인스턴스가 생성될 때마다 각 인스턴스별로 초기화 된다.
기본값 => 명시된 초기화 => 생성자 순으로 초기화 된다.
아래의 예를 보면
static 클래스 => main문 => 초기화 블럭 => 생성자
순으로 출력되는 것을 알 수 있다.
(8/4 자바의 메모리 사용 참고)
다만 main 문에 객체가 생성되는 것은 가장 나중의 일이기 때문에
첫번째 객체 생성 전에 있는 출력문이 나오고 인스턴트 => 생성자 순으로 진행되고
첫번째 객체를 생성, 그 후에 2번째 객체 생성 출력문이 나오고(이때, 2번째 객체는 생성되지 않는다)
클래스 초기화는 이미 되어 있는 상태기 때문에 또 출력되지 않는다.
그 후 인스턴스 => 생성자 순으로 또 진행 된다.
그 후 2번째 객체가 생성된다.
package block;
public class BlockExam {
// 클래스 초기화 블럭
static {
System.out.println("클래스 초기화 블럭");
}
// 인스턴스 초기화 블럭
{
System.out.println("인스턴스 초기화 블럭");
}
// 생성자
BlockExam(){
System.out.println("생성자 블럭");
}
public static void main(String[] args) {
System.out.println("첫번째 BlockExam 클래스 생성");
BlockExam aaa = new BlockExam(); // 1번째 객체
System.out.println("두번째 BlockExam 클래스 생성");
BlockExam bbb = new BlockExam(); // 2번째 객체
}
}
결과
클래스 초기화 블럭
첫번째 BlockExam 클래스 생성
인스턴스 초기화 블럭
생성자 블럭
두번째 BlockExam 클래스 생성
인스턴스 초기화 블럭
생성자 블럭
간단한 전화번호 입출력 프로그램 만들기1
package Phone;
import java.util.Scanner;
class PhoneInfo{
String name;
String phoneNumber;
String birth;
public PhoneInfo(String name,String phoneNumber, String birth ){
this.name = name;
this.phoneNumber = phoneNumber;
this.birth = birth;
}
public PhoneInfo(String name,String phoneNumber) {
this.name = name;
this.phoneNumber = phoneNumber;
this.birth = null;
}
public void showPhoneInfo(){
System.out.println("===================================");
System.out.println("이 름 : " + name);
System.out.println("전화번호 : " + phoneNumber);
if(birth != null) {
System.out.println("생년월일 : " + birth);
}
}
}
public class phone1 {
static Scanner typing = new Scanner(System.in);
public static void showMenu() {
System.out.println("원하는 작업을 고르세요");
System.out.println("1. 전화번호 입력");
System.out.println("2. 프로그램 종료 ");
System.out.print("무엇을 원하시죠? : ");
}
public static void choice1() {
System.out.print("이름 : ");
String name = typing.nextLine();
System.out.print("전화번호 : ");
String phone = typing.nextLine();
System.out.print("생년월일 : ");
String birth = typing.nextLine();
PhoneInfo info = new PhoneInfo(name, phone, birth);
info.showPhoneInfo();
}
public static void main(String[] args) {
int choice = 0 ;
while(true) {
showMenu(); // 메뉴 출력
choice = typing.nextInt(); // 메뉴 선택 받기
typing.nextLine();
// 이해는 안되는데 nextInt 다음에 nextLine를 안써주면
// 우리가 원하는 결과값이 나오지 않는다.
switch(choice) {
case 1: choice1();
break;
case 2:
return;
}
}
}
}
결과
원하는 작업을 고르세요
1. 전화번호 입력
2. 프로그램 종료
무엇을 원하시죠? : 1
이름 : 홍길동
전화번호 : 010-5462-2222
생년월일 : 9001004
===================================
이 름 : 홍길동
전화번호 : 010-5462-2222
생년월일 : 9001004
원하는 작업을 고르세요
1. 전화번호 입력
2. 프로그램 종료
무엇을 원하시죠? :
※참고 - nextInt()와 nextLine() 사용 시 주의점
위의 예에서 중간에 이해가 안되어서 주석처리를 한 부분이 있다.
choice = typing.nextInt();
typing.nextLine();
이 부분인데, 알고 있는 상식 선에서는 nextLine이 굳이 필요하지 않을 것인데
해당 부분을 제외하고 코딩을 하게 되면
아래처럼 결과값이 1과는 다르게 출력된다.
1. nextLine를 넣었을 때 결과값.
원하는 작업을 고르세요
1. 전화번호 입력
2. 프로그램 종료
무엇을 원하시죠? : 1
이름 :
2. nextLine를 넣지 않았을 때 결과값.
원하는 작업을 고르세요
1. 전화번호 입력
2. 프로그램 종료
무엇을 원하시죠? : 1
이름 : 전화번호 :
이렇게 되는 이유를 알아보자.
nextInt() 메소드를 실행할 때, 우리는 위처럼 숫자 1을 입력한다.
그리고 나서 무엇을 치는가? 엔터!!!!! 엔터를 친다!!!!
그런데 이 멍청한 nextInt() 메소드는 숫자까지만 입력을 받고나서
이 엔터를 없애지 못한다!!!!!
그럼 이 남아있는 엔터는 계속 메모리에 남아있다가 다음 입력을 받을 때 사용이 되어버린다.
그래서 2번 예처럼 이름 : 을 써야할 곳에 그 엔터가 바로 입력이 되어버린 후 전화번호를 입력 받는다.
원인을 알았으니 해결을 해야지.가장 쉬운 해결 방법은 위처럼 딱히 입력값을 어디 변수에 저장하지 않도록 한
스캐너변수이름.nextLine();
이거 한줄이면 해결된다.
그러면 엔터는 저 한 줄로 그냥 메모리에서 소모되어 버리고
다음 스캐너로 입력을 받을 수 있다.
다른 방법은
스캐너변수를 추가로 더 만들어서 입력을 따로 받아버리면 된다.
그런데 굳이...?
참고만 해라.
접근제어자(public, protected, default, private)
접근이란 패키지나 클래스 및 인터페이스 등 안에 있는 멤버가 참조하는 것을 말한다.
예를 들어 다른 패키지에서 사용 못하게 하여 데이터를 보호한다던가
어디서든 접근이 가능하게 만들고 싶다는 등
접근의 제어를 용이하게 하기 위해 만들어진 것이다.
public
어떤 외부에서도 접근 가능할 수 있도록 자유롭게 열어놓는다는 뜻이다.
퍼블릭으로 선언된 것들은 같은 패키지 뿐만이 아니라 다른 패키지에서도 참조가 가능하다.
다만 클래스의 경우, 파일명과 같은 이름을 가진 클래스만 public 사용이 가능하다.
그렇게 만든 이유는 파일에 대표 클래스를 가지게 하는 것이 코드 가독성에 도움이 되기 때문이라 한다.
(클래스, 필드, 생성자, 메소드 모두 사용 가능)
protected
같은 패키지 또는 다른 패키지의 자식 클래스에서만 사용이 가능.
다른 패키지의 일반 클래스에서는 사용 불가하게 만든다.
(클래스에서는 사용 불가)
default
어떤 접근제한자도 정의되지 않는 경우를 말함.
같은 패키지에 소속된 클래스에서만 사용이 가능
(클래스, 필드, 생성자, 메소드 모두 사용 가능)
private
외부에서 사용될 수 없도록 함.
같은 클래스 내에서만 사용될 수 있게 만든다.
(클래스에서는 사용 불가)
정리하면
접근 제어자 | 같은 클래스의 멤버 | 같은 패키지의 멤버 | 자식 클래스의 멤버 | 그 외의 영역 |
public | O | O | O | O |
protected | O | O | O | X |
default | O | O | X | X |
private | O | X | X | X |
final
final로 선언된 변수는 값이 할당되면 항상 같은 값을 가진다.
즉, 한번 값을 넣어두면 무슨일이 일어나더라도 값이 변하지 않는다.
심지어 변수가 객체를 참조하고 있어서 객체가 변하더라도 값은 변하지 않는다.
final은 변수뿐만이 아니라 클래스, 메소드, 객체, 변수와 매개변수 모두에게 붙을 수 있다.
클래스는 상속이 불가해지고
메소드는 오버라이딩이 불가능해지고
객체는 재생성이 불가능해지고
변수와 매개변수는 수정이 불가해진다.
final은 선언시 초기값을 정해놓을 수도 있고
아래처럼 변수만 선언을 해놓고 나중에 생성자로 초기화를 시키는 방법도 가능하다.
class seller {
int numOfApple;
int profit ;
final int ApplePrice ;
// final의 선언과 동시에 값을 지정해야하나, 생성자로 초기화 지정을 할 수 있다.
// 초기 데이터를 생성자로 만든다.
public seller(int money, int appleNum, int price) {
profit = money;
numOfApple = appleNum;
ApplePrice = price;
}
}
'코딩수업 > AWS 클라우드환경 네이티브' 카테고리의 다른 글
8/9 자바(Java) 오버라이딩, GUI 맛보기, toString (2) | 2022.08.09 |
---|---|
8/8 자바(Java) 클래스 활용 연습, comparTo 함수, 상속 (0) | 2022.08.08 |
8/4 자바(Java) 메소드(method), 메모리를 사용하는 방식, 클래스 변수와 인스턴스 변수, 기본형과 참조형 변수 차이. 생성자, 메소드/생성자 오버 로딩, this (0) | 2022.08.04 |
7/29 자바(Java) 클래스와 객체 (참조 변수의 이해, Static ) (0) | 2022.07.29 |
7/28 자바(Java) 다차원 배열, 가변 배열, 배열의 복사, 다차원 배열 연습 문제 (0) | 2022.07.28 |
댓글