KB IT’s Your Life 4기 - Java 알고리즘 17일차


형변환

package day_16;

public class Review01 {
	public static void main(String[] args) {
		int i = 100;
		long l = 200;
		float f= l;
		long l2 = (long)f;
//		boolean b = (boolean)i; // boolean 타입은 숫자가 아니다. 정수형과 실수형 사이에는 형 변환이 불가능하다.
//		String s = (String) i;  //String은 객체기 때문에 숫자와 형변환 불가.
		//큰타입 = 큰타입 - 작은타입;
//		int j = 1.0 + 2;  오류발생. double + int = double인데 int에 담을 수 없음.

	}
}

변수의 초기화

package day_16;

public class Review02 {
	static int j; // 멤버 변수, 필드 (static을 사용해야 main 내부에서 사용 가능)

	public static void main(String[] args) {
		int i; // 지역 변수
		//System.out.println(i); //오류발생. 지역 변수는 초기화 필요
		System.out.println(j); //필드의 경우, null, 0, false로 초기화된다.
	}
}

메서드 오버로딩 / 오버라이딩

  • 이름 동일
  • 오버로딩 : 매개변수 다름
  • 오버라이딩 : 매개변수 동일, 리턴타입 동일(자식타입), 상속관계

매개변수? 타입, 개수, 순서 (주의: 이름은 달라도 영향XXXX)

//오류발생 - 오버라이딩은 상속관계여야한다.
class A{
public void a(){}
public static void a(){}
}
//오류 발생. 이름은 같고, 매개변수가 같으면 오버라이딩 규칙 적용
//static void a() {}
//static int a() {}
	
//오류발생 - 이름은 상관없다. 오류 발생한다. 
public void a(int a, int b){}
public static void a(int b, int a){}

변수의 메모리 공간

package day_16;

public class Review03 {
	int i = 100;
	static int j = 200;
	
	public static void main(String[] args) {
//		System.out.println(i); //오류 발생. 공간상 접근 불가
		
		Review03 r = new Review03();
		System.out.println(r.i); //이렇게 불러와야 접근 가능
		
		System.out.println(j); //j는 static임으로 접근 가능
		// ==
		System.out.println(Review03.j); //j와 동일한 결과임
		
	}
}

Final 클래스

  • 상속 불가능한 클래스

System.out.println(Math.PI);

추상클래스

  • new 를 할 수 없어서 상속받은 자식클래스를 이용해서 만들어야한다.
  • 추상클래스를 쓰는 이유는 무조건 자식클래스에서 강제로 필수로 구현해야하는 메소드가 있기 때문이다.
abstract MyShape{
   int x, y;
      public abstract String draw();
}
  • abstract 메소드를 하나라도 가지고 있다면, abstract 클래스로 정의해야함.

예시

package day_16;
/** 도형들의 공통속성정의 */
public abstract class MyShape {
	private int x, y; //도형의 기준 좌표
	
	public MyShape() {
	}
	
	public MyShape(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}


	@Override
	public String toString() {
		return "x=" + x + ", y=" + y ;
	}
	
	public abstract String draw(); // 도형 그리기 기능 제공(내용을 쓰지않을거면 abstract 해준다.)
	
}

package day_16;

public class MyLine extends MyShape { // 오류 발생. MyShape가 abstract 이기 때문. 이걸 부모로 받아서 MyLine도 abstract이 되기에 선언 필요.

	private int x2, y2;

	public MyLine() {

	}

	public MyLine(int x1, int x2, int y1, int y2) {
		super(x1, y1);
		this.x2 = x2;
		this.y2 = y2;
	}

	public int getX2() {
		return x2;
	}

	public void setX2(int x2) {
		this.x2 = x2;
	}

	public int getY2() {
		return y2;
	}

	public void setY2(int y2) {
		this.y2 = y2;
	}

	@Override
	public String toString() {
		return super.toString() + ", x2=" + x2 + ", y2=" + y2 ;
	}

	// 이걸 구현해주면, 오류가 없어짐.
	@Override // Annotation
	public String draw() {
		return "Line";
	}

}

package day_16;

public class ShapeExam {
public static void main(String[] args) {
	MyShape ms = new MyLine(0,0,5,5);
	
	System.out.println(ms.draw());
}
}

String + String

  • String concatenation는 String과 String을 더하면 새로운 String을 만들어 값을 담음.
  • StringBuffer는 값을 바꾸기 전에 누가 쓰고 있으면 안 쓰고 없으면 씀. 속도는 100배 느려지지만, 여러 객체들이 동시에 달려들였을 때, 안정적이다.
  • StringBuilder는 자신의 크기를 키움. 공용이 아니라, 혼자서 쓰는 화장실.

언제이용? toString()을 추가할 때.

@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("MyShape [x=");
		builder.append(x);
		builder.append(", y=");
		builder.append(y);
		builder.append("]");
		return builder.toString();
	}

