본문 바로가기
java

22.11.07 클래스 인스턴스화 및 생성자

by SoulMania 2023. 2. 13.

 

클래스로 부터 new 라는 연산자를

ch06.zip
0.01MB
New Document 2022-11-07 162124.xlsx
0.01MB
설명.txt
0.02MB

사용해서 참조변수에 넣어주는 것을 인스턴스화 라고 한다.
객체랑 같은 개념이다


    package ch06;

public class MemberService {

public static void main(String[] args) {

    Member user1 = new Member("administrator", "password"); //이것이 기준이 되는값... 회원가입.
    user1.login("administrator", "password");
    user1.logout();

    System.out.println("---------------------------------------------------------------------------------------------");
    Member user2 = new Member("administrator", "password"); //이것이 기준이 되는값... 회원가입.
    user2.login("admin", "passwor");
    user2.logout();

// user1.login(id, password)

}

}


    package ch06;

public class Member {

String name;
String id;
String password;
boolean state = false;
int age;


Member(String id, String password){  ///생성자
    this.id=id;
    this.password=password;

}



void login(String id, String password) {
    if(this.id.equals(id) && this.password.equals(password)) {
      System.out.println("로그인 되었습니다.");
      state = true;
        return;
        }
      System.out.println("로그인에 실패하였습니다.");
}

void logout() {
    if(this.state) {
      System.out.println("로그아웃 되었습니다.");
        return;
        }
    System.out.println("로그인 정보가 없습니다.");


}

}


    package ch06;

//이 클래스는 자동차설계도 이다.
/*클래스 멤버
-field : 데이터 저장
[접근제한자] [제어자] 타입 필드명[=값];
-constructor : object생성method
[접근제한자] [제어자] 클래스(생성자)명(매개변수){}
-method : 기능, 동작
[접근제한자] [제어자] 리턴유형 메소드(매개변수){}

*/
public class Car02 {
// -field : 데이터 저장
//전역변수는 타입에 따라 자동초기화가 된다.
String color; // 색상 null
String nation; //제조국가 null
int price; // 가격 0
boolean isGas; //가스차량 false

// -constructor : object생성method
// [접근제한자] [제어자] 클래스(생성자)명(매개변수){}

Car02(){
    System.out.println("default constructor Call !!!"); //여기에 생성했는데 Car02_Main에서 표츌된다. 한마디로 객체 생성시에 참조변수에 주소를 할당하고 생성자를 생성한다는 뜻!!!
} //이 생성자는 일부러 동작하는 프로세스를 알기 위해 작성해놓은것.. 원래는 자동으로 생성되고 눈에 보이지는 않는다.

//this()  p212 -->코드중복을 줄이기 위해!!!
//색상, 제조국가의 값을 받아서 필드초기화 하는 생성자
Car02(String color, String nation){
    //Car02("red", "대한민국", 100); 생성자가 동일 클래스안에 존재하는 다른 생성자를 호출 할 수 없다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    //The method Car02(String, String, int)
    //is undefined for the type Car02

// this("red", "대한민국", 100); //--->>>이걸 만나는 순간 아래 3개 짜리 생성자로 가버린다. 그 생성자를 다 실행 하고 아래 것이 실행된다.
this(color, nation, 100); // myCar5 입력값이 2개니까 변수개수가 안맞으므로 밑에 3개짜리 생성자 호출해서 입력값 Black, Korea, 100을 출력!!!!!!!!!!!!!!
//Constructor call must be
//the first statement in a constructor --->>>this()는 생성자 첫번째 줄에서 콜해야한다.!!!!! 그래야 사용 가능
//this()는 반드시 생성자내
//반드시 첫 줄에 작성해야한다.-->주석은 제외

    //동일 클래스 내에서 생성자는 또 다른 생성자를 호출할 수 X
    //이 때는 this()를 사용해야 한다.

// this.color=color; //---> 아래 3개 짜리 생성자에서 실행됐으므로 주석 처리 또는 삭제
// this.nation=nation; //---> 아래 3개 짜리 생성자에서 실행됐으므로 주석 처리 또는 삭제
System.out.println("String 2개인 생성자를 호출");
// System.out.println("c="+color); // ---->>> Black
// System.out.println("n="+nation); // ---->>> Korea 둘다 모두 저장되긴 하지만 this()로 인해 중간에 아래 인자 3개 짜리로 가서 그 생성자 값을 출력

    //그래서 저 this() 에서 색상과 제조국을 Black과 Korea를 넣어주고 100은 갯수 맞춰주는 용도로 쓰여진다.this(color, nation, 100); 


}

//색상, 제조국가, 가격의 값을 받아서 필드초기화 하는 생성자
Car02(String color, String nation, int price){
    this(color, nation, price, false);  //--->외부에서 받은 3개는 재전달하고 true는 받은게 없으니 마음대로 값전달. 변수는 맞춰서 전달해야하므로

// this.color=color;
// this.nation=nation;
// this.price=price;
System.out.println("String 2개 와 int 1개인 생성자를 호출");
}

//색상, 제조국가, 가격, 가스차량 여부의 값을 받아서 필드초기화 하는 생성자
Car02(String color, String nation, int price, boolean isGas){
    this.color=color; 
    this.nation=nation; 
    this.price=price;
    this.isGas=isGas;
    System.out.println("String 2개 와 int 1개, boolean1개인 생성자를 호출");
}


//색상의 값을 받아서 필드초기화 하는 생성자
Car02(String color){
    this.color=color; //--->객체가 만들어졌을 그 당시의 변수..n 즉 참조변수를 뜻한다. 
    //this는 이 클래스 객체의 참조변수
    //필드명이 매개변수명과 동일하면
    //반드시 this.필드명 사용
    //필드와 매개변수를 구분하기 위해.
    System.out.println("String 1개인 생성자를 호출");
}

//가격의 값을 받아서 필드초기화 하는 생성자
Car02(int price){
    this.price=price; //--->객체가 만들어졌을 그 당시의 변수..n 즉 참조변수를 뜻한다. 
    System.out.println("int 1개인 생성자를 호출");
}

//가스차량 값을 받아서 필드초기화 하는 생성자
Car02(boolean isGas){
    this.isGas=isGas; //--->객체가 만들어졌을 그 당시의 변수..n 즉 참조변수를 뜻한다. 
    System.out.println("boolean 1개인 생성자를 호출");
}

// -method : 기능, 동작
// [접근제한자] [제어자] 리턴유형 메소드(매개변수){}

// public static void main(String[] args) {
//
// }

}


    package ch06;

