클래스가 필요한 이유
배열 사용의 한계
- 새로운 학생이 늘어난다고 생각해보면 결국 같은 코드를 반복해야한다. 이것을 배열로 묶을 수 있는데
묶게되면 다음과 같다.
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 정의하기
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;
}
참고
'자바(Java)' 카테고리의 다른 글
[자바] 자바 패키지(package) (0) | 2023.08.28 |
---|---|
[자바]자바 상속, 다이나믹&더블 메소드 디스패치 (0) | 2023.08.21 |
[자바] HashSet 중복값 처리 과정, 배열로 변경하는 법 (0) | 2023.08.08 |
[자바] 자바 조건문과 반복문, JUnit 5 (0) | 2023.08.05 |
[자바] 자바 연산자 (0) | 2023.07.29 |