builder.append(“MyShape [x=”).append(“얍”); 가 가능함.

//Chained call 이라고함. 
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("MyShape [x=").append(x).append(", y=").append(y).append("]");
		return builder.toString();
	}

인터페이스

  • 인터페이스에는 public static final, 추상, default, static, private, private static 메서드가 들어감.
package day_16;

public class ShapeExam {
public static void main(String[] args) {
	//부모 클래스 MyShape, 자식 클래스 MyLine
	MyLine ml = new MyLine(0,0,5,5);
	MyShape ms = ml;
	
	ml.draw();//가능
//	ms.draw();//오류. 부모 타입에는 draw()함수가 선언되지 경우, 사용이 안된다.
	MyDrawable md = ml;
	md.draw();//인터페이스로는 접근이 가능하다. 
	
	
	MyCircle mc = new MyCircle(3,3,9);
	MyDrawable md2 = mc;
	md2.draw();
}
}

package day_16;
/** 도형들의 공통속성정의 */
public class MyShape {
	private int x, y; //도형의 기준 좌표
	
	public MyShape() {
	}
	
	public MyShape(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}


	@Override
	public String toString() {
		return "x=" + x + ", y=" + y ;
	}
	
//	public abstract String draw(); // 도형 그리기 기능 제공(내용을 쓰지않을거면 abstract 해준다.)
	
}

package day_16;

public class MyLine extends MyShape implements MyDrawable{ // 오류 발생. MyShape가 abstract 이기 때문. 이걸 부모로 받아서 MyLine도 abstract이 되기에 선언 필요.

	private int x2, y2;

	public MyLine() {

	}

	public MyLine(int x1, int x2, int y1, int y2) {
		super(x1, y1);
		this.x2 = x2;
		this.y2 = y2;
	}

	public int getX2() {
		return x2;
	}

	public void setX2(int x2) {
		this.x2 = x2;
	}

	public int getY2() {
		return y2;
	}

	public void setY2(int y2) {
		this.y2 = y2;
	}

	@Override
	public String toString() {
		return super.toString() + ", x2=" + x2 + ", y2=" + y2 ;
	}

	// 이걸 구현해주면, 오류가 없어짐.
	@Override // Annotation
	public void draw() {
		System.out.println("draw Line");
	}

}

package day_16;

public class MyCircle extends MyShape implements MyDrawable{ // 오류 발생. MyShape가 abstract 이기 때문. 이걸 부모로 받아서 MyLine도 abstract이 되기에 선언 필요.

	private int radius;

	public MyCircle() {

	}

	public MyCircle(int x1,int y1, int radius) {
		super(x1, y1);
		this.radius = radius;
	}

	public int getRadius() {
		return radius;
	}

	public void setRadius(int radius) {
		this.radius = radius;
	}
	
	@Override
	public String toString() {
		return super.toString() + ", radius=" + radius  ;
	}

	// 이걸 구현해주면, 오류가 없어짐.
	@Override // Annotation
	public void draw() {
		System.out.println("draw Circle");
	}

}

package day_16;

public interface MyDrawable {

	void draw();

}

결과창

draw Line
draw Line
draw Circle

Interface를 사용하는 이유

package day_16;

public class ShapeExam {
	public static void main(String[] args) {
		MyDrawable[] mdarr = new MyDrawable[2];

		mdarr[0] = new MyLine(0, 0, 3, 3);
		mdarr[1] = new MyCircle(5, 5, 9);
		
		mdarr[0].draw();
		mdarr[1].draw();
	}
}

결과

draw Line
draw Circle
  • 모든 객체들이 공통적으로 가지는 메서드로 메서드 분리(기능 분리)
  • 인터페이스도 상속이 가능하다

상속관계가 없는 클래스에서도 인터페이스가 사용이 가능하다.

package day_16;

public class Student implements MyDrawable{
	private String name, major;
	
	public Student() {
	}