//이 클래스는 Car02에 대한 실행 클래스 이다.
public class Car02_Main {
//field
//생성자
//메소드

// [접근제한자] [제어자] 리턴유형 메소드명(입력값-argument) {}
static void showField(Car02 car) { //동일 클래스 내에 메소드를 호출 할 수 있는데 그중에 static이 붙은것 끼리 호출할 수 있다. ---> 메소드를 만든 것.
//생성자 객체 선언 할때 타입이 Human03 이었기 때문에 그것으로 선언한다. 다시 말해 Human03도 클래스의 한 형태 이다.
//필드값 get: 문법> 참조변수.필드명 --->덮어 씌울거라서 앞에 타입을 지운다.
System.out.println("color : "+car.color);
System.out.println("nation : "+car.nation);
System.out.println("price : "+car.price);
System.out.println("isGas : "+car.isGas);
System.out.println("----------------------------------------------------------------------------------------");

}



public static void main(String[] args) {
    //참조변수선언 및 객체 생성
    Car02 myCar1 = new Car02(); //상속에서는 클래스 타입이 클래스 명과 다른경우도 있다. 기본 생성자는 이 행위를 하면 Car02에 생성이 되었을것...인자가없는 기본 생성자.
    //new Car02() 매개변수가 없는 기본생성자
    System.out.println(myCar1); // ch06.Car02@15db9742 이런식으로 주소가 나오면 힙 영역에 객체생성이 완료되고 스택영역에 그 주소가 저장된다. 이때 기본 생성자 생성.
    System.out.println(myCar1.toString());

    System.out.println("----------------------------------------------------------------------------------------");
    //참조변수를 참조하여 
    //해당 객체의 필드에 접근.출력
    //참조변수명.메소드명(매개변수);
    //단, static이 있는 메소드를 호출시에는 참조변수x
    showField(myCar1);


    //참조변수를 참조하여 
    //해당 객체의 필드에 접근.출력
    //지금은 초기값

// System.out.println("myCar1.color : "+myCar1.color);
// System.out.println("myCar1.nation : "+myCar1.nation);
// System.out.println("myCar1.price : "+myCar1.price);
// System.out.println("myCar1.isGas : "+myCar1.isGas);
// System.out.println("----------------------------------------------------------------------------------------");

    //argument가 있는 생성자를 생성자호출 객체 생성
    //참조변수선언 및 객체 생성 - 색상 선택
    Car02 myCar2 = new Car02("black");
    showField(myCar2);

// //해당 객체의 필드에 접근.출력 //참조변수명.필드명
// System.out.println("myCar2.color : "+myCar2.color);
// System.out.println("myCar2.nation : "+myCar2.nation);
// System.out.println("myCar2.price : "+myCar2.price);
// System.out.println("myCar2.isGas : "+myCar2.isGas);
// System.out.println("----------------------------------------------------------------------------------------");

    //참조변수선언 및 객체 생성    - 가격제시
    Car02 myCar3 = new Car02(50000000);
    showField(myCar3);

// System.out.println("myCar3.color : "+myCar3.color);
// System.out.println("myCar3.nation : "+myCar3.nation);
// System.out.println("myCar3.price : "+myCar3.price);
// System.out.println("myCar3.isGas : "+myCar3.isGas);
// System.out.println("----------------------------------------------------------------------------------------");

    //참조변수선언 및 객체 생성    - 가스차량여부 제시
    Car02 myCar4 = new Car02(true);
    showField(myCar4);

// System.out.println("myCar4.color : "+myCar4.color);
// System.out.println("myCar4.nation : "+myCar4.nation);
// System.out.println("myCar4.price : "+myCar4.price);
// System.out.println("myCar4.isGas : "+myCar4.isGas);
// System.out.println("----------------------------------------------------------------------------------------");

    Car02 myCar5 = new Car02("Black", "Korea"); //----> Black과 Korea를 넣었다가 다시 다른값이 들어가는것... this()을 넣었기 때문에
    showField(myCar5);
    System.out.println("22222----------------------------------------------------------------------------------------");

    Car02 myCar6 = new Car02("Blue", "Indonesia", 50000000);
    showField(myCar6);
    System.out.println("33333----------------------------------------------------------------------------------------");

    Car02 myCar7 = new Car02("Aqua blue", "China", 50000000, true);
    showField(myCar7);

}//main 영역 안에서 또 다른 메소드를 콜 할수 있다.

}//class


    package ch06;

