Developer/JAVA

JAVA , 클래스와 인스턴스(객체), 객체의 의미 , 나만의 클래스 만들기

단님 2024. 8. 2. 00:44
728x90
Random random3 = new Random();
  • Random→ 클래스
  • random3 → 인스턴스(객체)(Random 이라는 클래스를 지칭하는 변수)
  • new → Random이라는 클래스가 사용가능하게 heap영역의 메모리를 할당케 한다.
  • 사용 가능한 형태로 객체화
  • 사전상의 의미

class : 학급[반] (학생들), 수업 (=lesson), (한 주제에 대한 연속적인) 수업[강좌] (=course)

Object : [명사] 물건, 물체 (→UFO), 욕망, 연구, 관심 등의 대상,

[동사] 반대하다, [동사] 반대 이유를 대다, …라고 항의하다 (=protest)

Instance: [명사] 사례, 경우, [동사][격식] …을 예로 들다

 

 

* 객체의 주기 (LifeCycle) => 생성 -> 사용 -> 소멸 (in Memory, RAM→가비지 컬렉터) => 클래스(in HDD) -> 생성(in Memory) -> 객체화 (인스턴스 생성) -> 사용 -> 소멸(Memory 반납)

 

* 클래스, 객체, 인스턴스(instance : 사례, 경우) 클래스와 인스턴스는 설계도와 제품이라고 할수있다. 그럼 객체는 클래스일까 인스턴스일까? Java 프로그래밍에서는 설계도인 클래스가 메모리상의 구체적인 실체인 인스턴스가 되었을때 객체라고 부른다.

 

그러므로 클래스와 인스턴스는 구별되고, 클래스와 객체도 구별되지만,

객체와 인스턴스는 구분없이 포괄적으로 객체라는 말을 쓰기도 한다.

 

 

클래스 
Class
  • 클래스의 구성

멤버는 변수 (= 클래스의 전역변수), 메소드 들이 올 수 있다.

멤버로 실행문은 올 수 없다. 실행문은 메서드 안에 있어야 한다.

 

  • 클래스에 포함 가능한것 (맴버) => 속성(변수, 필드_Field, Column), 기능.동작(메서드) => 맴버변수(전역변수), 맴버메서드 => 맴버메서드 종류 (역할이 정해져있는 메서드들)
  • 역할 정해져 있는메서드들 중 대표적인 메서드

1.main→ 프로젝트 안에 단 하나 존재해야하는 메서드

2.생성자(Constructor)

3.toString => 객체의 속성(맴버필드,맴버변수) 의 값을 문자로 제공하는 역할에 주로 사용됨 => 출력문에서 인스턴스명만 사용했을때 자동호출됨 => Object 에 정의됨 ( 객체의 주소를 String Type으로 return ) => 대부분의 클래스에서 속성값 출력용도로 재정의하여 사용함.

4.setter

5.getter

 

 

  • 클래스 명의 규칙

- 대문자로 시작(소문자가 문법적 오류는 아님.→ 추후 모듈화 하여 자동화 할때 오류발생)

-예약어 사용 불가

class System {
System.out~~~ //이 오류 뜨는것을 확인해본다.
}

- API 라이브러리의 클래스명 비추

 

 

실습 
실행문이 없고 기능만 가진 클래스 생성하여
사용을 위한 클래스에서 사용해보자
  • 기능만 지닌 클래스 생성

기능만 가지고 있기 때문에 main 메서드가 필요하지 않다.

잘 만들어진 것을 확인

public으로 선언.

public 이란 클래스에 있는 모든 메서드 들에서 사용할 수 있고 , 외부 타클래스에서 노출할 수 있는 멤버

  • 멤버변수 선언
	public int speed ;
	public double price ; 
	public char grade ;
	public String brand; 
	public String color = "blue";

 

  • 메서드 선언

1. void 메서드 (리턴값이 의무가 아닌 메서드)

리턴이 명시 될경우 더이상 메서드를 실행하지 않고 종료함을 의미한다.

  public void moneyUp(int mymoney) { 
	  if (mymoney>10000) {
		  System.out.println("범위 초과 오류, 입력 값 : "+mymoney); return;
	  }
  money+=mymoney;
  System.out.println("** moneyUp money ="+money);  // 전역변수 money를 의미 
  
  int money = 4000;
  System.out.println("** 지역변수 money ="+money);  //지역변수 money 를 의미
  }

