Java - 다형성, equals, 정렬로직, 인터페이스, template 패턴

|
package Week01;

import java.util.Scanner;

//실습3]
interface AnimalType {
	public String bark();
}
class Dog1 implements AnimalType {
	@Override
	public String bark() {
		return "멍멍";
	}
}

class Cat implements AnimalType {
	@Override
	public String bark() {
		return "야옹";
	}
}

public class 실습2일차 {
	
//실습2]
	private int move;
	private int arr[];
	public 실습2일차(int move, int arr[]) {
		this.move = move;
		this.arr = arr;
		ArrMove();
	}
	public void ArrMove() {
		for (int y = 0; y < move; y++) {
			int temp; //임시보관함 만듬
			temp = arr[0]; //0번째 배열값을 임시보관함에 저장. 반복문 실행될 경우 0번째 값은 사라지기에.
			for (int x = 1; x < arr.length; x++) {
				arr[x - 1] = arr[x];
			}
			arr[arr.length - 1] = temp; // 임시보관함에 저장한 것을 마지막 배열에 투입.
		}
	}
	public String toString() {
		return arr[0] + " " + arr[1] + " " + arr[2] + " " + arr[3] + " " + arr[4] + " " + arr[5] + " " + arr[6] + " ";
	}
	
//실습3]
private AnimalType type;
	public void setType(AnimalType type) {
		this.type = type;
	}
	public void bark() {
		System.out.println(type.bark());
	}
	
	
	public static void main(String[] args) {
		
		/*실습1 : 일반화, 추상화
		 * 1.Transformation(운송수단) : 교통통합시스템(기준, 전제)
		 * - 속성 : 이름, 평균속도, 승차가용인원, 배차간격, 첫차시간, 막차시간
		 * - 메소드 : 이동하다(추), 정차하다, 승객을 승차시킨다, 승객을 하차시킨다, 운행시간이 종료되다, 운행시간이 시작되다
		 * 2.Food : 배달(기준, 전제)
		 * - 속성 : 배달시간, 배달가능지역, 주문방법, 배달수단, 영업시간
		 * - 메소드 : 배달하다, 수거하다, 주문을 받다, 결제하다, 배달비를 따로 받는다 
		 * 3.Transformation 추상화 : 운송가능지역, 운임요금, 운행시간  
		 * 4.Food 추상화 : 칼로리, 가격대, 주로주문하는 연령대  
		 */
		
		
		/*실습2 : 배열원소 이동
		 * 입력 : 1~10
		 * 출력 : [2,3,4,5,6,7,1]
		 * -메소드를 만들고, 호출해서 배열을 넣고, 스캔쓰지말고, 왼쪽씩 1칸씩 옮기는 개념.
		 * - 생성자로 받았으면 멤버로 넣는다.
		 * - 알고리즘보단 구조를 만드는게 더 중요함.
		 */
		
		Scanner input = new Scanner(System.in);
		System.out.println("숫자를 입력하세요.");
		int move = input.nextInt();

		int[] arr = { 1, 2, 3, 4, 5, 6, 7 };

		실습2일차 am = new 실습2일차(move, arr);
		System.out.println(am.toString());
		
		/*실습3 : 동물짖기
		 * Animal class를 설계한다.
		 * 생성자로 AnimalType(부모클래스)을 파라미터로 받는다
		 * bark() 메소드를 통해 동물의 짖는 소리를 출력한다 : Dog는 멍멍, Cat은 야옹 (자식클래스, 오버라이딩)
		 * 현재 Dog와 Cat의 클래스만 존재하는데 향후 추가될 수 있다.
		 * - 
		 */
		
		Cat cat = new Cat();
		Dog1 dog = new Dog1();
		실습2일차 pr = new 실습2일차();
		
		pr.setType(cat);
		pr.bark();
		

	}

}
--------------------------------------------------------------------------
/*다형성*/
1. 여러개의 개별적인 클래스를 하나의 부모클래스 객체로 통합관리 -> 효율성을 높임
2. 자식 클래스의 instance를 부모class에 담았을때 접근 규정
- 부모 class가 가지고 있는 모든 멤버들에 접근
- 단 자식class에서 메소드 overriding 했다면 overriding 된 자식의 멤버에 접근
- 멤버 필드의 경우 부모 class의 멤버 필드에만 접근 가능

package Week01.polymor;

class A6{
	public void aaa() {
		System.out.println("aaa");
	}
	public void bbb() {
		System.out.println("bbb");
	}
}

class B6 extends A6{
	public void bbb() {
		System.out.println("bbb1");
	}
	
