1.Generic


Generic은 클래스의 인자를 유동적으로 사용하기 위해 만들어진 개념이다.


클래스 생성자나 메소드 그리고 변수의 자료형은 상황에 따라서 유동적일 필요가 있기 때문이다.


사용법은 [접근제한자] class [이름] [<A, B, C, .....>] 와 같이 사용할 자료형 갯수만큼 <> 안에 넣어두면 된다.


기본적인 예제



package chap08.exam04.generic;

public class Box<T> {
	// 아직 뭔지는 모르나 어떤 타입이 설정 될 예정
	// 타입이 설정되면 클래스 모든 타입이 통일 된다.
	// 클래스 선언/객체화 될 때 타입을 설정함.
	// T 자리에는 쓰고싶은거 써도 됨
	private T value;

	public T getValue() {
		return value;
	}

	public void setValue(T value) {
		this.value = value;
	}
}
package chap08.exam04.generic;

public class Main {

	public static void main(String[] args) {
		// 객체화 할 때 타입을 지정
		Box<Integer> box = new Box<Integer>(); // 뒤에 인티져는  생략 가능
		box.setValue(1234);
		int val = box.getValue();
		System.out.println(val);
	}

}



제네릭 선언시에는 다음과 같이 인자를 무한히 사용 할 수 있다.


하지만 getter와 setter 설정과 선언, 객체화 시 번거로움이 생긴다.



package chap08.exam05.multi;
// 복수의 파라미터는 , 로 구분
public class MultiBox<K, V> {
	
	private K key;
	private V value;
	public K getKey() {
		return key;
	}
	public void setKey(K key) {
		this.key = key;
	}
	public V getValue() {
		return value;
	}
	public void setValue(V value) {
		this.value = value;
	}
}
package chap08.exam05.multi;

public class Main {

	public static void main(String[] args) {
		MultiBox<String, Integer> box = new MultiBox<String, Integer>();
		
		// 추천 메소드 항목에서도 반환타입이 바뀐걸 확인 할 수 있다.
		// 데이터 넣기
		box.setKey("홍길동");
		box.setValue(90);
		
		// 데이터 빼기
		String name = box.getKey();
		int score = box.getValue();
		System.out.println(name + " : " + score);
	}

}



제네릭 응용


제네릭의 요소가 너무 많을경우 코드 길이가 길어지고 작성하는데도 오래 걸리지만 다음과 같이 사용하면 된다.



package chap08.exam07.classtype;

public class Employee <T> {
	
	private T t;

	public T getT() {
		return t;
	}

	public void setT(T t) {
		this.t = t;
	}
}
package chap08.exam07.classtype;

public class Info {
	
	private int emp_no;
	private String name;
	private int age;
	private long salary;
	private long asset;
	private float commision;
	private boolean married;
	private String hobby;
	public int getEmp_no() {
		return emp_no;
	}
	public void setEmp_no(int emp_no) {
		this.emp_no = emp_no;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public long getSalary() {
		return salary;
	}
	public void setSalary(long salary) {
		this.salary = salary;
	}
	public long getAsset() {
		return asset;
	}
	public void setAsset(long asset) {
		this.asset = asset;
	}
	public float getCommision() {
		return commision;
	}
	public void setCommision(float commision) {
		this.commision = commision;
	}
	public boolean isMarried() {
		return married;
	}
	public void setMarried(boolean married) {
		this.married = married;
	}
	public String getHobby() {
		return hobby;
	}
	public void setHobby(String hobby) {
		this.hobby = hobby;
	}
}
package chap08.exam07.classtype;

public class Main {

	public static void main(String[] args) {
		Employee<Info> emp = new Employee<Info>();
		// 넣는 과정 info에다가 값 넣음 -> Employee에 저장
		Info info = new Info();
		
		info.setEmp_no(123);
		info.setName("Kim");
		info.setSalary(1000000);
		info.setHobby("movie");
		emp.setT(info);
		// emp에서 info를 빼옴 -> info에서 개별값을 꺼내옴
		info = emp.getT();
		System.out.println(info.getEmp_no());
		System.out.println(info.getName());
		System.out.println(info.getSalary());
		System.out.println(info.getAge());
	}

}


1.Object 형


Object형은 모든 자료형의 상위, 부모에 위치한 자료형이다.


모든 자료형을 받을 수 있다.


안에 무엇이 들어갈지 모를때 Object로 선언하여 먼저 값을 받고 instance of로 값을 확인하여 사용한다.



package chap08.exam03.obj;

public class Box {
	private Object value; // 이 안에 뭐가 들어갈지 모르기 때문에 object 선언

	public Object getValue() { // 겟터 셋터 설정
		return value;
	}

	public void setValue(Object value) {
		this.value = value;
	}
}
package chap08.exam03.obj;

public class Main {

