Java

새싹체험_java_1022

coolcode 2022. 10. 22. 09:47

1022

생성자 ::  new 연산자로부터 클래스 객체를 생성할때 호출되어 객체의 초기화 역할을 함 

자바의 클래스는 생성자가 반드시 존재해야 함/ 클래스를 만들때 생성자 선언을 생략했다면 자바 컴파일러는 내용이 비어있는 기본 생성자를 자동으로 만들어 줌

int[] array = {1,2,3}; 

생성자는 리턴타입이 없고(리턴 값이 없는게 아니라 리턴 타입 자체가 없다는 의미) 클래스 이름과 동일함

필드를 선언할때 초기값을 주면 해당 클래스로 부터 생성되는 객체들은 모두 같은 값을 갖게 됨

생성자에서 매개변수로 매개값을 받아 필드 초기화를 하면 필드의 데이터를 (외부에서 제공되는)다양한 데이터 값으로 초기화 할 수 있음 

객체 초기화란 필드를 초기화 하거나 메서드를 호출해서 객체를 사용할 준비를 하는 것 

생성자 오버로딩(객체를 다양한 방법으로 생성하기 위해) :: 매개변수의 타입 갯수 순서를 다르게 하는 메서드 오버로딩과 같음 / 생성자 내에서 다른 생성자를 호출할때 this()를 사용함 > 자주 사용하지는 않지만 코드 개선시 간혹 사용함 

생성자 특징 정리 

생성자 명시 안하면 자바 컴파일러는 기본생성자를 자동으로 만든다

그러나 생성자를 명시하면 만들지 않는다 

반환타입이 없다

생성자는 클래스 이름과 같은 이름이다

> 객체를 생성하면 생성자가 호출되고 필드 초기화와 메소드 호출 등 객체를 사용할 준비를 한다

this() :: 생성자 내에서 다른 생성자 호출할때 사용 (첫줄에만 올 수 있음)

public Student2(int studentID) {
		this(studentID, null, 0);
		
	}

public Student2(int studentID, String name) {
    this(studentID, name, 0);
    this.studentID = studentID;
    this.name = name;

}

public Student2(int studentID, String name, int age) {
    this.studentID = studentID;
    this.name = name;
    this.age = age;
}

=====================================================1교시 끝

생성자 초기화 실습 

class Car {
	private String color;
	private int speed;
	
	
	public Car() {
		// TODO Auto-generated constructor stub
	}


	public Car(String color, int speed) {
		this.color = color;
		if(speed < 30 || speed > 300) {
			this.speed = 30;
		}else {
			this.speed = speed;
		}
		carProfile();
	}
	
	public void carProfile() {
		System.out.println("color :: " + color);
		System.out.println("speed :: " + speed);
	}
}

scanner 클래스 입력값으로 생성자 초기화

public static void main(String[] args) {
		
    Scanner scanner = new Scanner(System.in);
    System.out.println("색상 입력 >");
    String color = scanner.nextLine();
    System.out.println("속도 입력 >");
    int speed = scanner.nextInt();

    new Car(color, speed);
}
// console 
색상 입력 >
red
속도 입력 >
150
color :: red
speed :: 150

객체(클래스) 배열 :: 객체를 담는 배열로 객체의 주소값을 담는다

 Car[] car = new car[5];
 car[0] = new Car("red", 150);
 car[1] = new Car("yellow", 140);
 car[2] = new Car("pink", 130);
 car[3] = new Car("blue", 120);
 car[4] = new Car("purple", 110);

book 클래스의 객체 배열 생성 실습 

class Book {
	String title;
	String author;
	
	public Book(String title, String author) {
		this.title = title;
		this.author = author;
	}
	
	public void showInfo() {
		System.out.println("title :: " + title);
		System.out.println("author :: " + author);
	}
}

** 배열 요소(객체 원소)에 도트연산자(.)를 사용해서 필드나 메소드에 접근 가능

public class Ex01 {
	public static void main(String[] args) {
		// 객체를 생성한게 아니고 Book 타입의 배열을 생성한것
		Book[] books = new Book[3];
		
		books[0] = new Book("제목1", "홍길동1");
		books[1] = new Book("제목2", "홍길동2");
		books[2] = new Book("제목3", "홍길동3");
		
		for(Book b : books) {
			System.out.println(b.author);
			System.out.println(b.title);
			System.out.println();
			b.showInfo();
		}
	}
}

