일단 해보는 코딩/Java

[Java] 추상 메서드(abstract method)

eun_zoey2 2022. 7. 28. 15:44
728x90
추상 메서드(abstract method)

자식 클래스에서 반드시 오버라이딩해야만 사용할 수 있는 메서드를 의미

자바에서 추상 메소드를 선언하여 사용하는 목적은 추상 메서드가 포함된 클래스를 상속받는 자식 클래스가 반드시 추상 메서드를 구현하도록 하기 위함이다.

 

예를 들면 모듈처럼 중복되는 부분이나 공통적인 부분은 미리 다 만들어진 것을 사용하고, 이를 받아 사용하는 쪽에서는 자신에게 필요한 부분만을 재정의하여 사용함으로써 생산성이 향상되고 배포 등이 용이하다.

 

이러한 추상 메소드는 선언 부만이 존재하며, 구현부는 작성되어 있지 않다.

바로 이 작성되어 있지 않은 구현부를 자식 클래스에서 오버라이딩하여 사용하는 것!!!

 

 

추상 메소드(abstract method)의 구성
[접근제한] abstract [반환형] 메소드이름(); // { } 없이 ;로 마무리
abstract [접근제한]  [반환형] 메소드이름(); // { } 없이 ;로 마무리

 

 

추상클래스(abstract  class) 의 구성

추상 메서드가 한 개 이상 정의되어 있는 클래스를 추상 클래스 하고 하는데, 추상 클래스 또한 abstract를 붙여서 자신이 추상 클래스임을 명시해줘야한다. 

 

[접근제한] abstract class 클래스이름 { 
		....
		}

 

예제 모음)

더보기

예제 1 ) 

 

package Java09;
abstract class AbsEx {
	int value = 100;
	final int VALUE2 = 1000;	//상수는 앞에 final을 붙이고 보통 변수_명을 대문자로 한다.
	public int getValue() {
		return value;
	}
	abstract public void setValue(int n);	// 추상 매써드, {}속에 하는 일이 없다.
}
class AbsChild extends AbsEx {
	int age = 10;
	public void setValue(int n) {	// 부모 추상 클래스의 메써드를 호출해서 재지정
		age += n; //age = age + n // 추상메써드가 할 일을 기술		
	}
		@Override
		public int getValue() {
			return age;
		}
	}

public class Test04 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
//		AbsEx a1 = new AbsEx(); 
		//추상 클래스를 호출해서 작업하려면 추상클래스를 객체로 만들지 못하고 추상메써드가
		//사용되게 설정한 자식 클래스로 객체를 만들어야 한다.
		AbsChild a2 = new AbsChild();
		a2.setValue(20);
		System.out.println(a2.getValue());
	}
}

 

예제 2 )  

package Java09;
abstract class AbsClass {
	int value = 100;
	public int getValue() {
		return value;
	}
	public abstract int changValue();	// 추상 메써드
}

	class AbsChild1 extends AbsClass {
		public int changValue() {
		return value += 10;
	}
}

	class AbsChild2 extends AbsClass{
		public int changValue() {
			return value -=3;
	}
}
public class Test05 {
		public static void main(String[] args) {
			// AbsClass a1 = new AbsClass();	/객체 생성 불가
			AbsChild1 a1 = new AbsChild1();
			System.out.println(a1.changValue());
			AbsChild2 a2 = new AbsChild2();
			System.out.println(a2.changValue());
			System.out.println("-------------");
			System.out.println(a1.getValue());
			System.out.println(a2.getValue());
			System.out.println("-------------");
			
			Test05 ts = new Test05();
			ts.test(a1);
			ts.test(a2);
		}
	public void test(AbsClass n) {	
		// 부모 클래스를 메써드의 인자로 사용했기 때문에 모든 멤버들이 사용 될 수 있다.
		System.out.println(n.changValue());
	}
}

 

예제 3 ) 스타 크래프트에는 세 개의 종족에 지상, 공중 유닛이 분리되어 있고, 유닛마다 공격력이나 방어력이 모두 다르다. 
모든 유닛은 상대방에게 ‘공격을 당한다’라는 액션을 가지고 있지만 공격 당할 때 감소하는 에너지의 수치에는 차이가 있다. 이렇게 공통적인 기능(공격 당한다)이 있으나 내부에서 감소되는 에너지 구현 코드가 각각 다를 때 가상 클래스로 구현하는 것이 좋다.

// Unit 클래스 정의
abstract class Unit {	// 추상 메써드가 있으므로 추상 클래스
	String name;    //이름
	int energy;     //체력	
// 유닛이 공격을 당했을 때 체력 감소량을 관리하기 위한 메서드, 유닛마다 체력 감소량이 // 다르기 때문에 추상메서드로 정의했다.
	abstract public void decEnergy();  // 추상 메써드
	public int getEnergy() {           // 일반 메써드 
		return energy;
	}
}
// Terran 클래스 정의
class Terran extends Unit{
	// 공중유닛이면 true, 지상유닛이면 false
	boolean fly;
	public Terran(String name, int energy, boolean fly) {
		super.name = name;
		super.energy = energy;
		this.fly = fly;
	} // 생성자 오버로딩.	
	@Override
	public void decEnergy() {
		energy -= 3;
	}	
}
// Protoss 클래스 정의
class Protoss extends Unit{
	boolean fly;
	public Protoss(String name, int energy, boolean fly) {
		super.name = name;
		super.energy = energy;
		this.fly = fly;
	}
	@Override
	public void decEnergy() {
		energy--;
	}
}
// Zerg 클래스 정의
class Zerg extends Unit{
	boolean fly;
	public Zerg(String name, int energy, boolean fly) {
		super.name = name;
		super.energy = energy;
		this.fly = fly;
	} // 생성자 오버로딩.
	@Override
	public void decEnergy() {
		energy -= 10;
	}
}
// UnitMain 클래스 정의
public class UnitMain {
	public static void main(String[] args) {
		Terran t1 = new Terran("해병", 100, false);
		t1.decEnergy();  // 재정의한 decEnergy() 호출
		System.out.println("t1의 energy : " + t1.getEnergy());
		Zerg z1 = new Zerg("무리군주", 200, true);
		z1.decEnergy();
		System.out.println("z1의 energy : " + z1.getEnergy());
		Protoss p1 = new Protoss("거신", 250, false);
		p1.decEnergy();
		System.out.println("p1의 energy : " + p1.getEnergy());
	}
}