추상 메서드를 포함한 클래스
추상 메서드를 하나 이상 포함하고 있는 클래스는 반드시 '추상 클래스'로 정의되어야 함
추상 클래스 'abstract' 키워드를 사용하여 정의
//추상 클래스의 정의
public abstract class Hello {
public abstract void sayHello();
}
추상 클래스는 객체를 생성할 수 없고, 반드시 상속을 통해서 사용될 수 있다. 즉 추상 클래스는 다른 자식 클래스를 위한 '가이드라인'의 역할을 한다.
공통 기능과 설계 제시를 모두 처라하기
-> 추상 클래스는 생성자, 멤버변수, 일반 메서드 등을 포함
-> 즉 공통 기능과 가이드 라인을 모두 정의하여 다른 클래스에게 상속됨
public abstract class Hello {
//멤버 변수
private string msg;
// 생성자
public Hello(String msg) {this.msg = msg;}
//일반 메서드
public String getMsg() {..}
public void setMsg(String msg) {...}
// 추상 메서드
public abstract void sayHello();
}
package boxing;
public class Unit {
private String name;
public Unit(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void attack () {
System.out.println(this.name + " >> 공격 준비");
}
}
package boxing;
public class Navy extends Unit{
public Navy(String name) {
super(name);
}
@Override
public void attack () {
super.attack();
System.out.println(super.getName() + " >> 어뢰 발사!");
System.out.println(super.getName() + " >> 지상 상륙");
}
public void nucleus() {
System.out.println(super.getName() + " >> 탱크 공격!");
}
}


package boxing;
public class Army extends Unit{
public Army(String name) {
super(name);
}
@Override
public void attack () {
super.attack();
System.out.println(super.getName() + " >> 지상 공격 실행!");
}
public void tank() {
System.out.println(super.getName() + " >> 탱크 공격!");
}
}
package boxing;
public class AirForce extends Unit{
public AirForce(String name) {
super(name);
}
@Override
public void attack () {
super.attack();
System.out.println(super.getName() + " >> 공중 공격 실행");
}
public void bombing() {
System.out.println(super.getName() + " >> 폭격");
}
}
package boxing;
public class Main01 {
public static void main(String[] args) {
//부대 지정
Unit[] units = new Unit[5];
units[0] = new AirForce("공군 1호");
units[1] = new AirForce("공군 2호");
units[2] = new Navy("해군 1호");
units[3] = new Army("육군 1호");
units[4] = new Army("육군 2호");
//부대별 attack() 호출, for문
// 부대 일괄 공격
for(int i=0; i<units.length; i++) {
units[i].attack();
// 원래 클래스의 형태로 명시적 형변환 후 독립적으로 추가한 기능을 사용하는 코드 작성
if(units[i] instanceof Army) {
Army a = (Army)units[i];
a.tank();
} else if(units[i] instanceof Navy) {
Navy n = (Navy)units[i];
n.nucleus();
} else {
AirForce f = (AirForce)units[i];
f.bombing();
}
}
}
}
package abstractclass;
public abstract class Hello {
private String msg;
// 파라미터가 있는 생성자
public Hello(String msg) {
super();
this.msg = msg;
}
// getter, setter 정의
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
// 선언만 되고 구현부를 위한 블록이 존재하지 않음
// 추상 메서드
public abstract void sayHello();
}
package abstractclass;
// 추상 클래스를 상속받는 과정을 일반 클래스의 상속과 동일하게 'extends' 키워드를 사용
public class korean extends Hello {
// 부모 생성자 호출
public korean(String msg) {
super(msg);
}
// 부모 생성자의 호출을 처리하더라도 에러가 사라지지 않는 이유는, 부모 클래스가 정의하고 있는 추상 메서드를 Override를 하지 않았기 때문
// 즉, 추상 메서드의 재정의를 요구하기 위하여 에러가 표시
@Override
public void sayHello() {
}
}
package abstractclass;
public abstract class Unit {
private String name;
public Unit(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//추상 메서드
public abstract void attack();
public abstract void move();
}
package abstractclass;
public class Airforce extends Unit {
public Airforce(String name) {
super(name);
}
@Override
public void attack() {
System.out.println(this.getName() + ">> 공중 공격 실시");
}
@Override
public void move() {
System.out.println(this.getName() + ">> 비행기 이동 실시");
}
}
package abstractclass;
public class Army extends Unit{
public Army(String name) {
super(name);
}
@Override
public void attack() {
System.out.println(this.getName() + ">> 육상 공격");
}
@Override
public void move() {
System.out.println(this.getName() + ">> 이동 준비");
}
}
package abstractclass;
public class Navy extends Unit{
public Navy(String name) {
super(name);
}
@Override
public void attack() {
System.out.println(this.getName() + ">> 폭탄 발사");
}
@Override
public void move() {
System.out.println(this.getName() + ">> 잠수함 이동 실시");
}
}
package abstractclass;
public class Main01 {
public static void main(String[] args) {
Army army = new Army("육군");
Navy navy = new Navy("해군");
Airforce air = new Airforce("공군");
// 다형성이란, 객체의 이름이 서로 다르더라도 객체의 메서드를 호출할 때 고민하지 않기 위한 기법
// 추상화는 다형성을 강제하는 것으로 객체를 사용하는 개발자의 편의 위한 클래스 작성 규칙
army.attack();
army.move();
navy.attack();
navy.move();
air.attack();
air.move();
}
}