	public static void main(String[] args) {
		// 송장 없는 택배박스
		Box box = new Box();
		box.setValue(1234);
		//캐스팅을 할 때는 instanceof를 활용해야 안전하다.
		int val = (int) box.getValue();
		System.out.println(val);
	}

}


1.String


String은 하나의 자료형이라기 보다는 클래스라고 이해하는편이 쉽다.


문자형을 배열처럼 나열하여 문자열을 만든게 String이다.


String은 만들때 다양한 메소드들, 생성자들이 구현되어 있다.







- 다양한 초기화 방법


package chap08.exam01.string;

public class StringMehod {

	public static void main(String[] args) {
		// 문자열 만드는 방법
		String str1 = "abcd";
		
		String str2 = new String("abcde");
		
		char[] alphabet = {'a','b','c','d','e','f'};
		String str3 = new String(alphabet);
		
		System.out.println(str1);
		System.out.println(str2);
		System.out.println(str3);
	}

}


- 문자열 길이 (length())


- 특정 인덱스 가져오기 (charAt(n))


- 특정 부분부터 원하는 부분까지 잘라내기 (substring(n1, n2) , 자주 쓰이므로 꼭 알아두자


- 문자 배열을 문자열으로 / 문자열을 문자 배열로 넣기


- 특정 구분자를 기준으로 나누기 (split(""))


- 특정 문자열 찾기 (indexOf("")), (lastIndexOf(""))



package chap08.exam01.string;

public class CharArr {

	public static void main(String[] args) {
		
		// 문자열이 배열을 기반으로 해서 가능한 기능
		String str = "asdfghj";
		String strResult;
		int intResult;
		char charResult;
		
		// 문자열의 길이
		System.out.println(str.length());
		
		// 특정 인덱스 가져오기
		System.out.println(str.charAt(3));
		
		// 잘라내기 (자주 씀)
		strResult = str.substring(1, 5); // asdfghj
		// 1번 부터 보여주고 5번부터 잘라내라
		System.out.println(strResult); // sdfg
		
		// 문자열 -> 배열
		char[] chararr = str.toCharArray();
		System.out.println(chararr);
		
		// 배열 -> 문자열
		strResult = new String(chararr);
		System.out.println(strResult);
		
		// 특정 구분자를 기준으로 나누기
		str = "a|b|c|d|e|f|g";
		// 역슬래쉬나 버티컬바와 같은 특수 문자는 문자로 인식이 안됨
		String[] strArr = str.split("\\|"); // 이스케이프 문자인 역슬래쉬를 사용
		for(String s : strArr) {
			System.out.println(s);
		}
		
		// 특정 문자열 찾기
		str = "asfgdhgvabfkjaffasjkfn"; // 0, 8, 13, 16
		int idx = str.indexOf("a");
		// 무조건 첫번째 문자만 반환 한다.
		System.out.println(idx);
		idx = str.lastIndexOf("a");
		// 무조건 뒤에서 부터 첫번째 문자의 인덱스를 반환 한다.
		System.out.println(str.length() + "중 " + idx + "번째");
		// 3개의 a를 모두 찾을 수 있는 방법
		// indexOf("찾을 문자", 시작할 인덱스)
		int a = 0;
		while(true) {
			System.out.println(str.indexOf("a", a));
			a = str.indexOf("a", a) + 1;
			if(str.lastIndexOf("a") < a) {
				break;
			}
		}
	}

}



- 같은지 다른지 비교 (equals(""))


- 공백 제거, Excel 자료 불러올 때 쓰임 (trim())


- 특정 문자 포함 여부 (contains(""))


- 특정 문자열로 시작 or 끝나는가?, 파일 형식 알아낼 때 자주 쓰임 (startsWith(""), endWith(""))


- 문자열 교체 (replace(""))



package chap08.exam01.string;

public class StringUtil {

	public static void main(String[] args) {
		String str = "asdfg";
		
		String strResult;
		int intResult;
		boolean boolResult;
		
		// 문자열 비교
		boolResult = str.equals("abc"); // true | false
		System.out.println("두 문자가 같습니까? " + boolResult);
		
		intResult = str.compareTo("asd"); // 일치하지 않는 갯수
		System.out.println("두 문자가 같습니까? " + intResult);
		
		// 앞 뒤 공백제거 (excel 자료 불러올 때 종종 쓰임)
		str = " 가나다라마바사 ";
		strResult = str.trim();
		System.out.println(str);
		System.out.println(strResult);
		
		// 특정 문자 포함 여부 확인(잘 안씀)
		boolResult = str.contains("다");
		System.out.println("'다'를 포함하고 있는가? " + boolResult);
		
		// 특정 문자열로 시작 | 끝나는가?
		str = "[img]uploadFile.png";
		boolResult = str.startsWith("[img]");
		System.out.println("[img]로 시작되나? " + boolResult);
		boolResult = str.endsWith("png");
		System.out.println("png로 끝나는가? " + boolResult);
		
		// 문자열 교체
		strResult = str.replace("img", "이미지");
		System.out.println("str : " + strResult);
	}

}



- 더해서 넣기


- String Builder


- String Buffer



package chap08.exam02.compare;

public class Compare {

	public static void main(String[] args) {
		String str = "문자열을 "; // 객체 1개
		str += "추가 할 때 마다 "; // 객체 1개
		str += "객체가 추가 된다."; // 객체 1개
		System.out.println("String : " + str);
		
		// Builder나 Buffer는 하나의 객체를 확장하며 사용
		StringBuilder builder = new StringBuilder("문자열을 ");
		builder.append("추가 할 때 마다 ");
		builder.append("객체의 크기가 늘어 난다.");
		System.out.println("builder : " + builder);
		
		// StringBuffer는 동시 접속을 허용하지 않는다
		StringBuffer buffer = new StringBuffer("문자열을 ");
		buffer.append("추가 할 때 마다 ");
		buffer.append("객체의 크기가 늘어 난다.");
		System.out.println("buffer : " + buffer);
	}

}


1.Throw


Throw 예외처리는 예외가 예상되는 클래스와 메소드 이름 옆에 명시해줘야 하며 


오류가 발생한다면 throw에 적어놓은 클래스가 작동한다.


다르게 말하면 책임을 다른 클래스에 전가한다고 할 수도 있으며


따로 만들어 예외상황을 대처할 수 있다.


Java에서 미리 만들어둔 다양한 Exception도 역시 사용 가능하다.




package chap07.exam07.turn;

public class Sub {
	public void method1() throws NumberFormatException {
		// 2. method2()에게 일을 시킨다.
		method2();
		// 5. main에 책임 전가
	}
	public void method2() throws NumberFormatException {
		Integer.parseInt("asdfg"); // 3. 문제발생
		// 4. method1에 책임 전가
	}
}
package chap07.exam07.turn;

public class Main { // 비유로 폭탄돌리기

	public static void main(String[] args) throws Exception {
		// 1.main에서 Sub.method1()에게 일을 시킨다.
		Sub sub = new Sub();
		sub.method1();
		// 6. 결국 JVM에 책임을 전가 - 예외 메세지만 뿌려준다.
	}

}





2.커스텀 예외처리


Throw에 직접 작성한 클래스 파일을 지정하는 것이다. 예제를 확인해보자

package chap07.exam08.custom;

// 처음에 exception을 상속하는데 일반 예외라서 컴파일러에 오류가 걸리므로
// runtime exception으로 변경
public class ReservedException extends RuntimeException {

	public ReservedException(String msg) {
		super(msg);
	}
	
}
package chap07.exam08.custom;

public class JoinMember {
	
	String[] reserved = {"admin", "tester", "member"};
	
	public void regId(String userId) {
		// userId가 reserved에 있는 값과 일치 하면 안됨
		for(String name : reserved) {
			if(name.equals(userId)) {
//				System.out.println("예약어 입니다.");
				// 예외 발생이 목적이므로 변경
				// throw new XXXException("msg");
				// throw new RuntimeException("실행 예외");
//				throw new Exception("일반 예외"); // java에서 잡아주는 예외이므로 빨간줄
				throw new ReservedException(userId + "는 예약어 입니다.");
			}
		}
	}
}
package chap07.exam08.custom;

public class Main { // 임의의 예외처리 만들기

	public static void main(String[] args) {
		JoinMember join = new JoinMember();
		join.regId("admin");
	}

}


'개념 및 코딩 > 06.기타' 카테고리의 다른 글

[JAVA]06-06.Generic  (0) 2018.09.03
[JAVA]06-05.Object  (0) 2018.09.03
[JAVA]06-04.String  (0) 2018.09.03
[JAVA]06-02.예외처리 instance of, try catch  (0) 2018.09.03
[JAVA]06-01.중첩 클래스, 중첩 인터페이스  (0) 2018.09.03

1.예외처리, instance of


예외처리는 자바 작성 하고 실행 할 때에 발생하는 오류를 말한다.


예외는 수없이 많지만 대표적인것 3가지만 설명하자면


- NullPointerException


String data = null;

// ex 돈 안주고 심부름 시킬 경우

data.toString(); // null인 값에 무언가 하려고 할 경우


위와 같이 null값을 넣거나 초기화 하지 않아 null값이 들어가 있는데 참조 또는 호출을 할 경우 발생하는 오류이다.


가장 많이 발생하며 코딩의 논리적 순서나 어딘가에서 실수를 하였을 경우 자주 등장한다.


- ArrayIndexOutOfBoundsException


String[] var = new String[2];

var[0] = "data1";

var[1] = "data2";

// 예외 발생 지점

var[2] = "data3";


배열의 방의 크기는 2인데 3으로 가정 하고 작성하였을 경우 발생하는 오류이다.


- NumberFormatException


String data;

int val;

// "1234" -> 1234

data = "1234";

val = Integer.parseInt(data);

// "1q2w3e" -> 1q2w3e (예외 발생)

data = "1q2w3e";

val = Integer.parseInt(data);

System.out.println(data);


자료형을 잘못 지정하여 발생하는 오류이다.


값을 입력받을때 어떤 형식이 들어올지 예측할 수 없다면 instance of 라는 기능을 사용하여 조건문에 사용하면


구분 할 수 있다. 다음의 예제를 통해 쓰임을 살펴보자


package chap07.exam04.exception;

public class ClassCastingEx {

	public static void main(String[] args) {
		Object value = 1234;
		int intVal = (int)value;
		// 원래 숫자기 때문에 문자열 변환이 안된다.
//		String stringVal = (String)value;
		// 이것을 방지하기 위한 방법
		String strVal;
		
		if(value instanceof String) {
			strVal = (String)value;
		}else {
			strVal = "" + value;
			System.out.println(strVal + "숫자형을 문자로 변환이 불가능 합니다.");
		}
	}

}




2.try catch문


try catch문은 특정 코드 부분에서 예상된 오류가 발생했을 경우 처리할 구문을 작성 할 때에 쓴다.


try{ 진행할 코드 } catch ( 예상되는 오류 코드 ) { 오류 발생 시 작동 할 코드 } 


위와 같이 작성하며 오류코드는 너무 많기 때문에 보통 Exception e와 같이 작성하여 모든 예외를 받는다.



package chap07.exam05.tryCatch;

public class Main {

	public static void main(String[] args) {
		String data1 = "12345";
		String data2 = "asd";
		String data3 = "56789";
		
		try { // 문제가 날 것 같은 예상 지점
			
			int value1 = Integer.parseInt(data1);
			int value2 = Integer.parseInt(data2);
			
		} catch (NumberFormatException e) { // 예외 발생 시
			
			System.out.println("입력된 문자가 숫자로만 구성되었나?");
			System.out.println(e.toString());
			
		} finally { // 예외이던 아니던 무조건 실행
			
			System.out.println("data1 : " + data1);
			System.out.println("data2 : " + data2);
			
		}
	}

}


'개념 및 코딩 > 06.기타' 카테고리의 다른 글

[JAVA]06-06.Generic  (0) 2018.09.03
[JAVA]06-05.Object  (0) 2018.09.03
[JAVA]06-04.String  (0) 2018.09.03
[JAVA]06-03.Throw 예외처리, 커스텀 예외처리  (0) 2018.09.03
[JAVA]06-01.중첩 클래스, 중첩 인터페이스  (0) 2018.09.03

1.중첩 클래스


중첩 클래스란 클래스 안의 클래스라고 보면 된다.


중첩 클래스는 바깥의 클래스에 접근하기 용이하고 다른 사람이 읽기에도 좀 더 편리하며


유지 보수에도 효율적이다.


인스턴스, 정적, 로컬 멤버가 있으며 다음 예제를 통해 확인해보자.

package chap07.exam01.overClass;

public class Exclass {
	public Exclass() {
		System.out.println("외부 클래스 생성");
	}
	
	// 1. 인스턴스 멤버 - 객체화 해야 사용 할 수 있는 클래스 (클래스 영역에 생성)
	
	public class InsClass {
		public InsClass() {
			System.out.println("인스턴스 멤버 생성");
		}
		int field = 0;
		void method() {
			System.out.println(field + "을 출력하는 메서드");
		}
	}
	
	// 2. 정적 멤버 - 객체화를 하면 사용 할 수 없는 클래스

	public static class StaticClass{
		public StaticClass() {
			System.out.println("인스턴스 멤버 생성");
		}
		int field = 0;
		void method() {
			System.out.println(field + "을 출력하는 메서드");
		}
		
		static int sfield = 0;
		static void smethod() {
			System.out.println(sfield + "을 출력하는 메서드");
		}
	}
	
	// 3. 로컬멤버 - 메서드가 실행되어야 사용할 수 있는 클래스
	
	void localMethod() {
		// 메서드 안에서만 사용 할 수 있는 클래스
		// 메서드 안에서 선언 생성 전부 해야한다.
		class Local{
			Local(){
			System.out.println("Local 객체 생성");
			}
			int field = 0;
			void method() {
				System.out.println(field + "을 출력하는 메서드 실행");
			}
		}
		Local lo = new Local();
		lo.field = 10;
		lo.method();
	}
}


package chap07.exam01.overClass;

import chap07.exam01.overClass.Exclass.InsClass;

public class Main {

	public static void main(String[] args) {
		// Exclass에 있는 InsClass 사용 하기
		Exclass ex = new Exclass();
		Exclass.InsClass ins = ex.new InsClass();
		// Exclass를 import를 통해서 명시 하여도 됨
		InsClass ins2 = ex.new InsClass();
		ins.field = 3;
		ins2.field = 4;
		ins.method();
		ins2.method();
		
		System.out.println();
		
		
		
		// Static 멤버 가져오기, static 멤버의 static도 객체화 하지 않아야 접근 가능
		Exclass.StaticClass.sfield = 40;
		Exclass.StaticClass.smethod();
		// field와 method 호출 해 보기
		Exclass.StaticClass sta = new Exclass.StaticClass();
		sta.field = 99;
		sta.method();
		
		System.out.println();
		
		// Local member 호출
		ex.localMethod();
	}

}



2.중첩 인터페이스


인터페이스는 중첩 클래스의 인터페이스 버전으로 생각하면 된다.


중첩 클래스와 같이 직관적으로 보이고 특징들은 비슷하다.


예제를 통해 이해해보자.



package chap07.exam02.overInter;

public class Element {
	
	EventListener listener;
	
	void regist(EventListener listener) { // 특정 감시자를 등록
		this.listener = listener;
	}
	
	void trigger() {
		listener.call();
	}

	// Element와 EventListener의 관계가 직관적으로 보인다.
	interface EventListener{
		void call(); // 이벤트 발생 시 호출 할 메소드 구현
	}
	
}

package chap07.exam02.overInter;

public class Main { // 중첩인터페이스

	public static void main(String[] args) {
		// Element에 Listener 등록
		// 이벤트 발생 시 어떻게 되나?
		Element ele = new Element();
		ele.regist(new OnClickListener());
		
		ele.trigger();
		

		Element ele2 = new Element();
		ele2.regist(new OnKeyListener());
		
		ele2.trigger(); // 이벤트 발생 시 호출 할 메소드 구현
	}

}


'개념 및 코딩 > 06.기타' 카테고리의 다른 글

[JAVA]06-06.Generic  (0) 2018.09.03
[JAVA]06-05.Object  (0) 2018.09.03
[JAVA]06-04.String  (0) 2018.09.03
[JAVA]06-03.Throw 예외처리, 커스텀 예외처리  (0) 2018.09.03
[JAVA]06-02.예외처리 instance of, try catch  (0) 2018.09.03

1.익명객체, anony


익명객체란 클래스의 객체화 할 때 메소드를 임시로 생성하는 것이다.


실체가 없다고도 하며 한 두번 쓰이고 말 때에 작성한다. 그리고 일반적으로 static 영역에 만들어지지만


익명 개체는 heap영역에 올라간다. 클래스의 특징인 재사용을 할 필요가 없다면 익명객체가 좀 더 효율적이라고 볼 수 있다.



package chap06.exam06.anony;

import chap06.exam05.poly.Common;
import chap06.exam05.poly.CommonImpl;

public class Main {

	public static void main(String[] args) {
		
		// 익명 개체
		// 일반적인 객체 메서드 사용
		CommonImpl impl = new CommonImpl();
		impl.test1();
		
		// 익명 = 이름이 없다. = 실체가 없다. -> 한번만 쓰고 버리는 경우
		// 클래스는 static 메모리에 만들어지는데 익명 개체는 heap영역에 올려짐
		Common com = new Common() {
			
			@Override
			public void test2() {
				System.out.println("TEST 2");
			}
			
			@Override
			public void test1() {
				System.out.println("TEST 1");
			}
		};
		
		// 익명객체 = 단일클래스에서 한번 쓸 경우
		// 여러 클래스에서 객체를 원할 경우는 비효율적이다.
		com.test1();
		com.test2();
	}

}




2.결합도, Coupling


결합도란 클래스가 얼마나 똘똘 뭉쳐있냐라고 할 수 있다.


클래스의 중요한, 기능들을 공유하는 특징을 여러 클래스를 만들어 분산하였다면 결합도가 낮은것이고


한 두개의 적은 클래스 파일에 많은 기능을 집어 넣었다면 결합도가 높은것이다.


결합도가 낮은 코딩이 재사용, 객체지향의 특징을 더욱 살렸다고 보며 상황에 따라 다를 수도 있지만 더 잘 코딩했다고 한다.


특히 결합도가 낮으면 클래스 하나하나가 복잡하지 않고 보기 쉬울것이며


그러한 이유로 유지보수에 좀 더 효율적이라 볼 수 있다.

'개념 및 코딩 > 05.상속' 카테고리의 다른 글

[JAVA]05-05.추상클래스, 인터페이스  (0) 2018.08.30
[JAVA]05-04.다형성 배열, 활용  (0) 2018.08.29
[JAVA]05-03.다형성  (0) 2018.08.29
[JAVA]05-02.오버라이드  (0) 2018.08.27
[JAVA]05-01.상속  (0) 2018.08.24

1.추상 클래스, Abstract


추상 클래스는 클래스나 메소드 선언시에 접근제한자 뒤에 abstract를 입력하여 표시하고 다른 클래스에서 객체화를 할 수 없다.


추상 메소드는 바디를 가지지 않고 다음과 같이 사용한다. public abstract int abcde ( );


{ } -> 바디를 사용하지 않으며 [접근제한자] [abstract] [리턴타입] [함수이름] [매개변수];로 이루어진다.


하지만 모든 변수와 메소드에 추상화를 하지 않아도 된다.


추상 메소드는 바디가 없기 때문에 사용하기 위해서는 오버라이드를 통해서 기능을 설정해야 하고


다른 클래스와 같이 메소드를 선언하여 사용하는것도 가능하다. 이것이 인터페이스와 차이점 중 하나이다.


추상 클래스는 다형성을 통해 선언은 가능하지만 객체화는 불가능하므로 자식 클래스로 객체화 해 주어야 한다.


그리고 상속관계가 있어야 사용이 가능하다.


추상 클래스는 부모클래스로 사용하여 많은 자식클래스들의 공통 될 메소드를 예측하고 틀을 만들어두어 


오버라이드 해서 사용하는 경우가 많고 초기화는 자식 클래스의 객체화시 사용되는 생성자를 통해서 해야한다.


다음 예제를 통해 확인해보자.



먼저 추상 클래스인 세탁기이다. 기본 세탁기 기능을 선언

package chap06.exam02.absmethod;

public abstract class Laundry {
	// 무조건 만들어야 하는 기능들
	public abstract void 세탁하기();
	public abstract void 헹구기();
	public abstract void 탈수();
	
	public void 건조하기() {
		System.out.println("건조 시킵니다.");
	}
}


다음은 세탁기를 상속받는 드럼세탁기 클래스, Alt + Shift + S를 누르면 오버라이드를 자동으로 잡아주는 기능으로 간편하게 할 수 있다.


package chap06.exam02.absmethod;

public class DrumLaundry extends Laundry {
	// 추상 클래스 상속하여 자동 생성된 추상 메서드들
	@Override
	public void 세탁하기() {
		// TODO Auto-generated method stub
		System.out.println("세탁하기");
	}

	@Override
	public void 헹구기() {
		// TODO Auto-generated method stub
		System.out.println("헹구기");
	}

	@Override
	public void 탈수() {
		// TODO Auto-generated method stub
		System.out.println("탈수");
	}

}


마지막으로 메인 클래스


package chap06.exam02.absmethod;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		DrumLaundry drum = new DrumLaundry(); // Laundry로 다형성으로 생성해도 되지만 새로운걸 추가 할 수 없으므로 왠만하면 자식 클래스를 쓰는게 좋음
		drum.세탁하기();
		drum.탈수();
		drum.헹구기();
		// 추상 클래스의 일반 메서드 호출
		drum.건조하기();
	}

}



