[이것이자바다] chapter 6. 클래스(class) 2

chapter 6

클래스의 구조

필드(Field)

필드(Field)는 객체의 고유데이터, 객체가 가져야 할 부품, 객체의 현재 상태 데이터를 저장하는 곳이다. 자동차 객체를 예로 들어보면 모델, 색깔은 고유 데이터에 해당하고, 현재 속도, 엔진 회전 수는 상태 데이터에 해당한다. 그리고 차체, 엔진, 타이어는 부품에 해당한다. 따라서 자동차의 클래스를 구현하려면 이러한 정보들을 필드로 선언해야한다.


public class Car {    //클래스 Car

    // 고유 데이터
    String model;
    String color;

    // 상태 데이터
    int speed;
    int rpm;

    //부품
    Body body;
    Engine engine;
    Tire tire;
}

필드 선언

필드의 초기값은 필드 선언시 주어질 수 있고, 생략할수 있는데, 선언만 하고 초기화하지 않는다면 필드들은 객체 생성 시 자동으로 기본 초기값으로 설정된다.

분류   데이터타입 초기값
기본타입 정수 타입 byte 0
    char \u0000 (빈 공백)
    short 0
    int 0
    long 0L
  실수 타입 float 0.0F
    double 0.0
  논리 타입 boolean false
참조 타입 Reference type 배열 null
    클래스(String 포함) null
    인터페이스 null

필드 사용

//Car 클래스 (내부 클래스)
public class Car{
  
  //필드
  int speed;

  // 생성자 
  Car (){
    speed = 0; // -> 도트(.) 없이 사용, 값 변경
	}
  
  //메소드
  void method(){
    speed = 10; // 메소드 호출되면 필드 speed의 값이 10으로 변경.
	}

}


//Person 클래스 (외부 클래스)
public class Person{
   
   void method(){
     // Car 객체 생성
     Car myCar = new Car();

     // 필드 사용
     myCar.speed =60;  // -> 도트(.)을 사용한다.
   }
}


생성자(Constructor)

=> 생성자를 실행시키지 않고 객체를 만들 수 없다. new 연산자에 의해 생성자가 성공적으로 실행되면 heap영역에 객체가 생성되고, new 연산자에 의해 객체의 주소값이 리턴되어 변수가 객체를 참조(사용)할 수 있지만, 먄약 생성자가 매개변수의 잘못된 입력으로 인해 제대로 실행되지 않으면(즉, 에러) 객체는 생성되지 않는다.

기본 생성자(Defualt Constructor)

기본 생성자

[public] 클래스(){

}

=> 클래스가 public class로 선언되면 기본 생성자에도 public이 붙지만, 클래스가 public이 붙지 않으면 생성자도 public이 붙지 않는다.(명심!)

생성자 선언

생성자 선언부로 생성자가 어떻게 작성되는 지 알아보자

Car mycar = new Car("그랜저", "검정", 300);

public class Car{
   
   // 생성자
   Car(String model, String color, int maxSpeed){
      //...
	 }
}
// 생성자는 이와 같이 매개변수가 두가지 String 변수, 하나의 int변수로 선언되었다면,(String model, String color, int maxSpeed)
// 객체를 new 연산자로 생성자를 호출할 때  각 위치에 맞게 "그랜져", "검점", 300으로 인자를 입력해야 함을 알 수 있다.

Car mycar = new Car("검정", 3000);

public class Car{

  //생성자
  Car(String color, int cc){
   //...
	}
}
// 이와 같은 경우는 String color, int cc에 맞게 생성자의 인자에 "검정", 3000을 입력함을 알 수 있다.

필드 초기화


//내부 클래스
public class Korean{
  // 필드 
  String nation = "대한민국"
  String name;
  string ssn; // 주민번호

  //생성자
  public Korean(String n , String s){
    name = n;
    ssn = s;
	}
}

