Welcome! Everything is fine.

[1-2] 클래스와 객체1(4) ~ 2(2) 본문

자격증 및 기타 활동/J2KB

[1-2] 클래스와 객체1(4) ~ 2(2)

개발곰발 2021. 8. 12.
728x90

💡 참조 자료형(reference data type)

변수 자료형의 종류는 다음과 같다.

  • 기본 자료형  : int, long, double 등 기본적으로 제공되는 자료형.
  • 참조 자료형 String, Data, Student 등 기존의 자바 라이브러리(JDK)에서 제공하거나 사용자가 직접 만들어서 사용하는 자료형.(클래스)

학생 클래스에는 학생 ID, 이름, 과목 등을 넣을 수 있을 것이다. 그런데 과목이라는 속성이 학생에 포합된 속성이지만 과목이 점점 늘어나고, 과목에 대한 정보(점수, 이름, 선생님, 최고점, 최저점 등)가 늘어난다면 학생 클래스는 아래와 같이 매우 복잡해질 것이다.

public class Student {

	int studentID;
	String studentName;
	int koreaScore;
        int mathScore;
        String koreaSbject;
        String mathSbject;
        int engScore;
        String engSbject;
        ...
}

따라서 이럴때 참조 자료형을 사용한다. 과목 클래스를 아래와 같이 따로 만든 후, 학생 클래스에서는 앞에 Subject를 붙여 과목을 표현한다.

public class Subject {
	String subjectName;
	int score;
}
public class Student {

		int studentID;
		String studentName;
		Subject korea;
		Subject math;
}

 

💡 정보 은닉(information hiding)

정보 은닉이란 객체의 속성을 숨기는 것을 말하며, 객체 지향 프로그래밍의 가장 큰 특징 중 하나다. 이때 private 이라는 접근 제어자를 사용한다. 클래스의 외부에서 클래스의 내부의 멤버 변수나 메서드에 접근하지 못하게 하는 경우 사용되며, 외부에서 사용하지 못하도록 함으로써 오류를 줄일 수 있다. 변수에 대해서 필요한 경우, get( ), set( ) 메서드를 제공한다.

 

  • private : 클래스 내부에서만 사용할 수 있다. 꼭 사용할 필요는 없지만 어떤 변수를 사용해서 문제가 생길 수 있는 경우에는 반드시 private을 사용하고, get( ), set( ) 메서드를 사용하여 값을 가져가야한다.
  • public : 클래스 외부에서도 사용할 수 있다. 주의할 점은 하나의 자바 파일 안에 클래스가 두 개일수는 있지만 public 클래스는 단 하나여야한다.
  • proctected : 상속 관계에서 public처럼 사용할 수 있다.

💡 this 가 하는 일

1. 자신의 메모리를 가리킨다.

멤버 변수를 가리키려면 반드시 this를 써야한다.

class Birthday{
		int day;
		int month;
		int year;
		
		public void setYear(int year) {
			this.year = year;
		}
	}
    // 위 코드에서 this를 생략하면 year는 파라미터로 사용되는 year로 인식된다.

2. 생성자에서 다른 생성자를 호출한다.

📃 생성자(constructor) : 인스턴스를 생성할 때 반드시 처리해야하는 어떠한 작업이 있다면  생성자를 이용하여 초기값을 설정한다. 클래스와 똑같은 이름의 생성자를 정의하면 그게 바로 생성자이다. 어떤 클래스가 인스턴스화 될때 실행되어야 할 코드를 생성자 안에 정의함으로써 초기화의 목적을 달성할 수 있다. (생활코딩, 생성자와 this)

 

다음 코드에서 디폴트 값으로 name에는 "이름없음", age에는  1을 넣고자 한다면 어떻게 하는 것이 좋을까?

class Person{
	String name;
	int age;
	
	public Person() {}
	
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
}
public class CallAnotherConst {

	public static void main(String[] args) {
		Person p1 = new Person();
	}

}

기본적으로 아래와 같은 방식으로 적을 수 있을 것이다.

	public Person() {
		name = "이름없음";
		age = 1;
	}

그러나 그 아래에는 이미 name과 age를 초기화 해주는 생성자가 있다. 따라서 그것을 가져와서 this를 사용해 아래와 같이 적을 수 있다.

	public Person() {
		this("이름없음", 1);
	}

그래서 다음 코드를 출력해보면 "이름없음"과 1이 제대로 나오는 것을 확인할 수 있다.

class Person{
	String name;
	int age;
	
	public Person() {
		this("이름없음", 1);
	}
	
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
}
public class CallAnotherConst {

	public static void main(String[] args) {
		Person p1 = new Person();
	}

}