2.인터페이스, Interface


추상 클래스가 추상메소드를 선언하고 싶다면 하고 안하고 싶으면 안하는데


인터페이스는 안에 작성된 메소드가 전부 추상화가 된다.


인터페이스의 큰 장점은 상속의 경우 다중 상속이 불가능하여 클래스 하나만 상속이 가능한데


인터페이스를 사용하면 Implements를 사용하여 불러오고 콤마(, )를 사용하여 여러개의 인터페이스를 불러올 수 있다.


자손 클래스에서 인터페이스를 사용하면 인터페이스에 명시한 메소드들을 구현해 두어야 한다.


추상 클래스와 매우 유사한데 다음 표와 예제를 보고 숙지하자.


표는 작성중...



클릭 이벤트 인터페이스 (실제로 클릭 이벤트 담당이 아닌 인터페이스 예를 위한 예제)


package chap06.exam03.inter;

public interface MouseEvent { // 인터페이스
	// 인터페이스에서는 추상메서드에 abstract를 붙이지 않는다.
	public void click(int btn);
	public void dblClick(int btn);
	public double[] move();
	// 인터페이스에서는 일반 메서드를 사용 할 수 없었다.
	// 인터페이스는 jdk 1.8부터 사용가능
	
//	public void wheel(int i) {  //  default/static을 사용하지 않으면 오류발생
//		
//	}
	
