9일차 - 240108

김리오·2024년 1월 8일

학원공부 TIL

목록 보기
9/13

📌240105 과제 Solution

  • 각 과목 총점을 구하는 getTotal() 메소드를 만들지 않아도 된다.
    Student 클래스의 생성자를 정의할 때 필드변수로 각 과목의 Total이 누적되도록 작성하면서 효율이 늘었다.
public class Student {
	String name;
	int kor, eng, math;
	static int korTotal, mathTotal, engTotal; //static이 붙은 이 변수는 각 인스턴스의 공통된 속성들 

	//여기서 생성자의 기능은 필드값을 초기화
	Student(String name, int kor, int eng, int math) {
		this.name = name;
		this.kor = kor;
		this.eng = eng;
		this.math = math;
		korTotal+=kor;
		engTotal+=eng;
		mathTotal+=math;
	}

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

		Student[] students = { new Student("강호동", 85, 60, 70),
        					   new Student("이승기", 90, 95, 80),
							   new Student("유재석", 75, 80, 100),
                			   new Student("하하", 80, 70, 95),
                               new Student("이광수", 100, 65, 80) };

		sort(students);
		
		printStudent(students);

	}

	private static void printStudent(Student[] students) {

		System.out.println("========= 학생별   /   과목별 총점 구하기 =========");
		System.out.println("이름\t국어\t영어\t수학\t총점\t평균");

		for (Student obj : students) {
			printInfo(obj);
		}

		for (int j = 0; j < 45; j++) {
			System.out.print("=");
		}

		System.out.println();
		System.out.printf("%s\t%d\t%d\t%d\t", "총점", Student.korTotal, Student.engTotal, Student.mathTotal);

	}

	static void printInfo(Student student) {
		System.out.print(student.name + "\t" + student.kor + "\t" + student.eng + "\t" + student.math + "\t"
				+ student.getTotal() + "\t");
		System.out.printf("%.1f\n", student.getAverage());
	}
	
	private static void sort(Student[] students) {
		for (int i = 0; i < students.length - 1; i++) {
			for (int j = i + 1; j < students.length; j++) { // 초기값, 변하는 값, 최종값

				// students[0] ~ [4] 덩어리 째로 비교
				if (students[i].kor+students[i].eng+students[i].math < students[j].kor+students[j].eng+students[j].math) {
					Student imsi = students[i];
					students[i] = students[j];
					students[j] = imsi;
				}

			}
		}
	}

}

📌Exception / throw(s)

  • new Exception("구체적인 메시지") 객체를 생성한다.
  • throw는 에러를 발생시키는 키워드고, throws나 try~catch문으로 처리한다.
  • java.lang.ArithmeticException은 new를 통해 선언을 하지 않아도 객체가 생성되는 건가??
    • 그렇게 생각하는 이유는, e가 참조변수 역할을 하는 것처럼 보이기 때문이다.
      e.getMessage를 보면 참조변수 e를 통해 getMessage() 메서드를 호출하고 있다.
    • new로 선언하지 않고도 객체 생성할 수 있는 방법이 singleton에 있지 않았나??
      ⭐ 이클립스에서 ArithmeticException 위에 마우스를 올려보면, 답을 알 수 있다.
      ArithmeticException objects may be constructed by the virtual machine...
      즉, 이 클래스의 객체는 JVM에서 생성해주는 것이므로,
      사용자는 그 인스턴스의 주소를 가리킬 변수만 지정해주면 된 것이었다!!
//unchecked exception에 해당 - 컴파일 에러 없음
//실행시 에러 발생 - 예외 발생

class ExceptionExample2_3 {
	public static void main(String[] args) {
		int num1 = 3, num2 = 0;

		try {
			int result = num1 / num2;
			System.out.println(result); //try문에서 오류발생하면 catch문장으로 넘어감
		} catch (java.lang.ArithmeticException e) {
			//ArithmeticException객체에 있는 에러 메시지를 가져온다.
			String message = e.getMessage();
			System.out.println(message);

		}
	}
}
//checked exception을 던지는 메서드
//컴파일 에러 발생
//throws Exception를 가진 메서드 호출시 try~catch문으로 처리

