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