	public void ccc() {
		System.out.println("ccc");
	}
}

public class PolymorTest {

	public static void main(String[] args) {
		A6 ap = new B6(); // 다형적 표현 ap 는 b의 인스턴스를 가리킴
		ap.aaa(); //A6클래스의 aaa()메소드 호출 ? aaa출력
		ap.bbb(); //B6클래스의 bbb()메소드 호출 ? bbb1출력
//		ap.ccc(); //접근 가능한 멤버는 Data type에 의해 결정, compile error 발생 ->A6클래스는 ccc메소드가 없다. 그러므로 에러. (자식만 가지고 있는 메소드는 가리킬수없다.)

	}

}
--------------------------------------------------------------------------

package Week01;

class Car{
	String color; //색상
	String gearType; //변속기 종류 = auto(자동), manual(수동)
	int door; // 문의 개수
	
	Car(){
		this("white", "auto", 4); //parameter 3개 넣음
	}
	
	Car(Car c){ //인스턴스의 복사를 위한 생성자.
		color = c.color;
		gearType = c.gearType;
		door = c.door;
	}
	Car(String color, String gearType, int door){ //3개 받아서 초기화
		this.color = color;
		this.gearType = gearType;
		this.door = door;
	}
	
	long id;
	//Object의 equals를 Overriding
	public boolean equals(Object obj) { //object에 대해서 재정의됨.
		if(obj!=null && obj instanceof Car) { //obj가 Car의 Instance
			//위 3가지 항목이 같은경우 true가 나오게 equals 정의하는 경우...
			//return (this.color ==((Car)obj).color)
			// && (this.gearType ==((Car)obj).gearType)
			// && (this.door ==((Car)obj).door) ... 
			return id ==((Car)obj).id; // 값이 같은지 비교하는 equals? object?로 재정의됨.
		} else {
			return false;
		}
	}
	Car(long id){
		this.id = id;
	}
	
}


public class CarTest3 {

	public static void main(String[] args) {
		Car c1 = new Car(); //인스턴스 생성
		Car c2 = new Car(c1); // c1의 복사본 c2를 생성한다.
		System.out.println(c1.door);
		System.out.println(c2.door);
		
		if(c1==c2) //다르다
			System.out.println("c1과 c2는 같은 car입니다.");
		else
			System.out.println("c1과 c2는 다른 car입니다.");
		
		if(c1.equals(c2)) //같다. 재정의되어 같다고 표시
			System.out.println("c1과 c2는 같은 car입니다.");
		else
			System.out.println("c1과 c2는 다른 car입니다.");

	}

}

//object 0 = c1; -> object o가 c1을 가리킨다는 뜻. 데이터범위는 가리키는 애를 통해 결정됨.
//다형성 - PolymorTest 와 연관된 샘플.
/*class Parent{
 * public String name = 'k'
 * public int age
 * public void test1(){sysout aa}
 * 
 * public String getName{
 * 	this.name}
 * }
 * 
 * class Child extends Parent{
 * 	public void test2(){sysout bb}
 * 	public void test1(){sysout bb}
 * 
 * 	public String name = 'm'
 * 
 * 	public String getName(){
 * 		return this.NAME;
 * 	}
 * }
 * 
 * Child c = new Child();
 * Parent p = c; 
 * c.test1(); -> 가능 aa
 * c.test2(); -> 가능
 * p.test1(); -> 가능 bb (자식 메소드 오버라이딩)
 * p.test2(); -> 불가능 (가리키는 변수의 타입으로 결정.) Parent는 test2 메소드가 없음.
 *  c.name; -> m출력.
 *  p.name; -> k출력.
 *  c.getName; -> m출력.
 *  p.getName; -> m출력. (오버라이딩.) cf. 멤버변수는 오버라이딩x
 */

--------------------------------------------------------------------------
/* abstract */
1. 추상클래스 -> 자식을 통해 의미를 가지는 클래스
2. 인스턴스를 새로 만들 수는 없지만 그 유형의 객체를 저장하기 위한 배열 객체를 만드는 것은 가능.
3. 추상메서드
- 추상 메소드가 있는 클래스는 추상클래스여야 한다.
- 추상 메서드를 상속 받은 자식클래스가 "메소드를 재정의하지 않는다면" -> 자식클래스는 추상메소드를 재정의 하지 않아 추상클래스가 되기 때문에 객체를 생성시키지 못하게 된다.

package Week01;

//정렬로직
//자바에서 제공하는 api 이해하는데 도움됨.
public class SortTest {// ★★★★★ 활용도 높은 소스