주의 할 점은 this를 쓸 때는 아래와 같이 앞에 다른 문장을 적으면 안된다.

	public Person() {
    		int = 0; // 오류
		this("이름없음", 1);
	}

 

3. 자신의 주소를 반환한다.

this를 이용하여 자신의 주소를 반환 할 수 있지만 잘 쓰이진 않는다.

💡 객체 간의 협력

다음과 같은 관계를 코드로 나타내는 방법을 연습해보았다.

  • 학생 : 이름, 학년, 돈이라는 속성을 가지고 있다. 버스에 타면 가진 돈 중 1000원을 내고, 지하철에 타면 가진 돈 중 1500원을 낸다.
  • 버스 : 버스 번호, 승객 수, 돈이라는 속성을 가지고 있다. 학생이 버스에 타면 승객 수가 1명 올라가고, 돈은 1000원을 받는다.
  • 지하철 : 지하철 번호, 승객 수, 돈이라는 속성을 가지고 있다. 학생이 지하철에 타면 승객 수가 1명 올라가고, 돈은 1500원을 받는다.

제일 먼저 Student, Bus, Subway, TakeTrans라는 이름의 자바 파일을 하나씩 만들었다. 먼저 아래 코드는 학생 클래스의 내용이다. 학생 클래스에서는 먼저 기본정보인 학년, 이름, 돈을 변수로 선언했다. 그리고 생성자와 this 키워드를 이용하여 학생 인스턴스를 생성할 때 학년, 이름, 돈을 입력받도록 했다. 메서드는 버스 타기(takeBus), 지하철 타기(takeSubway), 정보 출력하기(showInfo) 세 개로 나누었다. 

public class Student {
	String studentName;
	int grade;
	int money;
	
	public Student(int grade, String studentName, int money) {
		this.grade = grade;
		this.studentName = studentName;
		this.money = money;
	}
	
	public void takeBus(Bus bus) {
		bus.take(1000);
		money -= 1000;
	}
	
	public void takeSubway(Subway subway) {
		subway.take(1500);
		money -= 1500;
	}
	
	public void showInfo() {
		System.out.println(grade + "학년 " +  studentName + 
        		" 님의 남은 돈은 " + money +"원입니다.");
	}
}

다음은 버스 클래스와 지하철 클래스의 내용이다. 먼저 버스/지하철 번호, 승객 수, 돈을 변수로 선언하였다. 생성자와 this 키워드를 이용하여 인스턴스를 생성할 때 버스/지하철 번호를 입력받도록 했다. 메서드는 버스/지하철 타기(take), 정보 출력하기(showInfo) 두 개로 나누었다. take 메서드는 학생 클래스에서 학생이 버스/지하철에 탈 때 호출된다. 버스는 1000원, 지하철은 1500원씩을 인자로 하고, 학생의 돈이 빠져나감과 동시에 버스/지하철에 돈이 들어온다. 또한 승객 수도 증가한다.

 

public class Bus {
	int busNumber;
	int passengerCount;
	int money;
	
	public Bus(int busNumber) {
		this.busNumber = busNumber;
	}
	
	public void take(int money) {
		this.money += money;
		passengerCount++;
	}
	
	public void showInfo() {
		System.out.println("버스 " + busNumber + "번의 승객은 " + passengerCount + 
				"명이고, 수입은 " + money + "원입니다.");
	}
}
public class Subway {
	int lineNumber;
	int passengerCount;
	int money;
	
	public Subway(int lineNumber) {
		this.lineNumber = lineNumber;
	}
	
	public void take(int money) {
		this.money += money;
		passengerCount++;
	}
	
	public void showInfo() {
		System.out.println("지하철 " + lineNumber + "호선의 승객은 " + passengerCount + 
				"명이고, 수입은 " + money + "원입니다.");
	}
}

다음은 이 세개의 클래스를 모두 출력하는 코드다. james, tomas라느 학생 인스턴스 2개와 bus100, subwayGreen이라는 버스/지하철 인스턴스 2개를 생성했다.

public class TakeTrans {

	public static void main(String[] args) {
		Student james = new Student(2, "james", 5000);
		Student tomas = new Student(3, "tomas", 10000);
		
		Bus bus100 = new Bus(100);
		james.takeBus(bus100);
		james.showInfo();
		bus100.showInfo();
		
        	System.out.println();
        
		Subway subwayGreen = new Subway(2);
		tomas.takeSubway(subwayGreen);
		tomas.showInfo();
		subwayGreen.showInfo();
        
	}

}

출력된 결과는 다음과 같다.

2학년 james 님의 남은 돈은 4000원입니다.
버스 100번의 승객은 1명이고, 수입은 1000원입니다.

3학년 tomas 님의 남은 돈은 8500원입니다.
지하철 2호선의 승객은 1명이고, 수입은 1500원입니다.