새싹체험_java_1022
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" 직접 입력