	public default void wheel(int i) {   // default를 사용하지 않으면 오류발생
		if(i==1) {
			System.out.println("윗 방향으로 스크롤");
		}else {
			System.out.println("아랫방향으로 스크롤");
		}
	}
	
	public static void setDpi(int dpi) {
		System.out.println("감도 조절 : " + dpi);
	}
}


마우스 이벤트를 받는 Window


package chap06.exam03.inter;
// implements == 구현이라고 부름, 인터페이스만 대상으로 한다.
public class Window implements MouseEvent {

	@Override
	public void click(int btn) {
		System.out.println(btn + "번 버튼 클릭");
	}

	@Override
	public void dblClick(int btn) {
		System.out.println(btn + "번 버튼 더블 클릭");
	}

	@Override
	public double[] move() {
		return null;
	}

}


메인에서 Window를 사용


package chap06.exam03.inter;

public class Main {

	public static void main(String[] args) {
		Window click = new Window();

		click.dblClick(3);
		click.click(1);

		Linux click2 = new Linux();

		click.dblClick(5);
		click.click(4);


		Mac click3 = new Mac();

		click.dblClick(2);
		click.click(8);
		
		// static 사용
		MouseEvent.setDpi(11);
		// 일반(디폴트) 메서드 
		click.wheel(3);


		// 다형성을 이용한 호출 (chap06.exam04.impl)
		MouseEvent aaa;
		aaa = new Window();
		aaa.dblClick(2222);
		aaa = new Linux();
		aaa.dblClick(13);
		aaa = new Mac();
		aaa.wheel(3);
	}

}