//이 클래스는 자동차관련 클래스이다.
public class Car_p223 {

//field-데이터 저장
//[접근제한자] [제어자] 타입 필드명[=값];

// int gas; //0으로 자동초기화
private int gas;
//private 접근제한자는 외부에서 접근불가 private는 동일 클래스 안이 아니면 모두 외부라고 인식한다.동일 소스안에서도 클래스가 다른것도 마찬가지다.
//외부에서 필드에 직접 접근시에는 아래와 같이 에러메시지가 뜬다.
//The field Car_p223.gas is not visible

//constructor-생성자. 주로 필드값을 초기화함
//[접근제한자] [제어자] 클래스명(매개변수리스트){}

//method-기능.동작
//[접근제한자] [제어자] 리턴유형 메소드명(매개변수리스트){}

//gas값을 설정하기
void setGas(int gas) {
    this.gas=gas;
}

//가스가 남아있니? - ok. 맞아, 남아있어 true
//              - no 틀렸어, 남아있지 않아 false
boolean isLeftGas() {
    if(gas==0) {//gas없다면 //조건만족시 실행코드
        System.out.println("gas 남아있지 않아요");
        return false; 
        //return 값;

    }
    System.out.println("gas 남아있어요");
    return true;

}

//주행하기(움직이기) 
void run() {
    while(true) {
        if(gas>0) {//조건만족실행코드 --> 가스가 있다면                        //gas앞에 this가 생략 된 것. 변수명이 다르기 때문에 굳이 this를 붙이지 않아도 된다.
            System.out.println("주행 중. - 현재gas : "+gas);//움직이기
            gas-=1; // gas=gas-1; //field gas의 값이 -1씩 감소된다.
        }else {//조건만족x실행코드 --> 가스가 없다면
            System.out.println("주행 불가. - 현재gas : "+gas);//움직이지 않기
            //return;//움직X    
            return; //메소드 종료
        }

    }//while 반복문

                //return 1;
                //return; //return이라는것 자체가 종료하겠다는 의미이다. 메소드 종료
                //return 값; 이런 형태로 리턴해주는게 원칙!!
                //void methods cannot return a value

}//run

}//class


    package ch06;