매개변수의 mymoney가 10000 초과일 경우 , 아래의 메서드 실행문은 실행되지 않는다.

 

2. 타입이 명시된 메서드(리턴값이 의무인 메서드)

예를 들어 toString 이 있다.

 

*toString 메서드

객체의 속성(맴버필드,맴버변수) 의 값을 문자로 제공하는 역할에 주로 사용됨

출력문에서 인스턴스명만 사용했을때 자동호출

Object 에 정의됨 ( 객체의 주소를 String Type으로 return )

대부분의 클래스에서 속성값 출력용도로 재정의하여 사용함.

	public String toString() {
		return "[speed ="+speed+", price ="+price+", brand = "+brand
					+", color = "+color+", grade: "+grade+" ]";
	}
  • 출력을 위한 클래스 생성

실행문을 위해 메인을 체크하여 클래스를 생성

Car myCar = new Car();

인스턴스 생성.

생성된 인스턴스를 통하여 접근한다.

우리가 public 으로 정의한 멤버들을 확인 할 수 있다.

Object 는 기본적으로 클래스를 생성할때 생성되는 클래스.

		System.out.println("Ex01_CarTest.java 의 테스트 ");
		Car myCar = new Car();
		System.out.println("Car의 toString 01 (멤버 변수의 초기값 확인)");
		System.out.println("-> "+myCar.toString());

 

만약 기능만 보유한 클래스의 toString 메서드를 주석처리하게된다면?

에러가 나지 않고 주소값이 나오는 것을 확인 할 수 있다.

애초에 toString 이라는 메서드가 모든 클래스들이 Object 안에 가지고있기 때문이다. 

우리가 toString을 만든다면 그걸로 덮어 씌워지는 형식.

 

  • 인스턴스를 통한 사용
Car myCar = new Car();
System.out.println("Car의 toString 01 (멤버 변수의 초기값 확인)");
System.out.println("-> "+myCar.toString());
//객체 사용(myCar.toString())
myCar.brand="현대";
myCar.color="gold";
myCar.speed =600;
myCar.price=5.5;
myCar.grade='A';
System.out.println("Car의 출력");
System.out.println("-> "+myCar);
System.out.println("Car의 toString 02(멤버 변수의 초기화 후 확인)");
System.out.println("-> "+myCar.toString());

 

 

  • 인스턴스 객체의 소멸

소멸: 메모리청소

더이상 사용되지않는 값들은 자동제거해줌

Garbage Collector (쓰레기 수집기)

정해진 알고리즘에 의해 작동됨 ( 일정시간동안 또는 더이상 참조되지않는등등... )

참조형 변수에 null 값을 주면 소멸 (더이상 참조되지않음)

myCar = null; // 소멸을 의미
System.out.println("소멸의 Car의 출력");
System.out.println("-> "+myCar);

 

다중 인스턴스의 이용
  • 기능만 가지고 있는 클래스 Car
public class Car {
//pubic 사용범위를 일컫음.
	public int speed ;
	public double price ; 
	public char grade ;
	public String brand; 
	public String color = "blue"; 

	public void hpowerUp() {
		speed+=10;
	}
	public void hpowerDown() {
		speed-=10;
	}
	//변수를 출력하기 위한 메서드
	public String toString() {
		return "[speed ="+speed+", price ="+price+", brand = "+brand
					+", color = "+color+", grade: "+grade+" ]";
	} 
}
  • 출력을 가진 클래스 CarTest
		Car fCar = new Car();
		fCar.brand="벤츠";
		fCar.color="black";
		fCar.speed =600;
		fCar.price=5.5;
		fCar.grade='A';
		Car mCar = new Car();
		mCar.brand="아우디";
		mCar.color="white";
		mCar.speed =400;
		mCar.price=4.5;
		mCar.grade='B';
		
		myCar = fCar; // fCar 의 주소값이 전달됨.

myCar = fCar;

라는 실행문으로 인해 ,

myCar는 fCar의 주소를 가지게 되고 , 값을 변경하면 fCar와 myCar가 같이 바뀌는 것을 볼 수 있다.

즉 주소를 참조했다는 것을 가장 쉽게 알 수 있다.

하지만 , 따로 값을 담고싶다면 , 주소값을 참조하는 형식이 아닌 대입연산자를 통해 할당 된 값들을 직접 넣어야 한다.