'개념 및 코딩 > 05.상속' 카테고리의 다른 글

[JAVA]05-06.익명객체, 결합도  (0) 2018.08.30
[JAVA]05-04.다형성 배열, 활용  (0) 2018.08.29
[JAVA]05-03.다형성  (0) 2018.08.29
[JAVA]05-02.오버라이드  (0) 2018.08.27
[JAVA]05-01.상속  (0) 2018.08.24

1.다형성 배열


일반 변수방(int, String, double 등)에 배열 선언[]을 할 때의 방식처럼


클래스 선언시에도 이용이 가능하다.


배열은 특징이 유사하니 별도의 설명 없이 예제를 보자.


마법사가 3가지의 주문을 외우는 코드로 예를 든다.


주문 클래스

package Chap05.exam08.field;

public class Spell {

	public String casting() {
		return "주문을 외운다.";
	}

}

주문 클래스를 상속받는 마법들

package Chap05.exam08.field;

public class Fire extends Spell {

	@Override
	public String casting() {
		// TODO Auto-generated method stub
		return "화염 " + super.casting();
	}

}




package Chap05.exam08.field;

public class Ice extends Spell {

	@Override
	public String casting() {
		// TODO Auto-generated method stub
		return "얼음 " + super.casting();
	}

}




package Chap05.exam08.field;

