본문 바로가기
Language/JAVA

[JAVA] 06일차. 클래스와 객체1 (3), (4)

by 전전긍긍 2022. 2. 18.

👀202202014 공부기록

 

📍본 포스팅은 인프런-Do it! 자바 프로그래밍 입문 강의를 바탕으로 작성함을 알립니다.

 

[무료] Do it! 자바 프로그래밍 입문 - 인프런 | 강의

비전공자, 문과생도 무릎을 ‘탁!’ 치며 이해하는 20년 경력 명강사의 자바 강의!, - 강의 소개 | 인프런...

www.inflearn.com


11. 클래스와 객체1 (3)

클래스로부터 객체를 선언하는 과정을 클래스의 생성(인스턴스화)라고 한다. 이렇게 선언된 해당 클래스 타입의 객체를 인스턴스(instance)라고 한다. 예를 들어 "개"라는 클래스를 만들었다면 인스턴스는 개의 하위범주에 있는 진돗개, 치와와 등등을 의미한다. 즉, 객체를 코드로 구현한 것이 클래스이고, 클래스의 설계를 바탕으로 메모리에 구현한(생성된) 상태를 인스턴스라고 한다. 이 인스턴스를 메모리에 할당된 객체라고 한다. 

인스턴스는 어떻게 생성하나요?

인스턴스를 사용하기 위해서는 클래스를 생성하여야 하는데, new 예약어를 이용하여 인스턴스를 생성한다. new의 의미는 동적 메모리 할당(Dynamic Memory Allocation)이다. new 키워드가 등장하면 힙메모리에 인스턴스가 생성되었다는 것을 알 수 있다. (new 없이 사용하는 클래스들은 static 클래스이다. static 클래스는 가능상 인스턴스를 만들 필요가 없는 클래스이다.)

클래스형 변수이름 = new 생성자;
Student studentA = new Studnet();

* 스택은 지역변수들이 자리를 잡는 메모리이다. 인스턴스는 힙 메모리에 생성된다. 하나의 클래스로부터 여러 개의 인스턴스를 생성할 수 있는데, 각각의 인스턴스는 각자 다른 힙(heap)메모리에 다른 값을 가진다. 실제로 생성된 객체의 주소를 가리키는 것이 힙 메모리이다. 힙 메모리는 동적으로 생성되는 메모리인데, 필요할 때 할당받을 수 있다. 스택메모리는 함수가 호출되면 지역변수가 쌓이고 함수가 끝나면 사라진다. 힙 메모리는 new라는 키워드에 의해 생성이 되고 사라질때, JVM의 GC(Garbage Collection)가 불필요한 메모리를 알아서 없애준다. (메서드는 명령어의 집합이고 변수가 아니기 때문에 heap메모리에 저장되지 않는다.)

public class Student {

	int studentID;
	String studentName;	
	int grade;
	String address;
	
	public void showStudentInFor() {
		System.out.println(studentName + " , " + address);
	}
	
	public static void main(String[] args) {
		
		Student studentLee = new Student();
		studentLee.studentName = "이순신";
		studentLee.studentID = 100;
		studentLee.address = "서울시 영등포구 여의도동";
		
		Student studentKim = new Student();
		studentKim.studentName = "김유신";
		studentKim.studentID = 101;
		studentKim.address = "미국 산호세";
		
		studentLee.showStudentInFor();
		studentKim.showStudentInFor();
	}

}
//이순신 , 서울시 영등포구 여의도동
//김유신 , 미국 산호세

📍참조변수, 참조값

인스턴스가 생성되면 힙메모리 영역에 생성된다. 참조변수(reference)는 이 힙메모리에 생성된 인스턴스이다. 즉, 인스턴스 생성시 선언하는 변수이다. 위 코드에서는 studentLee 와 studentKim이 참조변수이다. 참조변수는 내부적으로 주소를 가지고 있는데, 인스턴스가 생성되는 힙 메모리 주소를 참조값이라고 한다. 

System.out.println(studentLee);
//classpart.StudentTest@24d46ca6

위 코드는 studentLee 참조변수의 참조값을 출력한 코드이다.

📍생성자(constructor)

생성자(constructor) : 인스턴스 생성 시 new 키워드와 함께 사용했던 생성자. 즉, 해야 될 일들을 구현하는 것. (객체의 생성과 동시에 인스턴스 변수를 원하는 값으로 초기화할 수 있다.) 

  • 생성자는 인스턴스를 초기화 할 때의 명령어 집합이다.
  • 생성자의 이름은 그 클래스의 이름과 같다.
  • 생성자는 메소드가 아니다. 상속되지 않으며, 리턴값이 없다.

- 기본 생성자(default constructor) : 자바의 모든 클래스에는 하나 이상의 생성자가 정의되어 있어야 한다. 하지만 자바 컴파일러가 기본 생성자라는 것을 기본적으로 제공해주기 때문에 특별히 생성자를 정의하지 않고도 인스턴스를 정의할 수 있다. 기본 생성자는 매개변수를 하나도 가지지 않으며, 아무런 명령어도 포함하고 있지 않는다. (생성자가 하나라도 있다면 컴파일러는 기본 생성자를 제공하지 않는다.) 형식만 갖추고 아무것도 안하는 것이 포인트이다. +구현부없음

클래스이름() {}

위의 코드와 같이 기본 생성자는 어떠한 매개변수도 전달받지 않으며, 기본적으로 아무런 동작도 하지 않는다.

 

- 매개 변수가 있는 생성자 오버로드 : 생성자는 매개변수를 사용하여 데이터를 입력받을 수 있다. 데이터를 받는 초기화의 이점은 필요에 따라 다른 데이터의 인스턴스를 생성할 수 있다는 점이다.

