java/oop

[oop] 11. 학생정보를 저장 후 출력하는 프로그램(StudentApp)

jeri 2024. 4. 18. 18:25
반응형
oop > Student.java

1. 학생정보를 저장하기 위한 클래스

  • VO 클래스
  • 학생정보 : 학번,이름,국어,영어,총점
package oop;

//학생정보(학번,이름,국어,영어,총점)를 저장하기 위한 클래스 - VO 클래스
public class Student {

	//인스턴스 필드(Instance Field)
    // => 객체 생성시 메모리(Heap 영역)에 만들어지는 필드 
	private int num;
	private String name;
	private int kor, eng, tot;

	//정적 필드(Static Field)
    // => 클래스 생성시 메모리(Static 영역)에 만들어지는 필드
	// => 객체가 생성되기 전에 메모리에 하나만 생성되는 필드
	// => 생성자에서 초기화 처리하지 않고 직접 초기화 설정
	// => 모든 객체에서 정적 필드 사용 가능 - 공유값 : 메모리 절약 및 필드값 변경 용이
	// => 클래스 외부에서는 클래스 이름을 사용하여 접근
	private static int total=0;//기본값 사용시 초기값 설정 생략
	
	//생성자(Constructor)
    / => 객체 생성시 인스턴스 필드에 원하는 초기값을 저장하기 위해 작성
	public Student() {
		// TODO Auto-generated constructor stub
	}

	//매개변수가 있는 생성자 만들 시 주의점
	// => 모든 필드를 원하는 값으로 초기화시키지 않을 수도 있다.
	// => 예를 들어 계산해서 저장해야하는 필드는 객체의 필드값을 받아 
    // => 계산한 값을 저장해야 하기 때문에 생성자를 초기화시키지 않는다.
	// => ex. tot필드 - tot필드는 없다. 대신 calcTot를 호출해 tot도 초기화시킨다.
	public Student(int num, String name, int kor, int eng) {
		super();
		this.num = num;
		this.name = name;
		this.kor = kor;
		this.eng = eng;
		
		// 생성자에 명령을 작성해 원하는 초기값 이용 가능!
		// => 총점을 계산하여 필드에 저장하는 명령 작성 - 메소드 호출
		// => 코드의 중복성을 최소화하여 프로그램의 생산성 및 유지보수의 효율성 증가
		// => 필요하다면 클래스 내에서 메소드끼리 호출할 수 있도록 만드는 것이 좋음       
		//tot = kor + eng; 
		calcTot(); //코드의 중복성 최소화 및 유지보수의 효율성 증가
	}

	// 인스턴스 메소드
    // => this 매개변수가 존재하는 메소드
	// => 인스턴스 필드 및 정적 필드 접근 가능
	public int getNum() {return num;}
	public void setNum(int num) {this.num = num;}
	public String getName() {return name;}
	public void setName(String name) {this.name = name;}
	public int getKor() {return kor;}
	public void setKor(int kor) {
		this.kor = kor;
		//tot=kor+eng;
		calcTot();
	}
	public int getEng() {return eng;}
	public void setEng(int eng) {this.eng = eng;calcTot();}
	public int getTot() {return tot;}
	public void setTot(int tot) {this.tot = tot;}

	//private 메소드 
    // => 시스템 메소드 (은닉화 선언된 메소드)
	// => private 필드 뿐만 아니라, private 메소드도 사용한다!! 
	// => 같은 클래스 외 접근을 금지한다!
	// => 만드는 이유: 클래스 내부에서 메서드 내 호출 시 사용하기 때문에, 
    // => 외부 클래스에서의 사용을 금지하기 위해 private으로 지정함
	// => private 메소드는 언제 사용하면 좋을까? 생성자 내 특정 메소드를 호출하고 싶을 때 
    // => 호출할 특정 메소드를 private로 만들자!
	// => 즉, 클래스 내에서 메소드끼리 호출할 수 있도록 만드는 것이 좋다!!! 
	// => 왜 생성자 내 메소드를 호출하는가?
    // => 코드의 중복성을 최소화 및 유지보수의 효율성 증가하기 위해서
    
	//은닉화 선언된 메소드 - 클래스 내부에서만 사용하는 메소드 : 시스템 메소드
	// => 코드의 중복성을 최소화하기 위한 기능을 제공
	// => 다른 클래스에서 접근하지 못하게 private설정 
	//public void calcTot() {tot=kor+eng;} //총점을 계산하는 메소드
	private void calcTot() {//총점을 계산하는 메소드
		tot=kor+eng;
	}

	public void display() {
		System.out.print(name+"["+num+"]님의 성적 >> ");
		System.out.println("국어 = "+kor+", 영어 = "+eng+", 총점 = "+tot);
	}

	//정적 메소드(Static Method)
    // => this 매개변수가 없는 메소드
	// => this 매개변수가 없으므로 인스턴스 필드에 접근 불가능
	// => 정적 필드만 접근하여 사용 가능
	// => 객체 생성 전에 클래스 이름을 사용하여 호출 가능 - 메소드 호출의 용이성 
	public static int getTotal() {return total;}
	public static void setTotal(int total) {Student.total = total;}
}

 

 

 

 