public class Light extends Spell {

	@Override
	public String casting() {
		// TODO Auto-generated method stub
		return "빛 " + super.casting();
	}

}


스펠을 배열방식으로 객체화하여 사용


package Chap05.exam08.field;

public class MacroMage {

	public static void main(String[] args) {
		// 한번 실행하면 무조건 세개의 주문이 나가도록 (for문 이용)
		// 배열로 생성해서 객체 생성
		Spell[] mage = new Spell[3];
		
		mage[0] = new Fire();
		mage[1] = new Light();
		mage[2] = new Ice();
		
		for(int i = 0; i < 3; i++) {
			System.out.println(mage[i].casting());
		}
		for(Spell spell : mage) {
			System.out.println(spell.casting());
		}
		
		
//		for(int i = 0; i < 5; i++) {
//			mage = new Light();
//			System.out.println(mage.casting());
//			mage = new Fire();
//			System.out.println(mage.casting());
//			mage = new Ice();
//			System.out.println(mage.casting());
//		}

	}

}


2.활용, 메소드 매개변수에 클래스를 타입으로  설정하기


예전에 설명했듯이 변수 타입 역시 클래스와 같이 구현되고 메소드의 매개변수에 이용할 변수들을 따로 선언해주었다.


그러면 클래스를 직접 선언하고 나서 매개변수에 선언하여 활용 할 수 없을까?