//이 클래스는 Car_p223 클래스의 실행클래스 이다.
public class Car_p223_Main {

//필드

//생성자
//메소드


public static void main(String[] args) {
    //자동차 객체 생성

// 클래스타입 변수명 = null; //이런식으로 나눠 선언해도 무관.
// Car_p223 myCar=null;
// myCar=new Car_p223;
// 변수명=new Car_p223();//이런식으로 나눠 선언해도 무관.
Car_p223 myCar = new Car_p223();

    //가스충전을 위해서 필드로 직접 접근 불가.
    //myCar.gas=10; 
    //외부에서 필드에 직접 접근시에는 아래와 같이 에러메시지가 뜬다.
    //The field Car_p223.gas is not visible  //private int gas;때문에 에러남.

    //가스충전위해 gas값 설정하기()을 이용
    myCar.setGas(5); //-값을 던지면 true가 나온다.. 그래서 조건문을 좀 더 디테일 하게 넣어야한다. 0이 아닌경우에 다 true 리턴하게되는것.

    //가스 있는지? 없는지? 체크
    //->isLeftGas() 호출하겠다
    boolean gasState = myCar.isLeftGas(); // --> true 또는 false가 이자리에 남는다. 따라서 그 값을 담을 변수를 선언하는데 그 변수의 타입은 리턴값과 같은 boolean 타입으로 선언한다.
    System.out.println("gasState : "+gasState);
    if(gasState) { //조건충족시 true
        System.out.println("가스 있어요");    
    }else { //false
        System.out.println("가스 없어요");     /// 유저입장에서 false또는 true는 알아볼수 없으므로 if문을 추가 작성해서 유저한테 상태 보여주기 위함.
    }


    //주행하기 -> 참조변수명.run
    myCar.run();

}

}


    package ch06;

public class Member01 {
//field
//[접제][제] 타입 필드명
//static 필드(=정적필드)클래스 명을 통해서 접근한다!!! 그래서 클래스 필드라고도 한다. (대신 앞에 static이 붙는다.)
static String nation = "KOREA~"; //대한민국 사람만 있으므로 국적은 초기값으로 모두 동일하게 초기화 한다. (static field) 참조변수명이 없기 때문에 static이 붙는다고도 볼 수 있다.
//동일한 변수 값에 대해서 static 이라고 선언하면 객체를 굳이 만들지 않아도 접근가능하다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

//인스턴스 필드  --->>> 인스턴스 변수, 즉 참조변수는 참조변수 명.필드데이터 이런식으로 접근을 해줘야한다. 참조변수명에 주소가 있으므로. (non-static field)
String name; // 이름
String id; // id
String pwd; // 비번
int age; // 나이

// 생성자
// [접제][제] 클래스명 (매개변수){}
// 기본생성자 - 매개변수없는 생성자
//==> new Member01();
Member01(){} // --> 기본 생성자(default constructor)
//매개변수 있는 생성자-주로 필드값을 초기화
Member01(String name, String id, String pwd, int age){
this.name = name;
this.id = id;
this.pwd = pwd;
this.age = age;
}

// method
// [접제][제] 리턴유형 메소드명(매개변수){}
public void test(){

}  // --> 기본 생성자(default constructor)

}


package ch06;