class ExceptionExample3_3 {
	public static void main(String[] args) {
		try {
			int result = add(0, -1); 
			System.out.println(result);
		}catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
	
	//throws Exception : throw에 의해 발생한 에러를 호출한 메서드(여기서는 main)로 넘긴다.
	static int add(int a, int b) throws Exception {
		int result = a + b;
		if (result < 0)
			throw new Exception("0보다 작아 에러 발생합니다.");
		System.out.println("나는 출력이 될까요?"); //출력 안 됨. throw로 인해 호출한 메서드로 넘어간다
		return result;
	}
}

📌간단한 입출금 문제

public class Account {

	String accountNo;
	String ownerName;
	int balance;

	Account(String accountNo, String ownerName, int balance) {
		this.accountNo = accountNo;
		this.ownerName = ownerName;
		this.balance = balance;
	}

	void deposit(int amount) {
		this.balance += amount;
	}

	int withdraw(int amount) throws Exception {
		// Exception 클래스를 이용해서 예외를 발생시킨다.
		if (balance < amount) {
			throw new Exception("잔액이 부족합니다.");
		}
        
		balance -= amount;
		return amount;
	}

}
public class Account_Make {
	public static void main(String[] args) {
		Account obj = new Account("777-777-7777777", "최대박", 10);
		try {
			int amount = obj.withdraw(100000000);
			System.out.println("인출액:" + amount);
			//try에서 오류 문장을 만나면, catch 문으로 넘어감
		} catch (Exception e) {
			String msg = e.getMessage();
			System.out.println(msg);
		}
	}
}

📌상속(Inheritance)

  • 기존의 클래스를 재사용해서 새로운 클래스를 작성하는 것이다.
    코드의 재사용성을 높이고 코드의 중복을 제거하여 프로그램의 생산성과 유지 보수에 크게 기여하는 기능이다.
//모든 클래스의 조상은 Object 클래스이다.
//다른 클래스로부터 상속 받지 않는 모든 클래스들은 자동으로 Object 클래스로부터 상속 받는다.

class Account { //컴파일러가 extends object를 자동으로 추가한다.
				//class Account의 부모는 object

		String accountNo; //계좌번호
		String ownerName; //예금주 이름
		int balance;	  //잔액
    
    	Account(String accountNo, String ownerName, int balance) {
		this.accountNo = accountNo;
		this.ownerName = ownerName;
		this.balance = balance;
	}

	void deposit(int amount) {	//예금한다.
		this.balance += amount;
	}

	int withdraw(int amount) throws Exception {	//인출한다.
		// Exception 클래스를 이용해서 예외를 발생시킨다.
		if (balance < amount)
			throw new Exception("잔액이 부족합니다.");
		// if문 안에 문장이 하나만 있으면 생략 가능
		balance -= amount;
		return amount;
	}

}
  • 부모클래스로 상속 받은 필드와 메서드를 참조하는 super() 메소드
    1. 자손클래스의 생성자 선언 첫줄에는 조상클래스의 생성자를 호출해야 한다.
    2. 조상클래스의 생성자를 호출하면, 조상클래스의 멤버들이 먼저 초기화되어 있어야 한다.
//은행 계좌 클래스를 상속받는 직불 계좌 클래스
//은행 계좌 클래스(Account)			- 슈퍼 클래스(상속을 해주는 클래스)
//직불 계좌 클래스(CheckingAccount)	- 서브 클래스(상속을 받는 클래스)

public class CheckingAccount extends Account {

	CheckingAccount2(String accountNo,
    				 String ownerName,
					 int balance,
                     String cardNo) {
		
		//파라미터 3개의 슈퍼 클래스 생성자 호출문
		//반드시 생성자의 첫번째 명령문이어야 한다.
		//예전에 this()로 생성자 호출했던 것도 연결해서 공부
		super(accountNo, ownerName, balance);
		this.cardNo = cardNo;		//클래스 안에 선언된 필드 초기화

	/*
	 * 매서드 이름 : pay
	 * 매개변수 : 카드 번호(cardNo-문자열), 인출액(amount-정수형)
	 * 반환형 : int
	 * 반환되는 값 : 부모 클래스의 인출메서드 호출
	  
	   balance 필드와 withdraw() 메소드는 Account클래스로부터 상속받아 사용 가능
	   이 클래스 안에 선언되어 있는 것처럼 사용하고 있음
	 */
	// 직불 카드 사용액을 지불한다에 해당하는 메서드
	int pay(String cardNo, int amount) throws Exception {
		if (!cardNo.equals(this.cardNo) || (balance < amount))
			throw new Exception("지불이 불가능합니다.");

		return super.withdraw(amount); //super.은 생략할 수 있다.
	}

}

📌Method overriding

class Account { //은행 계좌 클래스

