[JAVA] 생성자를 사용하여 클래스 설계하여 객체 생성

 

생성자가 뭘까

1. 생성자가 뭘까?

2. 생성자를 사용하는 방법(문법)

3. 생성자에는 기본생성자와 사용자 정의 생성자가 있다

4. 생성자 오버로딩이란 무엇일까?

5. 생성자는 인스턴스화 될 때 가장 먼저 수행되는 코드이다.

 

용어 정리


● 객체 : 객체 지향 프로그램의 대상, 생성된 인스턴스
● 클래스 : 객체를 프로그래밍 하기위해 코드로 정의해 놓은 상태 
● 인스턴스 : new 키워드를 사용하여 클래스를 메모리에 생성한 상태
● 멤버 변수 : 클래스의 속성, 상태, 특성
● 메서드 : 멤버 변수를 이용하여 클래스의 기능을 구현한 함수 
● 참조 변수 : 메모리에 생성된 인스턴스를 가리키는 변수
● 참조 값 : 생성된 인스턴스의 메모리 주소 값

 

인스턴스 (instance)


● 클래스는 객체의 속성을 정의 하고, 기능을 구현하여 만들어 놓은 코드 상태(설계도면) 입니다.
● 실제 클래스 기반으로 생성된 객체(인스턴스)는 각각 다른 멤버 변수 값을 가지게 됩니다. 
● 가령, 학생의 클래스에서 생성된 각각의 인스턴스는 각각 다른 이름, 학번, 학년등의 값을 가지게 됩니다.
● new 키워드를 사용하여 인스턴스 생성

 

힙 메모리 

● 생성된 인스턴스는 동적 메모리(heap memory) 에 할당됨
● C나 C++ 언어에서는 사용한 동적 메모리를 프로그래머가 해제 시켜야 함 ( free() 난 delete 이용)
● 자바에서 Gabage Collector 가 주기 적으로 사용하지 않는 메모리를 수거
● 하나의 클래스로 부터 여러개의 인스턴스가 생성되고 각각 다른 메모리 주소를 가지게 됨

 

 

생성자

● 객체를 생성할 때 new 키워드와 함께 사용 - new Student();
● 생성자는 일반 함수처럼 기능을 호출하는 것이 아니고 객체를 생성하기 위해 new 와 함께 호출 됨
● 객체가 생성될 때 변수나 상수를 초기화 하거나 다른 초기화 기능을 수행하는 메서드를 호출 함
● 생성자는 반환 값이 없고, 클래스의 이름과 동일
● 대부분의 생성자는 외부에서 접근 가능하지만, 필요에 의해 private 으로 선언되는 경우도 있음

 

기본 생성자 (default constructor)

● 클래스에는 반드시 적어도 하나 이상의 생성자가 존재한다. 
● 클래스에 생성자를 구현하지 않아도 new 키워드와 함께 생성자를 호출할 수 있음
● 클래스에 생성자가 하나도 없는 경우 컴파일러가 생성자 코드를 넣어 줌
● public Student(){}

 

생성자 만들기

● 컴파일러가 제공해 주는 기본 생성자외에 필요에 의해 생성자를 직접 구현 할 수 있음

 

Student.java

public class Student {

 

public int studentNumber;

public String studentName;

public int grade;

 

public Student(int studentNumber, String studentName, int grade) {

this.studentNumber = studentNumber;

this.studentName = studentName;

this.grade = grade;

}

 

public String showStudentInfo() {

return studentName + "학생의 학번은 " + studentNumber + "이고, " + grade + "학년 입니다.";

}

}

StudentMainTest.java

public class StudentMainTest {

 

public static void main(String[] args) {

 

//Student studentLee = new Student();

 

Student studentLee = new Student(12345, "Lee", 3);

 

String data = studentLee.showStudentInfo();

System.out.println(data);

}

 

}

오버로딩

여러가지 생성자를 정의하는 생성자 오버로딩(overloading)


생성자 정의 하기

생성자를 구현해서 사용할 수 있음
클래스에 생성자를 따로 구현하면 기본 생성자 (default constructor)는 제공되지 않음
생성자를 호출하는 코드(client 코드)에서 여러 생성자 중 필요에 따라 호출해서 사용할 수 있음

 