	public Student(String name, String major) {
		super();
		this.name = name;
		this.major = major;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getMajor() {
		return major;
	}

	public void setMajor(String major) {
		this.major = major;
	}

	@Override
	public String toString() {
		return "name=" + name + ", major=" + major;
	}

	@Override
	public void draw() {
		System.out.println("draw 학생");
	}

	
}

package day_16;

public class ShapeExam {
	public static void main(String[] args) {
		MyDrawable[] mdarr = new MyDrawable[3];

		mdarr[0] = new MyLine(0, 0, 3, 3);
		mdarr[1] = new MyCircle(5, 5, 9);
		mdarr[2] = new Student("길동이", "컴공");
		
		mdarr[0].draw();
		mdarr[1].draw();
		mdarr[2].draw();
		
	}
}

결과

draw Line
draw Circle
draw 학생

디폴트 메소드

[public] default 리턴타입 메소드명(매개변수, ...) {...}

Random

//현재 시간을 기준으로 random값을 return하는 것.=> import java.util.Random

package day_16;

import java.util.Random;

public class RandomExam {
	public static void main(String[] args) {
		Random r = new Random();
		int ri = r.nextInt(45) + 1;
		System.out.println(ri);
	}
}

Date

package day_16;

import java.util.Date;
import java.util.GregorianCalendar;
import java.time.Year;
import java.util.Calendar;

public class DateExam {
	public static void main(String[] args) {
		Date d = new Date();
		System.out.println(d);
		System.out.println(d.getDate()); //사용하지 않는 것을 추천함
		
		//사용을 추천하는 생년월일 시간 추출방식
		Calendar c = Calendar.getInstance();
		int month = c.get(Calendar.MONTH);
		System.out.println(month);

		///////////////////// 출력 포멧 만들기
		SimpleDateFormat dateFormat = new SimpleDateFormat("yy년"); //yyyy년 하면, 2023년이라고 출력됨. MM월 mm분 dd일 
		String today = dateFormat.format(new Date());
		System.out.println(today);
	}
}

결과

Tue Jul 25 14:47:17 KST 2023
25
6
23년

List, Set, Map

  • Collection
    • List : 순서, 중복 허용
    • Set : 순서X, 중복X
  • Map : 키, 값

ArrayList (ListExam.java)

package day_16;

import java.util.ArrayList;

public class ListExam {
	public static void main(String[] args) {
		ArrayList<String> arr = new ArrayList<String>();
		arr.add("홍");
		arr.add("김");
		arr.add("박");
		System.out.println(arr);
		arr.add(1, "최");
		System.out.println(arr);
		arr.set(1, "강");
		System.out.println(arr);
		System.out.println(arr.get(2));
		arr.remove(0); // "홍" 삭제
		System.out.println(arr);
		arr.remove("김"); // "김" 삭제
		System.out.println(arr);
	}
}

결과

[홍, 김, 박]
[홍, 최, 김, 박]
[홍, 강, 김, 박]
김
[강, 김, 박]
[강, 박]

hashSet (setExam.java)

package day_16;

import java.util.HashSet;

public class SetExam {
	
	public static void main(String[] args) {
		HashSet<String> hs = new HashSet<String>();
		hs.add("홍");
		hs.add("김");
		hs.add("박");
		hs.add("홍"); //중복 저장X
		System.out.println(hs); //내부적으로는 순서없이 관리 중...
		
		hs.remove("김");//index로는 삭제 불가(순서없음)
		System.out.println(hs);
	}

}

결과

[김, 박, 홍]
[박, 홍]

hashMap (mapExam.java)

package day_16;

import java.util.HashMap;

public class MapExam {
public static void main(String[] args) {
	HashMap<String, Integer> hm = new HashMap<String, Integer>();
	hm.put("홍", 70);
	hm.put("김", 80);
	hm.put("강", 80);
	
	System.out.println(hm);
	
	//해시맵 안에 해시맵 넣기
	//HashMap에 홍길동의 수학점수 90, 영어점수 80을 저장한다.
	HashMap<String, Integer> subject = new HashMap<String, Integer>();
	subject.put("수학점수", 90);
	subject.put("영어점수", 80);
	
	HashMap<String, HashMap<String,Integer>> name = new HashMap<String, HashMap<String,Integer>>();
	name.put("홍길동", subject);
	
	System.out.println(name);
	
}
}

{김=80, 강=80, 홍=70}
{홍길동={영어점수=80, 수학점수=90}}

FileReader;

package day_16;

import java.io.FileNotFoundException;
import java.io.FileReader;

public class ExceptionExam {
	//main에서는 try-catch로 메세지를 정확히 보여주면 좋음.
	public static void main(String[] args){
		readFile(); //방법1
		
		try { 
			readFile2(); //방법2
			System.out.println("파일처리성공");
		} catch (FileNotFoundException e) {
			System.err.println("파일 없음.");
			e.printStackTrace();
		}

	}

	private static void readFile() {
		// 파일에서 문자를 읽기
		// 파일이 없는 경우 처리를 위한 try-catch.
		try {
			FileReader fileReader = new FileReader("poem.txt");
			System.out.println("파일 열기 성공");
		} catch (FileNotFoundException e) {
			// System.out.println(); //out은 정상적인 실행사항의 메시지 출력.
			System.err.println("파일 없음."); // error는 오류 상황에서의 메시지 출력. 이클립스만, 빨갛게 출력됨.
			e.printStackTrace();
		}
	}

	//throws를 통해서 file이 존재하지 않는 예외사항에 FileNotFoundException을 던짐
	private static void readFile2() throws FileNotFoundException {
		// 파일에서 문자를 읽기
		FileReader fileReader = new FileReader("poem.txt");
		System.out.println("파일 열기 성공");

	}
}


파일이 있는 경우, 결과

파일 열기 성공
파일 열기 성공
파일처리성공