	public static void main(String[] args) {
		String[] names = {"이인화", "한희원", "김성연", "심재후"};
		Sorter s = new StringSorter();
		s.doSort(names);
		for(int i =0; i<names.length; i++) {
			System.out.println(names[i]);
		}

	}

}

abstract class Sorter{
	abstract boolean isCorrectOrder(Object o, Object o2); //object는 모든 클래스의 최상위. object가 매개변수로 온이유:모든 클래스를 다 가리키기 위해.
	void doSort(Object[] list) {
		for(int max=list.length-1;max>0;max--) {
			for(int i=0; i<max; i++) {
				if(!isCorrectOrder(list[i], list[i+1])) {
					Object temp;
					temp = list[i];
					list[i]=list[i+1];
					list[i+1]=temp;
				}
			}
		}
	}
}

class StringSorter extends Sorter{
	boolean isCorrectOrder(Object o, Object o2) { //두값이 왔을때 첫번째 값이 크면 false
		if(((String)o).compareTo((String)o2)<=0) { //o2가 더 크면
			System.out.println(o+ "," + o2 + "TRUE, " + ((String)o).compareTo((String)o2));
			return true;
		} else {
			System.out.println(o+ "," + o2 + "FALSE, " + ((String)o).compareTo((String)o2));
			return false;
		}
	}
}
--------------------------------------------------------------------------
/* interface */
1. 다형성에 의한 클래스 제어
-> interface는 클래스가 어떤 역할을 할 수 있는지를 정의.
2. 형식 : 접근_제한자 interface 인터페이스명 extends 상위_인터페이스
3. 인터페이스 포함 멤버 - 필드
-> 무조건 public static final 멤버 필드
4. 인터페이스 포함 멤버 - 메소드
-> 무조건 public abstract 멤버 메서드(public abstact를 붙이지 않아도 error가 나지는 않는다)
-> 구현부가 없음
* 구현부 정의 가능한 예외 2가지
 1) 디폴드 메소드 : 추상메소드가 아니다. 접근제한자는 항상 public 이고 생략할 수 있다.
 2) static 메소드(jdk 1.8) : 접근제한자가 항상 public 이고 생략할 수 있다.
5. 인터페이스에 있는 메소드는 반드시 재정의해야함.

package Week01.iface;

interface interA1{
	int w = 10;
	static int x = 20;
	final int y = 30;
	public static final int z = 40;
}

public class InterfaceTest {

	public static void main(String[] args) {
//		interA1 ap = new interA1(); //interface는 instance를 생성할 수 없다
//		interA1.w = 100; //interface의 필드는 public static final이므로 값을 변경할 수 없다.
		System.out.println("w =" + interA1.w); //w = 10
		System.out.println("x =" + interA1.x); //x = 20
		System.out.println("y =" + interA1.y); //y = 30
		System.out.println("z =" + interA1.z); //z = 40

	}

}

--------------------------------------------------------------------------

package Week01.iface;

interface interA2{
	void aaa();
	public abstract void bbb(); //구현부가 없음.
}

class interB2 implements interA2{
	//A2의 aaa가, public abstract이므로 public으로 지정해야함.
	//자식은 부모보다 넓은 접근제한자를 가져야 한다.
	public void aaa() {
		System.out.println("aaa 메소드");
	}
	public void bbb() {
		System.out.println("bbb 메소드");
	}
}

public class InterfaceTest2 {

	public static void main(String[] args) {
		interB2 bp = new interB2();
		bp.aaa();
		bp.bbb();

	}

}

--------------------------------------------------------------------------

package Week01.pattern;

//template 패턴
//카페인 제조과정
abstract class CaffeineReferage{ //공통된 제조과정 fix
	final void prepareRecipe() {
		this.boilWater();
		this.brew();
		this.pourInCup();
		this.addcndiments();
	}
	
	abstract void brew(); // 구체적으로 정확히 모름. 재정의하게 보냄.
	abstract void addcndiments();
	void boilWater() {
		System.out.println("물 끓이는 중");
	}
	void pourInCup() {
		System.out.println("컵에 따르는 중");
	}
}

class Coffee extends CaffeineReferage{
	void brew() { //재정의
		System.out.println("필터를 통해 커피를 우려내는 중");
	}
	void addcndiments() {
		System.out.println("설탕과 우유를 추가하는 중");
	}
}

class Tee extends CaffeineReferage {
	void brew() {
		System.out.println("차를 우려내는 중");
	}
	void addcndiments() {
		System.out.println("레몬을 추가하는 중");
	}

}
And