// 메인
public static void main(String[] args){
  Korean k1 = new Korean("이자바", 970707-1234888"); // 생성자로 다양하게 초기화...
  Korean k2 = new Korean("김도형", 930928-1999999");

}

=> Korean 생성자의 매개 변수 이름으로 각각 n과 s를 사용했는데 , 매개변수의 이름이 너무 짧으면 가독성이 좋지 않기에 초기화시킬 필드와 동일한 이름을 갖는 매개변수를 사용하라. 이 경우 필드와 매개변수 이름이 동일하기에 생성자 내부에서 필드에 접근할 수 없는데(생성자의 매개변수가 생성자 내부에서 우선순위가 더 높기 때문), 해결 방법은 생성자 내부에서 필드 앞에 this.을 붙이면 필드에 접근할 수 있다. this란 객체 자신의 참조를 뜻하는 말로 객체는 객체 자신을 this라고 한다.

//생성자
public Korean(String name, String ssn){
   this.name = name; // 필드, 매개변수
   this.ssn = ssn;  // 필드, 매개변수
}

=> 생성자로 모든 필드를 초기화한다면, 필드의 수가 많을 경우 다 입력하기엔 너무 번거롭다. 실제로는 중요한 몇 개 필드만 생성자를 통해 초기화하고, 나머지필드들은 필드 선언시에 초기화하거나 나중에 따로 메소드를 통해 초기화를 한다. 모든 필드를 생성자로 초기화하지 말자.

생성자 오버로딩(Overloading)


public class Car{
  Car(){...} // 기본생성자는 생성자가 아래처럼 생략되있지 않은 경우 자동 생성 x, 따라서 이렇게 명시해서 만들자.
  Car(String model){...}
  Car(String model, String color){...}
  Car(String model, Stirng color, int maxSpeed){...}

}

public class Car {

    // 고유 데이터
    String model;
    String color;

    // 상태 데이터
    int speed;
    int maxspeed;
    int rpm;

    //부품
    Body body;
    Engine engine;
    Tire tire;

    Car(){

    }

    Car(String model){
        this.model = model;
    }
    Car(String model , String color){
        this.model = model;
        this.color = color;
    }
    Car(String model, String color, int maxspeed){
        this.model = model;
        this.color = color;
        this.maxspeed = maxspeed;
    }
}

this() : 다른 생성자 호출

public class Car {

    // 고유 데이터
    String model;
    String color;

    // 상태 데이터
    int speed;
    int maxspeed;
    int rpm;

    //부품
    Body body;
    Engine engine;
    Tire tire;

    // 생성자
    Car(){

    }

    Car(String model){
        this(model,"은색", 250); // 다른 생성자 호출 (String model, String color, int maxSpeed)
    }
    Car(String model , String color){
        this(model,color, 250);
    }
    Car(String model, String color, int maxspeed){
        this.model = model;
        this.color = color;
        this.maxspeed = maxspeed;   // 공통 실행 코드 
    }
}

메소드(Method)

메소드 선언

  • 메소드 선언은 선언부(리턴타입, 메소드 이름, 매개변수 선언)과 실행 블록으로 구성된다. 메소드 선언부를 메소드 시그니처(signiture) 라고도 한다.

리턴(return) 문

메소드 호출 : 클래스 내부의 다른 메소드에서 호출하는 경우 vs 클래스 외부의 다른 메소드에서 호출하는 경우

  1. 객체 내부에서 호출 ```java //메소드 선언 void run(){…} void stop(){…} void sound(){…}

//내부 메소드 void 내부메소드(){ run(); stop(); sound(); }


2. 객체 외부에서 호출
```java
//외부 메소드
void 외부메소드(){
  Car car = new Car();
  car.run();
  car.stop();
  car.sound();
}

메소드 오버로딩(Method Overloading)

int plus(int x, int y){

  return x + y;
}

double plus(double x, double y){

  return x + y;
}
//이처럼 plus 메소드를 사용할 때 인자를 int 형으로 넣고 int 값으로 반환하고 싶을때 위의 plus메소드를 사용하면 되고,
// 인자를 double형으로 넣고 double 값으로 반환하고 싶을 때 아래의 plus메소드를 사용하면 된다. 
// 이렇게 다양하게 매개값을 줘야할때 메소드 오버로딩을 사용한다.