자바(Java)

[자바] 자바 클래스

Ash_jisu 2023. 8. 14. 12:18

클래스가 필요한 이유

배열 사용의 한계

  • 새로운 학생이 늘어난다고 생각해보면 결국 같은 코드를 반복해야한다. 이것을 배열로 묶을 수 있는데
    묶게되면 다음과 같다.
String[] studentNames = {"학생1", "학생2"};
int[] studentAges = {15,16};
int[] studnetGrades = {90,80};
for (int i = 0; i < studentNames.length; i++) {
    System.out.println("이름:" + studentNames[i] + " 나이:"+studentAges[i]+" 성적:"+studnetGrades[i]);
}
  • 추가하는 과정에서는 크게 불편함을 못 느낄 수 있다. 그런데 이제 추가 또는 삭제하는 과정에서
    학생의 이름 배열, 학생의 나이 배열, 학생의 성적 배열 3개에서 각 학생에 맞는 값을 지워줘야한다. 
  • 그래서 아예 학생이라는 타입형을 두고 배열을 만들면 더 쉽게 추가 또는 삭제가 가능하다.

 


클래스 정의

Class란

  • 객체 지향 프로그래밍에서 가장 기본적인 구성 요소 중 하나로, 변수와 메서드를 정의하는 일종의 틀이다
    아래 그림을 보면 이해가 쉽다

class Car

Class 정의하기

public class ClassName {
    // 멤버 변수 (필드) 선언
    // 접근 제어자 필드타입 필드이름;
    
    // 생성자 정의
    // 접근 제어자 ClassName(매개변수) {
    //생성자 코드
    // }
    
    // 메서드 정의
    // 접근 제어자 반환타입 메서드이름(매개변수) {

     }   
}

 

차 클래스 예시

static class Car {
    // 멤버 변수 (필드) 정의
    private String engineType;  //엔진 종류
    private double mileageInKm;  //달린 km수
    private String make;  //제조사
    private int year;   //제조년도
    private String model;  //모델명

    // 생성자 정의
    public Car(String engineType, double mileageInKm, String make, int year, String model) {
        this.engineType = engineType;
        this.mileageInKm = mileageInKm;
        this.make = make;
        this.year = year;
        this.model = model;
    }
}

 

 

 

 

 

 


객체 

new

  • 주솟값을 매핑하는 참조값을 저장하는데 이제 참조값을 사용자가 직접 만들 수는 없고, 가상머신의
    허락을 받아야 참조값을 얻을 수 있다. 그 허락을 받는것이 바로 연산자 new이다. 
    따라서 new 키워드를 사용하면 참조값과 heap영역에 공간이 생기고 주소공간에 값을 넣는다. 
    그리고 그것을 이제 앞선 변수나 인스턴스에 참조값을 대입한다

객체 만들기

  • 클래스를 정의했으니 이제 사용해볼차례이다. new 키워드를 이용하여 main에서 Car class를 생성해주면 된다.
  • 이때 new키워드란 내가 만든 객체를 생성하여 메모리(heap 영역)에 데이터를 저장한 공간을 할당하고 저장한 공간의 주소를 객체에 반환한다. 주소는 이제 car라는 변수에 저장되어 스택영역에 생성된다.
public static void main(String[] args) {
    //엔진 ="I6", 키로수="100000", 제조사="Toyota", 제조년도 ="1993", 자동차모델명 = "SupraA80"\
    Car car = new Car("I6", 100000, "Toyota", 1993, "SupraA80");
    //엔진 ="Electric", 키로수="1000", 제조사="Hyundai", 제조년도 ="2022", 자동차모델명 = "Ionic6"
    Car car2 = new Car("Electric", 1000, "Hyundai", 2022, "Ionic6");
  }

 

 

car, car2의 주소값을 출력해보면 아래와 같이 다른거를 볼수있다.

 

 

 

 

 

 


메소드 

다른 언어에서는 함수라도고 하는 메소드 정의하는 방법은 4가지가 있다.

  • void 반환 타입, 매개변수 없음
  • void 반환 타입, 매개변수 사용
  • 변수 반환 타입, 매개변수 없음
  • 변수 반환 타입, 매개변수 사용

 예시

  • 위에 4가지 메소드를 아래 car클래스 안에 정의해줬다 그리고 그 메소드를 main에서 사용하는 예시도 나타내보았다