UserInfo.java

public class UserInfo {

 

public String userId;

public String userPassWord;

public String userName;

public String userAddress;

public String phoneNumber;

 

public UserInfo(){}

 

public UserInfo(String userId, String userPassWord, String userName) {

this.userId = userId;

this.userPassWord = userPassWord;

this.userName = userName;

}

 

public String showUserInfo() {

return "고객님의 아이디는 " + userId + "이고, 등록된 이름은 " + userName + "입니다.";

}

}

UserInfo.java

public class UserInfoTest {

 

public static void main(String[] args) {

 

UserInfo userLee = new UserInfo();

userLee.userId = "a12345";

userLee.userPassWord = "zxcvbn12345";

userLee.userName = "Lee";

userLee.phoneNumber = "01034556699";

userLee.userAddress = "Seoul, Korea";

 

System.out.println(userLee.showUserInfo());

 

UserInfo userKim = new UserInfo("b12345", "09876mnbvc", "Kim");

System.out.println(userKim.showUserInfo());

}

}

 

 

참조 자료형 변수

● 클래스형으로 변수를 선언
● 기본 자료형은 사용하는 메모리의 크기가 정해져 있지만, 참조 자료형은 클래스에 따라 다름
● 참조 자료형을 사용 할때는 해당 변수에 대해 생성하여야 함 (String 클래스는 예외적으로 생성하지 않고 사용할 수 있음)

예제

 

전사 궁수 마법사 3개의 클래스를 설계하여 

객체를 생성해보자

전사 클래스

public class Warrior {

 

// 참조 타입

String name;

// 기본 데이터 타입

int power;

int hp;

 

public Warrior(String name) {

this.name = name;

power = 14; //this.power

hp = 100; //this.hp

}

 

public void attackArcher(Archer archer) {

// archer 주소값을 넘겨 받은 상태 이다.

// power (값 10)

archer.beattacked(this.power);

System.out.println("궁수를 공격 합니다");

}

 

public void attackWizard(Wizard wizard) {

wizard.beattacked(this.power);

System.out.println("마법사를 공격 합니다");

// 마법사를 공격 함

}

 

//내가 공격을 받다

public void beAttacked(int power) {

if(this.hp<=0) {

System.out.println("이미 죽었습니다");

this.hp = 0;

}else {

this.hp = hp - power;

}

}

public void showInfo() {

System.out.println("===상태창===");

System.out.println("닉네임 : " + name);

System.out.println("공격력 : " + power);

System.out.println("체력 : " + hp);

}

 

}

궁수 클래스

public class Archer {

 

String name;

int power;

int hp;

 

public Archer(String name) {

this.name = name;

this.power = 15;

this.hp = 80;

}

 

public void attackWarrior(Warrior warrior) {

// 전사를 공격합니다.

warrior.beAttacked(this.power);

System.out.println("전사를 공격 합니다");

}

 

public void attackWizard(Wizard wizard) {

// 마법사를 공격합니다

wizard.beattacked(this.power);

System.out.println("마법사를 공격 합니다");

}

// 내가 공격 당하다

public void beattacked(int power) {

if(this.hp<=0) {

this.hp = 0;

System.out.println("이미 죽었습니다");

}else {

this.hp = hp - power;

if(this.hp<=0) {

this.hp = 0;

System.out.println("이미 죽었습니다");

}

}

}

 

public void showInfo() {

System.out.println("===상태창===");

System.out.println("닉네임 : " + name);

System.out.println("공격력 : " + power);

System.out.println("체력 : " + hp);

}

}

마법사 클래스

public class Wizard {

 

String name;

int hp;

int power;

 

public Wizard(String name) {

this.name = name;

power =20;

hp =50;

}

 

public void attackWarrior(Warrior warrior) {

// 전사를 공격합니다

warrior.beAttacked(this.power);

System.out.println("전사를 공격 합니다");

}

 

public void attackArcher(Archer archer) {

// 궁수를 공격합니다

archer.beattacked(this.power);

System.out.println("궁수를 공격 합니다");

}

 

public void beattacked(int power) {

if(this.hp<=0) {

System.out.println("이미 죽었습니다");

this.hp = 0;

} else {

this.hp = hp -power;

}

}

 

public void showInfo() {

System.out.println("====상태창====");

System.out.println("닉네임 : " + name);

System.out.println("공격력 : " + power);

System.out.println("체력 : " + hp);

}

}

