1. 싱글톤
class Soojebi {
static private Soojebi instance = null;
// main 에서 s1 선언 후 정적 변수는 더 이상 null 이 아니게 됨
private int count = 0;
static public Soojebi get() {
if (instance == null) { // 정적 변수인 instance 가 null이면
instance = new Soojebi();// Soojebi 생성자
}
return instance; // 그게 아니면 기본 instance 객체 리턴
}
public void count() {
count++; // 증가
}
public int getCount() {
return count;
}
}
class Soojebi2 {
public static void main(String[] args) {
Soojebi s1 = Soojebi.get(); // 여기서 Soojebi 인스턴스 생성
s1.count(); //count= 1
Soojebi s2 = Soojebi.get(); // 인스턴스가 null 이 아니므로 s1 에서 생성된 인스턴스 반환
s2.count(); // 인스턴스의 변수 중 저장된 count 에서 ++
//count= 2
Soojebi s3 = Soojebi.get();// 인스턴스가 null 이 아니므로 s1 에서 생성된 인스턴스 반환
s3.count(); // 즉 s1 , s2 ,s3 은 동시에 객체 Soojebi(s1) 를 가리킴
// count = 3
System.out.println(s1.getCount()); //3 출력
}
}
2. 상속
class Soojebi {
public static void main(String[] args) {
Parent c = new Child();
//업캐스팅 시 오버라이딩 메서드일 경우
//자식의 메서드가 호출됨
c.paint(); // 현재까지 BDCD
c.draw(); // Child의 draw 호출 -> "D" 출력
// BDCDD 출력
}
}
class Parent {
public void paint() {
System.out.print("A");
draw();
}
public void draw() {
System.out.print("B"); // "B" 출력
draw(); //두번째 호출 Child 의 draw()-> "D" 출력
}
}
class Child extends Parent {
public void paint() { // 호추출
super.draw(); // 부모의 draw() 함수 호출
System.out.print("C"); // 현재까지 "BDC"
this.draw(); // 자기 자신의 draw() 호출 -> "D" 출력
} // 현재까지 BDCD
public void draw() {
System.out.print("D");
}
}
3. 재귀+배열
class Soojebi {
public static String fn(String str, int index, boolean[] seen) {
if (index < 0) return "";
char c = str.charAt(index);
String result = fn(str, index - 1, seen);
if (!seen[c]) {
seen[c] = true;
return c + result;
}
return result;
}
public static void main(String[] args) {
String str = "abacabcd";
int length = str.length();
boolean[] seen = new boolean[256];
System.out.print(fn(str, length - 1, seen));
}
}
4. 2차원배열 (역삼각형 채우기)
public class Soojebi {
public static void main(String[] args) {
// 1) 3x3 정수형 2차원 배열 생성
int[][] arr = new int[3][3];
// 2) 배열을 0으로 초기화
init(arr);
//배열 역삼각형 모양으로 숫자 채우기
hourGlass(arr);
// 출력 함수
arrayPrint(arr);
}
public static void init(int arr[][]) {
// arr.length -> 행의 수 (여기서는 3)
for (int i = 0; i < arr.length; i++) {
// arr[0].length -> 열의 수 (여기서는 3)
for (int j = 0; j < arr[0].length; j++) {
arr[i][j] = 0; // 각 칸을 0으로 설정
}
}
}
/*
* - v: 채워 넣을 숫자(1부터 시작)
* - 바깥 루프 i: 각 행(row)을 의미
* - 안쪽 루프 j: i부터 시작해서 오른쪽 끝까지 채움 -> 윗삼각(대각선 포함)이 채워짐
*
* 채워지는 순서(예시, 최종 결과):
* arr =
* [ [1, 2, 3],
* [0, 4, 5],
* [0, 0, 6] ]
*
* 이유: 각 행에서 j를 i부터 시작하면
* i=0 -> j=0,1,2 (행0의 모든 열)
* i=1 -> j=1,2 (행1의 대각선부터 우측)
* i=2 -> j=2 (행2의 대각선)
*/
public static void hourGlass(int arr[][]) {
int v = 0; // 값을 0으로 초기화. ++v를 사용해서 1부터 채움.
for (int i = 0; i < arr.length; i++) { // 각 행(row)
for (int j = i; j < arr[0].length; j++) { // 각 행에서 열을 i부터 시작
// ++v: 먼저 v를 1 증가시키고 증가된 값을 사용.
arr[i][j] = ++v;
// arr[0][0] = 1, 다음 => arr[0][1] = 2, ...
}
}
}
/**
* - 0이면 공백(" ")을 출력해서 비어 보이게 함
* - 숫자면 그대로 출력
* 이렇게 하면 자릿수 정렬(칸 맞춤)이 더 보기 좋아짐.
*/
public static void arrayPrint(int arr[][]) {
for (int i = 0; i < arr.length; i++) { // 각 행 출력
for (int j = 0; j < arr[0].length; j++) { // 각 열 출력
if (arr[i][j] == 0) {
// 0이면 공백 한 칸 출력 (원래 코드 동작 유지)
System.out.print(" ");
} else {
// 0이 아니면 숫자 출력
System.out.print(arr[i][j]);
}
}
// 한 행 출력이 끝나면 줄바꿈
System.out.println("");
}
}
}
//hourGlass 에서 채워진 대로
//역삼각형 모양의 숫자판이 출력됨
// 1 2 3
// 4 5
// 6
5. 상속과 생성자
class Parent {
public Parent() { // 2. Parent 의 생성자가 먼저 호출 됨
this(3); // 3. Parent 클래스의 정수를 매개변수로 받는 메서드를 호출 하여 3을 전달
System.out.print("A"); // 5.this(3) 메서드 호출이 끝나서 A 출력
}
public Parent(int x) { // 4. 호출되어 B 를 출력
System.out.print("B");
}
public void fn1() {
System.out.print("C");
}
public void fn2() {
System.out.print("D"); // 7. 호출되어 D 출력
}
}
class Child extends Parent {
public Child() { // 11. 호출되어 E 출력
System.out.print("E");
}
public Child(int x) { // 9. 호출
this(); //10. Child 의 매개변수가 없는 생성자 호출
System.out.print("F"); // 12. this() 함수가 종료되어 F 출력
}
public void fn1() {
System.out.print("G"); // 13. G 출력
}
public void fn2() {
System.out.print("H");
}
}
public class Soojebi {
public static void main(String[] args) {
Parent a = new Parent(); // 1. Parent 의 인스턴스를 a 에 저장
// 여기까지 BA 출력
a.fn2(); // 6. Parent의 fn2() 함수 호출
// 여기까지 BAD
new Child(5).fn1();
//8. new Child(5) 생성자 호출 -> 자바의 상속 규칙 때문에, 자식 클래스의 생성자가 호출될 때는
// 무조건 부모 클래스의 생성자가 가장 먼저 호출
// BA 출력
// new Child(5)-> Child 의 정수를 매개변수로 받는 생성자 호출
// new Child(5) 까지하면 현재까지 출력은 BADBAEF
// 마지막으로 Child 의 fn1 가 호출 됨
// 최종 출력값은 BADBAEFG
}
}