추상 클래스와 인터페이스 비교하기
- 추상 클래스
: 추상 클래스는 미완성 클래스이다. 객체가 가지는 특성을 추상화했으나 구현하지 못한 것이다.
추상 클래스를 상속한 자식 클래스는 구현하지 못한 메서드를 구현해야만 객체를 생성할 수 있다.
추상 메서드는 "프로토 타입 메서드"라고도 한다.
- 선언과 구현을 분리시킨다.
- 부모는 자식보다 추상적 또는 일반적이다.
- 자식의 특징에 알맞은 구체적 메서드를 자식의 클래스에서 오버라이딩한다.
1) 추상 메서드가 1개 이상 있을 때(abstract field는 없다.)
2) 추상 클래스를 상속하거나, 인터페이스를 구현한다고 했는데, 오버라이딩 하지 않거나
구현 안 한 메서드가 있을 때
3) 추상 메서드는 없지만 반드시 상속을 해서 사용하도록 강제성을 두기 위해
(final과 반대 - final class는 상속을 금지시켜서 자식이 없다.)
- 인터페이스
: 인터페이스는 프로토 타입이라고 불리는 구현되지 못한 메서드(추상 메서드)만 선언한다.
모든 메서드가 추상 메서드인 추상 클래스는 인터페이스로 바꿀 수 있다.
추상 메서드를 선언 할 깨 abstract 키워드를 메서드에 붙인다. 인터페이스에서 선언된 변수는
자동으로 final static이 붙어 상수가 되고, 메서드는 자동으로 abstract 키워드가 붙는다.
- 선언과 구현을 분리시킨다.
- 커플링을 떨어뜨린다.
- 다중 상속을 흉내낸다.
1) 변수는 자동으로 상수가 된다.
2) private은 사용하지 말고 default 이상을 사용하라.
3) {}(바디)를 붙이지 않는다.
4) 인터페이스에 선언되어 메서드를 구현 못하면 자식 클래스는 추상 클래스가 된다.
5) 인터페이스가 여러 개일 때 ,(컴마)를 사용한다.
6) 상속이 우선이다.
7) 인터페이스는 여러 개의 인터페이스를 extends 할 수 있다.
{
int move(); // 사람은 몇 명 나르는가? (자동으로 public abstract int move();가 된다.)
int carry(); // 무기를 몇 정 나르는가? (자동으로 public abstract int carry();가 된다.)
}
{
public abstract void fly(); // 추상 메서드
public abstract int power(); // 추상 메서드
// 추상 메서드 때문에 추상 클래스가 된다.
}
{
private String id="Air Balls";
{ // 멤버필드를 초기화 하려고 아규먼트가 하나 있는 생성자를 호출하면서 "LeeMass"를 대입
this("LeeMass"); // this 생성자를 이용하여 멤버필드 초기화
}
{
this.id=id;
} // 추상화
{
System.out.println("엔진과 날개를 이용하여 날아감");
}
{
return 10000;
}// 인터페이스
{
return 5;
}// 사람을 몇 명 나르는가?
{
return 300;
}// 무기를 몇 정 나르는가?
{
return this.id+"가 "+power()+"마력으로 "+move()+"명을 나른다.";
}
}
{ /* show(Plane p), show(Ship s), show(SeaAirplane s)와 같이 각 타입에 맞게 호출 할 수 있다.
그러나 show(Plane p), show(Ship s)와 같이 오버로딩된 메서드 두 개만 있을 경우,
show 메서드의 아규먼트로 SeaAirplane 타입을 입력하면 reference to show is ambibuous라는
에러가 난다. SeaAirplane은 Plane도 되고, Ship도 될 수 있기 때문이다. */
{
System.out.print(p.power());
p.fly();
}
{
System.out.print(s.move()+"명을 태우고 ");
System.out.println(s.carry()+"정을 싣고 가고 있다.");
}
{
System.out.println(s);
}
{
System.out.print(s.move()+"명을 태우고 ");
System.out.println(s.carry()+"정을 싣고 가고 있다.");
}
{
System.out.print(p.power());
p.fly();
}
}
{
public static void main(String[] args)
{
SeaAirplane sea = new SeaAirplane("CS110"); // SeaAirplane 타입으로 SeaAirplane의 객체를 생성
Plane p = sea; // 추상클래스 Plane의 이름으로 SeaAirplane을 받을 수 있는 아규먼트의 다형성
Ship s = sea; // 추상클래스 Ship의 이름으로 SeaAirplane을 받을 수 있는 아규먼트의 다형성
SeaAirplaneUtil.show(p); // Plane을 아규먼트로 갖는 show를 호출한다.
SeaAirplaneUtil.show(s); // Ship을 아규먼트로 갖는 show를 호출한다.
SeaAirplaneUtil.showPlane(sea);
}
}
/*
======================================================================================
추상 클래스
1) abstract 키워드를 사용
2) 추상 클래스는 자기 이름으로 자신의 객체를 생성할 수 없으며, 추상 클래스를 상속한
자식 클래스의 객체를 생성하여 사용한다.
3) 추상 메서드는 반드시 자식 클래스에서 오버라이딩하여 구현해야 한다.
그렇지 않으면 자식도 추상 클래스가 된다.
4) 추상 클래스는 반드시 자식을 가져야 한다.
--------------------------------------------------------------------------------------
[추상 클래스가 되는 3가지 경우]
1) 추상 메서드가 1개 이상일 때
2) 추상 클래스를 상속했지만 추상 메서드를 오버라이딩하지 않거나,
인터페이스를 구현했지만 메서드를 구현하지 않았을 때
3) 추상 메서드가 없는데 강제로 상속하여 사용하려는 경우
======================================================================================
*/
abstract class Ship
{
public abstract int move(); // 사람을 몇 명 나르는가?
public abstract int carry(); // 무기를 몇 정 나르는가?
}
class Boat extends Ship
{
public int move()
{
return 6;
}// 사람을 몇 명 나르는가?
public int carry()
{
return 0;
} // 무기를 몇 정 나르는가?
public String name()
{
return "쌩쌩 보트: ";
}
}
class Cruise extends Ship
{
public int move()
{
return 300;
}// 사람을 몇 명 나르는가?
public int carry()
{
return 200;
}// 무기를 몇 정 나르는가?
public String name()
{
return "전함 무궁화: ";
}
}
class ShipUtil
{
public static void search(Ship s)
{
System.out.println(s.move());
System.out.println(s.carry());
if(s instanceof Boat)
{
Boat b = (Boat)s;
System.out.println("Boat 이름: "+b.name());
}
else if(s instanceof Cruise)
{
Cruise b = (Cruise)s;
System.out.println("Cruise 이름: "+b.name());
}
}
}
public class ShipMain
{
public static void main(String[] args)
{
Ship ship1 = new Boat();
Ship ship2 = new Cruise();
System.out.println(ship1.move());
System.out.println(ship1.carry());
System.out.println(ship2.move());
System.out.println(ship2.carry());
ShipUtil.search(ship2);
}
}
===========================================================================================
/*
=======================================================================================
인터페이스(interface)
(1) interface 키워드 사용.
(2) 인터페이스 자기 이름으로 객체를 만들 수 없다.
→ 인터페이스 자기 이름으로 인터페이스를 구현한 클래스의 객체를 생성할 수 있다.
(3) 인터페이스의 추상 메서드(선언된 메서드, 프로토 타입 메서드)는 반드시 인터페이스를
구현하는 클래스에서 구현되어야 한다.
(4) 인터페이스만 구현하고, 추상 메서드를 구현하지 않은 클래스는 추상 클래스가 된다.
(5) 인터페이스는 선언과 구현을 분리시키며, 추상 메서드를 반드시 구현해야 하는 강제성이 있어
인터페이스를 만든 의도대로 클래스를 구현할 수 있다.
(6) 인터페이스의 추상 메서드는 구현된 것이 아니므로 커플링(다른 클래스에 대한 의존성)을 떨어뜨린다.
(7) 다중 상속을 흉내낸다.
---------------------------------------------------------------------------------------
[인터페이스(interface)의 특징]
1) 변수는 자동으로 상수가 된다. (int a=1;은 public final static int a=1;이 된다.)
2) private은 사용하지 말고 기본 접근 제한자 이상을 사용하자.
void show();는 public abstract void show();가 된다. 그래서 추상 메서드라 불린다.
3) void show();와 같이 바디({})를 붙이지 않는다. 메서드 이름을 나열한다.
4) 인터페이스의 추상 메서드를 구현하지 못하면 자식 클래스는 추상 클래스가 된다.
5) 인터페이스가 여러 개일 때, ,(컴마)를 사용한다. (ex) Penguin implements IFish, IBird
6) 상속이 우선이다. (ex) Penguin extends Animal implements IFish
7) 인터페이스는 여러개의 인터페이스를 상속할 수 있다.
(ex) IPenguin extends IAnimal, IFish, IBird
=======================================================================================
*/
interface Flyer
{
int fast = 100; // 상수가 됨
void fly();
boolean isAnimal();
}
class Bird implements Flyer
{
public void fly()
{
System.out.println("날개를 휘저으며 날아감");
}
public boolean isAnimal()
{
return true;
}
}
class Airplane implements Flyer
{
public void fly()
{
System.out.println("엔진과 날개를 이용하여 날아감");
}
public boolean isAnimal()
{
return false;
}
}
class FlyerUtil
{
public static void show(Flyer f)
{
f.fly();
System.out.println(f.isAnimal());
}
}
public class FlyerMain
{
public static void main(String[] args)
{
System.out.println(Flyer.fast); // 상수
Bird b = new Bird();
FlyerUtil.show(b);
Airplane ap = new Airplane();
ap.fly();
FlyerUtil.show(ap);
Flyer f =new Bird();
f.fly();
System.out.println(f.isAnimal());
FlyerUtil.show(f);
Bird bf = (Bird)f;
FlyerUtil.show(bf);
}
}
'IT_Programming > Java' 카테고리의 다른 글
자바 컬렉션 프레임워크 [JCF] (0) | 2007.07.02 |
---|---|
클론을 이용한 참조 타입의 복사본 만들기 (0) | 2007.06.29 |
native method 정의 및 구현 (0) | 2007.06.28 |
ZIP/JAR 엔트리의 생성 제어하기 (0) | 2007.06.28 |
사용자 정의 클래스와 함께 printf 사용하기 (0) | 2007.06.28 |