mCar.grade = fCar.grade;

 

 

예제
나만의 클래스를 만들어 보세요
* MyClass
맴버변수 3개, 메서드 2개 정의
MyClass 를 정의하고
Ex02_MyClassTest 에서 인스턴스 2개 만들어 출력하기

나는 성적관리 프로그램을 만들어 보았다.

class MyClass {
	String  name;
	int strNumber;
	int kor , eng , math ;
	char grade;
	String minresult="" ,maxresult="";
	int min, max ;
	double avg () {
		double result= (double)(kor+eng+math)/3;
		return result;
	}
	

	char grade() {
		double result = (kor+eng+math)/3;
		char gradeResult ;
		switch ((int)(result/10)) {
		case 10:
		case 9:
			gradeResult ='A';
			break;
		case 8:
		case 7:
			gradeResult ='B';
			break;
		case 6:
			gradeResult ='C';
			break;
		default:
			gradeResult ='D';
			break;
		}
		return gradeResult;
	}
	String cheerUp() {
		String cheerString ;
		double result = (double)(kor+eng+math)/3;
		if (result>80) {
			cheerString = "참 잘했어요";
		}else if (result>60) {
			cheerString ="조금 더 노력하세요";
		}else {
			cheerString="이러면 큰일 나!!";
		}
	
		return cheerString;
	}
	
	String tosString() {
		return "이름 : "+name+", 학생번호 : "+strNumber+", 평균 :"+avg()+", 등급 : "+grade() ;
	}
	void max() {
		max = kor;
		max = Math.max(max,eng);
		max = Math.max(max,math);
		if (max ==kor) {
			maxresult += "국어, ";
		}
		if (max==eng) {
			maxresult += "영어, ";
		}
		if (max==math){
			maxresult +="수학";
		}

	}
	void min () {
		min = kor;
		min = Math.min(min,eng);
		min = Math.min(min,math);
		
		if (min ==kor) {
			minresult += "국어";
		}
		if (min==eng) {
			minresult += "영어";
		}
		if (min==math){
			minresult+="수학";
		}

	}
}




public class Ex02_MyClassTest {
	public static void main(String[] args) { //출력을 위한 메서드
		MyClass strListClass = new MyClass();
		strListClass.name = "정혜미";
		strListClass.strNumber=1;
		strListClass.kor = 100;
		strListClass.eng =12;
		strListClass.math=70;
		strListClass.min();
		strListClass.max();
		
		Scanner scanner = new Scanner(System.in);
		MyClass scannerStu = new MyClass();
		System.out.println("학생 이름");
		scannerStu.name = scanner.nextLine();
		System.out.println("학생 번호");
		scannerStu.strNumber = Integer.parseInt(scanner.nextLine());
		System.out.println("영어 점수");
		scannerStu.eng = Integer.parseInt(scanner.nextLine());
		System.out.println("수학 점수");
		scannerStu.math = Integer.parseInt(scanner.nextLine());
		System.out.println("국어 점수");
		scannerStu.kor = Integer.parseInt(scanner.nextLine());
		scannerStu.min();
		scannerStu.max();
		
		
		System.out.println("학생 "+scannerStu.name+"의 성적표");
		System.out.printf("국어점수: %d , 영어점수: %d , 수학점수: %d , 평균점수: %f , 등급: %c %n" ,
				scannerStu.kor,scannerStu.eng , scannerStu.math ,  scannerStu.avg() , scannerStu.grade());
		System.out.println(scannerStu.tosString());
		System.out.println(scannerStu.cheerUp());
		System.out.println("최고점 : "+scannerStu.max+ ",과목 :"+scannerStu.maxresult);
		System.out.println("최저점 : "+scannerStu.min+ ",과목 :"+scannerStu.minresult);
		
		scanner.close();
	}
}

어려웠던 부분은 연산하고나면 int 형을 반환하니 double 형으로 형변환을 이루어 줘야한다는 부분이 있었다.

각각의 연산결과를 전역변수로 선언하고 나니 , 생성자초기화를 배우기 전이라, 값이 들어가지 않은 상태에서는 메서드를 사용할 수 없었고 각각의 지역변수를 메서드 마다 선언해주었다.

최고점과 최저점을 계산하기 위해 if를 통하여 문자열의 합산을 이루어 주는것 또한 생각의 전환이 필요했다.