	String accountNo; //계좌번호
	String ownerName; //예금주 이름
	int balance;	  //잔액
	
	Account(String accountNo, String ownerName, int balance) {//생성자
		this.accountNo = accountNo;
		this.ownerName = ownerName;
		this.balance = balance;
	}

	void deposit(int amount) {
		this.balance += amount;
	}

	int withdraw(int amount) throws Exception {
		if (balance < amount)
			throw new Exception("잔액이 부족합니다.");
		balance -= amount;
		return amount;
	}

}
//마이너스 통장 클래스
// - 상속 받은 withdraw메서드를 다시 구현(메서드 오버라이딩)하는 클래스
/* 메서드 오버라이딩(슈퍼클래스에 정의된 메서드를 서브 클래스에서 재정의하는 것) 조건
 	1. 상속관계
 	2. 부모 클래스의 선언부와 일치(리턴값 타입, 메서드 이름, 매개변수 목록)
 	3. 접근 제어자의 범위는 같거나 넓어야 한다. 
 */

package ex08_04_overriding;

public class CreditLineAccount extends Account {
	int creditLine;	//마이너스 한도 필드

	CreditLineAccount(String accountNo,
					  String ownerName,
					  int balance,
					  int creditLine) {
		super(accountNo, ownerName, balance);
		this.creditLine = creditLine;
	}
	
	//메소드 오버라이딩 - 인출한다 기능 다시 구현
	//(잔액+마이너스 한도) < 인출액  ---- 만족하는 경우 "인출이 불가능합니다" 예외 발생
	int withdraw(int amount) throws Exception {
		if ((balance + creditLine) < amount)
			throw new Exception("인출이 불가능합니다.");
		balance -= amount;
		return amount;
	}

}

📌final

  • 클래스에 붙으면 상속 등 불가 / 메소드에 붙으면 오버라이딩 등 불가

📌abstract

//인스턴스화를 금지하는 abstract키워드(by.미완성)
//abstract 키워드가 붙은 클래스를 추상 클래스(abstract class)라고 한다.
//추상 메서드를 포함하는 클래스 - 메시지 전송 클래스


public abstract class MessageSender {
	String title;		//제목
	String senderName;  //발송자 이름

	MessageSender (String title, String senderName) {
		this.title = title;
		this.senderName = senderName;
	}
	
	//추상 메서드 - 메시지를 송신한다
	abstract void sendMessage(String recipient);

}
class EMailSender extends MessageSender {
	
	String senderAddr;
	String emailBody;

	EMailSender(String title, String senderName,
			String senderAddr, String emailBody) {
		super(title, senderName);
		this.senderAddr = senderAddr;
		this.emailBody = emailBody;
	}
	
	// 슈퍼클래스의 메소드를 오버라이드하는 메소드
	// 추상 클래스를 상속받은 class는
	// 추상 메서드를 구현(implement)해야만 한다!!!(must)
	
	void sendMessage(String recipient) {
		  System.out.println("------------------------------");
		  System.out.println("제목: " + title);
		  System.out.println("보내는 사람: " + senderName + "\n" 
			                 + "보낸 주소 : " + senderAddr);
		  System.out.println("받는 사람: " + recipient);
		  System.out.println("내용: " + emailBody);
	}

}

📌240108 과제 : System.out.println 의미

  • Object 클래스를 상속받고 있는 System 클래스는 몇 가지 유용한 필드와 메서드를 포함하고 있다.
    Public final로 정의되어 있으므로 인스턴스화 할 수 없다.
  • System 클래스의 필드변수인 PrintStream out은 Modifier 설정이 static으로 되어 있으므로,
    '클래스명.필드변수(System.out)' 형태로 호출할 수 있다.
  • 참조변수인 out을 통해 PrintStream 클래스의 멤버를 참조할 수 있고,
    따라서 PrintStream 클래스에 존재하는 인스턴스 메서드인 println()을 호출할 수 있다.
//java.lang 패키지에 있는 항목들은 따로 import를 해주지 않아도 됨
//System 클래스는 API문서 들어가보면, constructor 즉, 생성자가 정의되어 있지 않음

import java.io.PrintStream;

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

		PrintStream out = System.out; //JVM 내부에서 객체 생성

		out.println("모니터에 출력합니다"); // 인스턴스 변수이므로 참조변수를 통해 접근해야 함

	}

}
profile
생각하는 사람이 되고 싶다

0개의 댓글