가능하다. 다음 예제를 통해 눈에 익히자.


자동차와 그것을 상속받는 페라리와 마세라티

package Chap05.exam09.refer;

public class Car {
	public void run() {
		
		System.out.println("자동차가 달린다.");
	}
}


package Chap05.exam09.refer;

public class Ferrari extends Car {

	@Override
	public void run() {
		System.out.println("페라리가 달린다.");
}

}



package Chap05.exam09.refer;

public class Maserati extends Car {

	@Override
	public void run() {
		System.out.println("마세라티가 달린다.");
	}

}


운전자 클래스


package Chap05.exam09.refer;

public class Racer {
//	public void drive(Car car) {
//		//Car 형태면 Car가 부모클래스이기 때문에 어떠한 객체라도 다 받을 수 있다.
//		car.run();
//	}
	
	// 다형성을 사용 하지 않을 경우?
	// 각 형태별 메서드를 만들어야 한다.
	// 오버로드를 사용하면 사용자 입자에서는 동일
	
	public void drive(Maserati car) {
		// 다형성을 사용하지 않아 고유의 멤버 사용이 가능
		car.run();
	}
	public void drive(Ferrari car) {
		car.run();
	}
	public void drive(McLarren car) {
		car.run();
	}
}


레이서 클래스를 불러오는 메인 클래스


package Chap05.exam09.refer;

public class Main {

	public static void main(String[] args) {
		// 레이서를 부른다
		Racer man = new Racer();
		Car car1 = null; // 차를 가져온다.
		car1 = new Maserati();
//		man.drive(car1);

		man.drive(new McLarren());
		man.drive(new Ferrari());
	}

}


'개념 및 코딩 > 05.상속' 카테고리의 다른 글