객체

3명 중 한명의 체력이 0이 될 때까지 반복

public class MainTest1 {

 

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

 

Warrior warrior1 = new Warrior("전사1");

Archer archer1 = new Archer("궁수1");

Wizard wizard1 = new Wizard("마법사1");

 

 

// System.out.println("-------------");

// System.out.println(" 1 : " + (archer1.hp <= 0));

// System.out.println(" 2 : " + (warrior1.hp <= 0));

// System.out.println(" 3 : " + ( wizard1.hp <= 0));

 

//System.out.println(archer1.hp);

boolean flag = true;

while (flag) {

if(archer1.hp <= 0 || warrior1.hp <= 0 || wizard1.hp <= 0) {

break;

 

}

System.out.println("누가 공격하시겠습니까? ");

System.out.println("1. 전사 2. 궁수 3. 마법사");

int a = sc.nextInt(); // 누가

System.out.println("누구를 공격하시겠습니까? ");

System.out.println("1. 전사 2. 궁수 3. 마법사");

int b = sc.nextInt(); // 누구를

if (a == 1 && b == 2) {

warrior1.attackArcher(archer1);

archer1.showInfo();

} else if (a == 1 && b == 3) {

warrior1.attackWizard(wizard1);

wizard1.showInfo();

} else if (a == 2 && b == 1) {

archer1.attackWarrior(warrior1);

warrior1.showInfo();

} else if (a == 2 && b == 3) {

archer1.attackWizard(wizard1);

wizard1.showInfo();

} else if (a == 3 && b == 1) {

wizard1.attackWarrior(warrior1);

warrior1.showInfo();

} else if (a == 3 && b == 2) {

wizard1.attackArcher(archer1);

archer1.showInfo();

} else if (a == b) {

System.out.println("자기 자신을 때릴 수 없습니다");

} else {

System.out.println("잘못 입력하셨습니다");

}

}

System.out.println("게임 종료");

 

// while(archer1.hp>0) {

// warrior1.attackArcher(archer1);

// }

 

// warrior1.showInfo();

// archer1.showInfo();

// wizard1.showInfo();

 

} // end of main

 

}

결과

누가 공격하시겠습니까?

1. 전사 2. 궁수 3. 마법사

1

누구를 공격하시겠습니까?

1. 전사 2. 궁수 3. 마법사

2

궁수를 공격 합니다

===상태창===

닉네임 : 궁수1

공격력 : 15

체력 : 66

누가 공격하시겠습니까?

1. 전사 2. 궁수 3. 마법사

1

누구를 공격하시겠습니까?

1. 전사 2. 궁수 3. 마법사

2

궁수를 공격 합니다

===상태창===

닉네임 : 궁수1

공격력 : 15

체력 : 52

누가 공격하시겠습니까?

1. 전사 2. 궁수 3. 마법사

1

누구를 공격하시겠습니까?

1. 전사 2. 궁수 3. 마법사

2

궁수를 공격 합니다

===상태창===

닉네임 : 궁수1

공격력 : 15

체력 : 38

누가 공격하시겠습니까?

1. 전사 2. 궁수 3. 마법사

1

누구를 공격하시겠습니까?

1. 전사 2. 궁수 3. 마법사

2

궁수를 공격 합니다

===상태창===

닉네임 : 궁수1

공격력 : 15

체력 : 24

누가 공격하시겠습니까?

1. 전사 2. 궁수 3. 마법사

1

누구를 공격하시겠습니까?

1. 전사 2. 궁수 3. 마법사

2

궁수를 공격 합니다

===상태창===

닉네임 : 궁수1

공격력 : 15

체력 : 10

누가 공격하시겠습니까?

1. 전사 2. 궁수 3. 마법사

1

누구를 공격하시겠습니까?

1. 전사 2. 궁수 3. 마법사

2

이미 죽었습니다

궁수를 공격 합니다

===상태창===

닉네임 : 궁수1

공격력 : 15

체력 : 0

게임 종료