필드 생성자 메서드 총 정리 실습 >> 회원 클래스/ 회원 서비스 클래스 생성 후 회원 등록, 정보 조회, 수정 기능 실행

=====================================================2교시 끝

접근제한자 :: public / protected / private >> 생성자, 필드, 메서드 접근제한 동일

public : 외부에서 자유롭게 사용 가능(다른 패키지에서도 사용 가능) / 단 다른 패키지에 있는 클래스 사용시 import 필요

protected : 같은 패키지와 자식클래스에서 사용 가능 

private : 클래스 외부에서는 사용 불가

(default) :  같은 패키지에서 사용 가능 

*내일 상속 파트 나갈때 자식 클래스에 대해 자세히 배울 예정

package pack01;

// 같은 패키지에서 접근가능
class B {
	
}

// 외부 패키지에서도 접근가능
public class A {

}

package pack01;

public class ClassTest1 {
	public static void main(String[] args) {
		new A();
		new B();
	}
}

// 외부 패키지에서 클래스 import 해서 사용하기

package pack02;

import pack01.A;

public class ClassTest2 {
	public static void main(String[] args) {
		new A();
//		new B();
	}
}

자바는 클래스 멤버(필드, 메서드)를 따로 구분해서 선언할 수 있도록 함

클래스로부터 객체가 생성이 될 때 객체가 가지고 있는 멤버를 인스턴스 멤버라 하고, 객체가 가지고 있지 않고 클래스에 고정된 멤버를 정적 멤버라고 함 

** 예를 들어 원주율(PI) 같은 경우엔 해당 필드를 클래스(Math클래스)에  
고정 멤버로 선언을 하고 필드를 사용하는 모든 객체가 공유될 수 있도록 한다

double a = Math.PI;
System.out.println("a :: " + a );
// a :: 3.141592653589793

** 인스턴스 멤버 :: 객체를 생성한 후 사용할 수 있는 필드와 메서드

** static 멤버 :: 클래스에 고정된 (메모리상에 고정된) 멤버로서 객체를 생성하지 않고 사용할 수 있는 필드와 메서드임

> 정적 필드와 정적 메서드는 static 키워드를 추가적으로 붙이면 됨

[java 메모리 영역]

스택 영역 :: 메모리의 스택 영역은 메서드의 호출과 관계되는 지역변수와 매개변수가 저장되는 영역임

힙영역 :: 메모리의 힙 영역은 사용자가 직접 관리할 수 있는 영역임 / 힙 영역은 사용자에 의해 메모리 공간이 동적으로 할당되고 해제 되는 곳 > new 연산자를 이용해서 메모리를 할당하는 것은 전부 힙 영역에 할당 / 힙에 보관되는 메모리는 메소드 호출이 끝나도 사라지지 않고 유지되어 이러한 메모리 관리는 jvm의 가비지컬렉터가 관리함 

메소드 영역 (클래스 영역  / static 영역)

메소드 영역에서는 '.class' 파일(컴파일러에 의해 생성된 java bytecode 파일)들을 읽어들여 각각의 클래스 별로 필드 데이터, 메소드, 생성자 등을 저장하는 영역 / 일반적으로 static으로 선언된 값들 역시 메소드 영역에 저장됨 

** 정적 메서드 안에서는 인스턴스 필드나 인스턴스 메서드를 사용할 수 없음 

=====================================================3교시 끝

** static int boxID = 0;

static 필드 :: 메모리상에서 정적임(공유되는 전역변수) >  프로그램 시작 시(실행하자마자 작성한 클래스 파일 모두 로드하고 메소드 영역에 자원들을 보관) 메모리의 최상단(method영역) 에 할당됨 

** int idNum = 0;

인스턴스 필드 :: 객체 생성시 메모리의 힙영역에 할당됨

인스턴스 변수는 객체마다 공유되지 않고 static 변수는 모든 객체에 공유됨

class Player{
	String name = "홍길동";
	static String gameID = "기사";
	
	public static void gamePlay() {
	    System.out.println(gameID);
        // System.out.println(name); // 사용 불가
	System.out.println(new Player().name); 
	}
}

public class Ex02 {
	public static void main(String[] args) {
		Player.gamePlay();
	}
}

실습