[JAVA]05-06.익명객체, 결합도  (0) 2018.08.30
[JAVA]05-05.추상클래스, 인터페이스  (0) 2018.08.30
[JAVA]05-03.다형성  (0) 2018.08.29
[JAVA]05-02.오버라이드  (0) 2018.08.27
[JAVA]05-01.상속  (0) 2018.08.24

1.다형성


다형성이란 단순하게 부모클래스로 선언하여 자식클래스로 객체화하거나 그 반대를 의미한다.


특징으로는 자식클래스의 기능을 간편하게 이용할 수 있다는게 가장 큰 장점이고 


단점으로는 겹치는 기능들만 사용하도록 기능이 축소되는것이다.


부모클래스로 선언하여 자식클래스로 객체화에는 따로 작업이 필요 없고 (묵시적 형변환, Promotion)


자식클래스에서 부모클래스로 이용을 할 때에는 따로 형변환을 적어줘야 한다. (Casting)


다형성을 사용하면 공간을 효율적으로 사용하고 객체 방을 새로 선언할 수고를 덜어준다.


아래 두가지 예제를 살펴보자



1. 포유류와 조류의 관계에 대한 다형성 예제


package Chap05.exam06.promotion;

/************************************************************
 			-  상속 관계  - 
 		 		Vertebrate
  				l			l
  			Birds			Mamal
 			/ 	l				/  l
 Chicken 	Ducks  Dog    Cat
 
 ************************************************************/

class Vertebrate{}


class Birds extends Vertebrate {}	// 조류
class Mamal extends Vertebrate {}	//포유류


class Chicken extends Birds {}		// 닭
class Duck extends Birds {}			// 오리 

class Dog extends Mamal {}			// 개
class Cat extends Mamal {}			// 고양이

/************************************************************/

public class Promotion {

	public static void main(String[] args) {
		// Promotion : 작은거 -> 큰거
		Vertebrate 척추동물;
		척추동물 = new Dog();
		척추동물 = new Cat();
		척추동물 = new Duck();
		척추동물 = new Chicken();
		
		Mamal 포유류;
		포유류 = new Dog();
		포유류 = new Cat();
		// 닭은 포유류를 상속 받지 않았기 때문에 Promotion 불가
		// 포유류 = new Chicken();  // 오류 발생
	}

}










2. Mamal클래스를 상속받은 Cat, Dog 클래스에 대한 Casting 예제


포유류

package Chap05.exam07.cast;

public class Mamal {

	public void birth() {
		System.out.println("새끼를 낳다.");
	}
	public void eat() {
		System.out.println("젖을 먹이다.");
	}
	
}

고양이

package Chap05.exam07.cast;

public class Cat extends Mamal {

	@Override  // 부모로부터 온 것이기 때문에 Promotion시 유지된다.
	public void birth() {
		System.out.println("4마리를 낳는다.");
	}

	// 원래 내 것은 Promotion시 사용하지 못 한다.
	public void mew() {
		System.out.println("냥");
	}
	
}


package Chap05.exam07.cast;

public class Dog extends Mamal {

	@Override  // 부모로부터 온 것이기 때문에 Promotion시 유지된다.
	public void birth() {
		System.out.println("5마리를 낳는다.");
	}

	// 원래 내 것은 Promotion시 사용하지 못 한다.
	public void bark() {
		System.out.println("멍멍 짖는다.");
	}
	
}

Casing 예

package Chap05.exam07.cast;

public class Cast {

	public static void main(String[] args) {


		// Promotion
		Mamal mamal = new Dog();
		mamal.birth();
		mamal.eat();
		//mamal.bark(); // Promotion 했기 때문에 자기것은 사용 불
		
		// bark나 mew를 사용하고 싶을 경우 Casting 사용
		Dog 댕댕이 = (Dog) mamal;
		댕댕이.bark();
		
		mamal = new Cat(); // 다시 Promotion을 해주어 바꿔야 오류가 나지 않음
		Cat 나비 = (Cat) mamal;
		나비.mew();
		
		// 상속받은 객체가 많은 경우 누가 누군지 헷갈리게 된다.
		// instanceof (bool값 반환) 를 사용하면 본래 객체를 확인 할 수 있다.
		if(mamal instanceof Cat) {
			나비 = (Cat) mamal;
			나비.mew();
		} else {
			System.out.println("고양이 객체가 아니에요");
			댕댕이 = (Dog) mamal;
			댕댕이.bark();
		}
		
	}

}


'개념 및 코딩 > 05.상속' 카테고리의 다른 글

[JAVA]05-06.익명객체, 결합도  (0) 2018.08.30
[JAVA]05-05.추상클래스, 인터페이스  (0) 2018.08.30
[JAVA]05-04.다형성 배열, 활용  (0) 2018.08.29
[JAVA]05-02.오버라이드  (0) 2018.08.27
[JAVA]05-01.상속  (0) 2018.08.24

+ Recent posts