oop > StudentApp.java

2. 학생 정보 출력 프로그램

package oop;

public class StudentApp {
	public static void main(String[] args) {

		//👻방법1) 객체 생성 및 메소드 호출 - 비권장
		//아래의 인스턴스는 하나씩 메소드 호출함
		//하지만 효율적인 프로그램을 만들기 위해서는 객체배열 사용 권장
		/*
		Student student1=new Student(1000, "홍길동", 90, 90);
		Student student2=new Student(2000, "임꺽정", 94, 98);
		Student student3=new Student(3000, "전우치", 92, 80);
		Student student4=new Student(4000, "일지매", 76, 82);
		Student student5=new Student(5000, "장길산", 84, 86);
		
        
		//생성자 초기화값에 calcTot();를 호출하기 때문에 아래처럼 calcTot메소드와 display 메소드 2번 쓸 필요없이, display메소드만 이용하면 된다.
		//student1.calcTot();
		//student2.calcTot();
		//student3.calcTot();
		//student4.calcTot();
		//student5.calcTot();
		
        
		student1.display();
		student2.display();
		student3.display();
		student4.display();
		student5.display();
		//홍길동[1000]님의 성적 >> 국어 = 90, 영어 = 90, 총점 = 180
		//임꺽정[2000]님의 성적 >> 국어 = 94, 영어 = 98, 총점 = 192
		//전우치[3000]님의 성적 >> 국어 = 92, 영어 = 80, 총점 = 172
		//을지매[4000]님의 성적 >> 국어 = 76, 영어 = 82, 총점 = 158
		//장길산[5000]님의 성적 >> 국어 = 84, 영어 = 86, 총점 = 170
		
        
		student1.setKor(100);
		//원래는 calcTot() 메소드가 있어야 총점이 변경되지만, setKor() 메소드에 calcTot() 메소드를 호출하기 때문에 
    	//student1.calcTot() 메소드 호출이 필요없어짐
		//student1.calcTot();

		student1.display();
		//홍길동[1000]님의 성적 >> 국어 = 100, 영어 = 90, 총점 = 180
		*/

		
		//👻방법2) 배열을 활용한 객체 생성 및 메소드 호출 -권장
		/*
		//방법1
		//객체를 저장할 수 있는 참조요소가 5개인 배열 생성 - 배열의 참조요소는 기본적으로 null 저장
		Student[] students=new Student[5];
		
		//배열의 참조요소에 객체를 생성하여 저장 - 객체 배열
		//=> 객체가 생성되어 null 대신 각각 객체가 가진 hashcode가 저장됨
		students[0]=new Student(1000, "홍길동", 90, 90);
		students[1]=new Student(2000, "임꺽정", 94, 98);
		students[2]=new Student(3000, "전우치", 92, 80);
		students[3]=new Student(4000, "일지매", 76, 82);
		students[4]=new Student(5000, "장길산", 84, 86);
		
		//메소드호출 (for문 이용 - 일괄처리 목적) 참조변수(요소)에 null이 저장된 상태에서 메소드를 호출한 경우 
        //NullPointerException 발생 가능
		for(int i=0;i<students.length;i++) {
			//참조변수(요소)에 저장된 값이 null이 아닌 경우에만 메소드 호출
			// => NullPointerException 발생 방지
			if(students[i]!=null) {
				students[i].display();
			}
		}
		//홍길동[1000]님의 성적 >> 국어 = 90, 영어 = 90, 총점 = 180
		//임꺽정[2000]님의 성적 >> 국어 = 94, 영어 = 98, 총점 = 192
		//전우치[3000]님의 성적 >> 국어 = 92, 영어 = 80, 총점 = 172
		//을지매[4000]님의 성적 >> 국어 = 76, 영어 = 82, 총점 = 158
		//장길산[5000]님의 성적 >> 국어 = 84, 영어 = 86, 총점 = 170
		*/

		//방법2
		Student[] students={
        	new Student(1000, "홍길동", 90, 90),
			new Student(2000, "임꺽정", 94, 98), 
			new Student(3000, "전우치", 92, 80),
			new Student(4000, "일지매", 76, 82), 
			new Student(5000, "장길산", 84, 86)
        };

        //모든 학생들의 성적 합계를 저장하기 위한 변수지만, 이거 말고 total정적필드를 이용하자!
        //int total=0;

        //🔥NullPointerException발생 안하므로 if문 사용필요없음
        for(Student student:students) {
            student.display();

            //학생 총점을 반환받아 총합계 변수에 누적이지만, 이거 말고 정적필드를 이용하자!   
            //total+=student.getTot();

            //정적 필드는 클래스를 이용하여 접근 - 형식)클래스명.필드명 
            // => 정적 필드의 접근 지정자가 private인 경우 접근 불가능
            //Student.total+=student.getTot();

            //정적 메소드는 클래스를 이용하여 호출 - 형식)클래스명.메소드명(값,값,...);
            Student.setTotal(Student.getTotal()+student.getTot());
        }

		//System.out.println("총합계 = "+total);//모든 학생들의 점수 총합계를 출력
		System.out.println("총합계 = "+Student.getTotal());//총합계 = 872

	}
}
반응형