public class Main {
    public static void main(String[] args) {
        Person p1 = new Person("Mimi");
        Person p2 = new Person("Tykon");
        Person p3 = new Person("Lapi");

        Person p4 = new Person();

        p1.showName();
        p2.showName();
        p3.showName();
        p4.showName();
    }
}
class Person{
    String name;
    //매개변수가 없는 생성자
    public Person(){
        name = "John Doe";
        System.out.println("constructing... " + name);
    }
    //매개변수가 있는 생성자
    public Person(String name){
        this.name = name;
        System.out.println(this.name + "Constructed...");
    }
    void showName(){
        System.out.println(name);
    }
    void showRef(){
        System.out.println(this);
    }
}
//Mimi
//Tykon
//Lapi
//John Doe

* 생성자 오버로드 (constructot overload) : 필요에 의해 생성자를 추가하는 경우, 생성자를 호출하는 측에서 어떤 매개변수를 호출했느냐에 따라 생성자를 선택할 수 있다. (생성자만 오버로드 되는 것이 아니라, 메소드 또한 오버로드가 가능하다.) 매개변수가 다르다면 여러 개를 생성할 수 있다.

📍SET, GET 메소드

SET은 변수값을 할당하는 목적의 함수인기 때문에 인자를 받는다. (setter, 값을 저장하도록 유도)

GET은 변수값을 반환하는 목적이기 때문에 retutn이 필요하다. (getter, 값을 반환받게 해줌)

(외부에서 데이터에 직접적으로 접근하는 것을 막기 위해서 메소드를 공개하여 데이터에 접근할 수 있게 하는 메소드)

	public String getStudentName() {
		return studentName;
	}
	public void setStudentName(String name) {
		studentName = name;
	}

 

[ 용어정리 ]

객체 객체 지향 프로그램의 대상, 생성된 인스턴스
클래스 객체를 프로그래밍하기 위해 코드로 만든 상태
인스턴스 클래스가 메모리에 생성된 상태
멤버 변수 클래스의 속성, 특성
메서드 멤버 변수를 이용하여 클래스의 기능을 구현
참조 변수 메모리에 생성된 인스턴스를 가리키는 변수
참조 값 생성된 인스턴스의 메모리 주소 값

12. 클래스와 객체1 (4)

참조 자료형(reference data type) : 자바 라이브러리에서 제공되는 자료형들(String 등)과 직접 만들어서 사용하는 자료형(Student, Date 등)이 있다. 클래스가 변수의 자료형이 되는 것이다.

package reference;

public class Circle {

	Point point;
	int radius;
	
	public Circle() {
		point = new Point();
	}
}
package reference;

public class Point {

	int x;
	int y;
}

Point클래스를 생성하고 CIrcle 클래스에서 참조하는 코드이다.

 

1️⃣학생 클래스

package reference;

public class Student {

	int studentID;
	String studentName;
	
	Subject korea;
	Subject math;
	
	//생성자 호출
	public Student() {
		korea = new Subject("국어");
		math = new Subject("수학");
	}

	//생성자 오버로드
	public Student(int id, String name) {
		studentID = id;
		studentName = name;
		
		korea = new Subject("국어");
		math = new Subject("수학");
	}
	
	public void setKorea(int score) {
		korea.setScore(score);
	}
	
	public void setMath(int score) {
		math.setScore(score);
	}
	
	public void showStudentInfo() {
		int total = korea.getScore() + math.getScore();
		System.out.println(studentName + " 학생의 총점은 " + total + "점 입니다.");
	}
}

2️⃣과목 클래스

package reference;

public class Subject {

	String subjectName;
	int score;
	
	public Subject(String name) {
		subjectName = name;
	}
	
	//get, set 메서드를 만들어주는 소스 제공해줌
	public void setSubjectName(String name) {
		subjectName = name;
	}


	public int getScore() {
		return score;
	}


	public void setScore(int score) {
		this.score = score;
	}


	public String getSubjectName() {
		return subjectName;
	}
}

3️⃣학생클래스와 과목 클래스 참조 test

package reference;

public class StudentTest {

	public static void main(String[] args) {

		Student studentJames = new Student(100, "James");
		studentJames.setKorea( 100);
		studentJames.setMath( 95);
		
		Student studentTomas = new Student(100, "Tomas");
		studentTomas.setKorea(80);
		studentTomas.setMath(60);
		
		studentJames.showStudentInfo();
		studentTomas.showStudentInfo();
	}

}

📍정보 은닉(information hiding)

private 접근 제어자 : 클래스의 외부에서 클래스 내부의 멤버 변수나 메서드에 접근(access)하지 못하게 하는 경우 사용. 멤버 변수나 메서드를 외부에서 사용하지 못하도록 하여 오류를 줄일 수 있음. 변수에 대해서는 필요한 경우 get(), set()메서드를 제공

package hiding;

class BirthDay {

	private int day;
	private int month;
	private int year;
	
	
	public int getDay() {
		return day;
	}
	public void setDay(int day) {
		
		if(month == 2) {
			if( day < 1 || day > 28) {
				System.out.println("날짜 오류입니다.");
			}
		}
		else {
			this.day = day;
		}
	}
	public int getMonth() {
		return month;
	}
	public void setMonth(int month) {
		this.month = month;
	}
	public int getYear() {
		return year;
	}
	public void setYear(int year) {
		this.year = year;
	}
}

public class BirthDayTest{
	
	public static void main(String[] args) {
		
		BirthDay day = new BirthDay();
		
		day.setMonth(2);
		day.setDay(30);
		day.setYear(2022);
	}
	
}
//날짜 오류입니다.