// Machine클래스 만들고 필드는 private static int ticketCnt = 10; 으로 함
// 티켓수를 출력해주는 showTicket 정적 메서드를 만든다
// 정수 하나를 매개변수로 받아서 티켓을 구입하는 buyTicket 메서드를 만든다
// 받은 정수가 티켓 수보다 많으면 구입할 수 없고 티켓수가 0되면 프로그램 종료

** 모든 객체들한테 업데이트 된 데이터가 공유되어야 하는 경우 static으로 선언하면 됨

class Machine{
	private static int ticketCnt = 10;
	
	public static void showTicket() {
		System.out.println(ticketCnt);
	}
	
	public void buyTicket(int a) {
		if(a > ticketCnt) {
			System.out.println("수량 부족 ! 구입 불가 ");
			return;
		}else {
			System.out.println("티켓을 구입했습니다");
			ticketCnt -= a;
			System.out.println("남은 티켓 수는 :: " + ticketCnt);
		}
        if(ticketCnt == 0) {
			System.out.println("티켓판매종료");
			System.exit(0); // 메인메서드가 종료되면 내부적으로 호출되어 종료된다고 함 
            				// status가 들어갈 인자값에 0 이외의 수가 들어가면 비정상 종료로 인식
		}
	}
}


public class Ex03 { 
	public static void main(String[] args) {
		Machine machine = new Machine();
//		Machine.showTicket();
//		machine.buyTicket(5);
		
		Scanner scanner = new Scanner(System.in);
		
		while(true){
			System.out.println("1.남은 티켓수 보기 2. 티켓 구입 > ");
			int num = scanner.nextInt();
			switch (num) {
			case 1:
				System.out.println("남은 티켓 수 :: ");
				Machine.showTicket();
				break;
			case 2:
				System.out.println("구매할 티켓수 입력 >");
				int ticketCnt = scanner.nextInt();
				machine.buyTicket(ticketCnt);
				break;
			}
			scanner.close();
		}
	}
}

=====================================================4교시 끝

static 초기화블록 / 인스턴스 초기화 블록

public class Ex04 {
	// static 필드 초기화 역할 (메인 메서드 보다 먼저 실행됨)
	static { 
		System.out.println("static 블록");
	}
	
	// 인스턴스 초기화 블록 (객체생성시 초기화 역할 / 생성자와 역할은 같지만 매개값 없음)
	{
		System.out.println("인스턴스 블록");
	}
	
	public static void main(String[] args) {
		System.out.println("메인 메서드 시작");
		new Ex04();
		System.out.println("----------");
		new Ex04();
		System.out.println("메인 메서드 끝");
		
	}
    
    // console
    static 블록
    메인 메서드 시작
    인스턴스 블록
    ----------
    인스턴스 블록
    메인 메서드 끝

static final 필드 ::  정적 불변의 상수 > 원주율PI 등이 해당됨

statci final 타입 상수 = 초기값; >> 반드시 선언과 동시에 초기값을 지정해야함

>> 클래스에 대한 지정 예약어 (final / abstract)

>> 필드에 대한 지정 예약어 (static / final / staic final)

>> 메서드에 대한 지정 예약어 (static / final / staic final / abstract) 

** 보통 프로그래밍에서 상수는 static final을 의미함

** static :: 메모리에 미리 올린다는 지정 예약어

class Person {
	static final String NATION = "KOREA";
	// 정적 불변의 상수(메모리의 최상단 영역 = 메서드영역)에 올라가므로 반드시 선언과 동시에 초기화
	// 역할 공용데이터
	final String SSN;
	// 불변의 인스턴스 상수
	// 선언과 동시에 초기화 하거나 혹은 생성자에서 단 한번만 초기화가 이루어진다
	
	
	String name;
	int age;
	
	public Person(String ssn, String name, int age) {
		SSN = ssn;
		this.name = name;
		this.age = age;
	}
}

public class Ex05 {
	public static void main(String[] args) {
		Person person = new Person("NY", "홍길동", 20);
		System.out.println(person.SSN); 
		System.out.println(person.name); 
		System.out.println(person.age); 
		
	}
}

****내일 내부 클래스 보고 상속으로 넘어갈 예정

*** 콘솔창 한글깨짐현상 해결

window > preferences > general > workspace > text file encoding "utf-8" 확인 

run > runconfiguration > common탭 > encoding "EUC-KR" 직접 입력