static class Car {
        //멤버와 생성자 생략

        //메서드 정의
        //void 반환 타입, 매개변수 없음
        public void start() {
            System.out.println("차가 시동이 켜졌습니다.");
        }

        //void 반환 타입, 매개변수 사용
        public void carYear(int curYear){
            System.out.println("차연식: "+(curYear-year));  //차 연식출력(현재년도 - 제조년도)
        }

        //변수 반환 타입, 매개변수 없음
        public String getCarMake(){
            return make;
        }
        // 변수 반환 타입, 매개변수 사용
        public double updateMileage(double newMileage) {
            mileageInKm += newMileage;
            System.out.println("주행 거리가 업데이트되었습니다.");
            return mileageInKm;
        }
    }

    public static void main(String[] args) {
        //엔진 ="I6", 키로수="100000", 제조사="Toyota", 제조년도 ="1993", 자동차모델명 = "SupraA80"
        Car car = new Car("I6", 100000, "Toyota", 1993, "SupraA80");
        car.start();  //"차가 시동이 켜졌습니다."
        car.carYear(2023);  //"차연식: 30"
        System.out.println("차 제조사: "+ car.getCarMake());  //"차 제조사: Toyota"
        double curKm = car.updateMileage(30000);   //"주행 거리가 업데이트되었습니다."
        System.out.println(curKm+"km");     //"130000.0km"
    }
}

 

 

 

 


생성자 

생성자 정의

  • 생성자는 객체를 생성할때 호출되는 특별한 종류의 메서드이다 클래스의 이름과 동일하며, 객체 생성시 자동으로 호출된다 보통은 클래스의 인스턴스를 초기화하기 위한 역할을 한다

사용법은 다음과 같다

  class Car {
        private String engineType;
        private double mileageInKm;
        private String make;
        private int year;
        private String model;

        //기본생성자 추가
        public Car() {

   }

        //오버로딩을 통해 생성된 생성자
   public Car(String engineType, double mileageInKm, String make, int year, String model) {
        this.engineType = engineType;
        this.mileageInKm = mileageInKm;
        this.make = make;
        this.year = year;
        this.model = model;
   }
}

 

※오버로딩: 오버로딩은 같은 이름의 매서드나 생성자를 여러 번 정의하되, 매개변수의 타입, 개수, 순서를 다르게 하여 다양한 호출 형태를 지원한다(다양한 초기화)

  • 추가로 생성자를 하나도 안만들경우 기본생성자가 자동으로 생긴다 이 생성자는 컴파일러가 알아서 만들어준다(물론 생성자를 개발자가 제공하면 기본생성자는 생기지 않는다)

 

 

 


this 키워드

 this정의

  • 주로 클래스 내부에서 현재 객체(인스턴스)를 가리키는 데 사용된다.
    ’.’ 통칭 점을 사용하여 인스턴스 메서드 또는 생성자 내에서 현재 개체의 모든 멤버를 참조할 수 있다.

예시 

public class Main {
    static class Car 
        public Car() {
        }
				
         public Car returnThis() {  
            return this;    //생성한 차 인스턴스 가리키는 참조 반환
        }
    }
	public static void main(String[] args) {
        Car car = new Car();
        System.out.println(car);
        System.out.println(car.returnThis());
    }
}

 

this를 안쓴경우

  • 아래와 같이 작성할경우 매개변수로 받은 값에 자기 자신을 할당해버린다
    이렇게 되면 매개 변수의 값이 멤버 변수에는 아무런 값도 할당하지않는다
    따라서 this키워드를 써줘야한다

//옳지못한 예시
public Car(String engineType, double mileageInKm, String make, int year, String model) {
    engineType = engineType;
    mileageInKm = mileageInKm;
    make = make;
    year = year;
    model = model;
}

//좋은 예시(this를 사용해 멤버 변수에 값 할당)
public Car(String engineType, double mileageInKm, String make, int year, String model) {
    this.engineType = engineType;
    this.mileageInKm = mileageInKm;
    this.make = make;
    this.year = year;
    this.model = model;
}

 

 

 


참고