//이 클래스는 회원관련 데이터, 기능을 실행하는 클래스이다.
public class Member01_Main {

static void showView(Member01 my) {
    System.out.println("Member name : "+my.name);
    System.out.println("Member ID : "+my.id);
    System.out.println("Member PW : "+my.pwd);
    System.out.println("Member age : "+my.age);
    System.out.println("==========================================");

    }

//non-static메소드 =>참조변수명.메소드명()

// void test() {}
//static메소드 => 클래스명.메소드명()
// static void testt() {}

public static void main(String[] args) {

    //static메소드를 호출

// 그러나 public static void main 또는 위에 과 같이 static void testt와 같은 static 메소드는 참조변수를 선언할 필요가 없다.
// Member01_Main.testt();

    //정적메소드를, non-static메소드 ==>p233, p236, p237
    //객체생성

// 클래스타입 참조변수=new 클래스명();
// Member01 a = new Member01();
// 참조변수명.test();
// a.test();
// static이 붙지 않은 논 스태틱 메소드는 위와같이 참조변수 선언및 객체 선언해주고
//참조변수.test();로 접근!!! 기존 인스턴스 생성과 동일하다.

    //참조변수선언 및 객체생성
    //클래스명 참조변수=new 생성자();

// Member01 mem1 = null; //이런식으로 따로 선언해도 무관 -->객체의 주소가 저장될 변수 선언 (참조변수 = 인스턴스변수)
// mem1 = new Member01("홍길동", "hid", "h123", 20); //이런식으로 따로 선언해도 무관
Member01 mem1 = new Member01("홍길동", "hid", "h123", 20);
//mem1은 인스턴스 변수
// mem1.nation = "Republic of Korea"; //이렇게 해도 상관없으나 ... 더 좋은 방법으로

~ 주석
// System.out.println("Member nation : "+mem1.nation);
System.out.println("Member nation : "+Member01.nation); // -->>이건 어느 클래스안에 nation 인지를 찍는 더 확실한 방법. -->절대경로 느낌 //정적필드
System.out.println("클래스명.nation = "+mem1.name);
System.out.println("Member ID : "+mem1.id);
System.out.println("Member PW : "+mem1.pwd);
System.out.println("Member age : "+mem1.age);
System.out.println("==========================================");
showView(mem1);
Member01 mem2 = new Member01("손흥민", "sid", "s123", 31);
// mem2.nation = "Republic of Korea"; //이렇게 해도 상관없으나 ... 더 좋은 방법으로

주석
// System.out.println("Member nation : "+mem2.nation);
System.out.println("클래스명.nation = "+Member01.nation); // -->>이건 어느 클래스안에 nation 인지를 찍는 더 확실한 방법. -->절대경로 느낌 //정적필드
System.out.println("Member name : "+mem2.name);
System.out.println("Member ID : "+mem2.id);
System.out.println("Member PW : "+mem2.pwd);
System.out.println("Member age : "+mem2.age);
System.out.println("==========================================");
showView(mem2);
Member01 mem3 = new Member01("이순신", "lid", "l123", 35);
// mem3.nation = "Republic of Korea"; //이렇게 해도 상관없으나 ... 더 좋은 방법으로~~ 주석
// System.out.println("Member nation : "+mem3.nation);
System.out.println("클래스명.nation = "+Member01.nation); // -->>이건 어느 클래스안에 nation 인지를 찍는 더 확실한 방법. -->절대경로 느낌 //정적필드
System.out.println("Member name : "+mem3.name);
System.out.println("Member ID : "+mem3.id);
System.out.println("Member PW : "+mem3.pwd);
System.out.println("Member age : "+mem3.age);
System.out.println("==========================================");
showView(mem3);

        //참조변수명을 통해서 접근하지 않아도 Member01 클래스명.필드변수로 수정 및 출력이 모두 가능하다.
    //객체가 서로 달라도 동일한 값의 데이터를 공유해야하는 경우라면 정적필드 static field를 사용한다!!!이것을 사용하면 각 객체의 참조변수에 담겨있는 주소지를 참고할 필요가 없다.
    //바로 클래스명.으로 접근 및 수정 가능!!!
}

}