2014. 11. 9. 17:21ㆍBasic/etc
1. 추상 클래스
상속관계에서 "자동차"라는 클래스를 상속받은 "그랜져"와 "모닝"이라는 클래스가 있다.
구현되는 코드에서는 그랜저 객체나 모닝 객체만을 사용한다고 했을때 자동차라는 객체를 만들지 못하게 하는 방법은 없을까?
자바언어에서는 클래스 선언시 abstract class라고 해주면 그 클래스의 객체를 만들 수 없다.
abstract class Car{}
class Grandeur extends Car{}
class Morning extends Car{}
Car c = new Car(); // 컴파일 에러!
추상클래스는 객체를 만들수는 없지만 "Car c = new Grandeur();"같이 부모클래스형으로 참조변수(레퍼런스)로는 사용될 수 있다.(다형성)
이것이 추상클래스의 가장 중요한 역할 이기도 하다.
2. 추상 메서드
완성되지 못한 메서드. 구현부({...})가 없는 메서드를 말하며 형식은 다음과 같다. abstract 키워드를 사용한다. 실행할 내용이 없으므로 호출될 수도 없다. 추상 메서드의 존재 목적은 "오버라이딩" 이다!
abstract 리턴타입 메서드이름(....);
3. 추상 메서드를 가지는 추상 클래스
추상메서드를 가지는 클래스. 추상클래스는 호출되지 못하는 메서드(추상메서드)를 가지고 있어 객체를 만들 수 없다.
public abstract Person
{
public abstract void move();
}
Person p = new Person(); // p.move()를 호출하면 뭘 실행? --> 컴파일 에러!
추상클래스는 하위클래스를 만들기 위해 존재하고 추상클래스를 상속받은 하위클래스에서 상위클래스의 추상메서드를 오버라이딩 하지 않으면 그 클래스 또한 추상클래스가 된다.
추상 클래스는 확장하지 않으면(서브 클래스를 만들지 않으면) 의미가 없다. 추상 클래스가 있을때 최종적으로 실행되는 코드는 그 추상 클래스의 하위 클래스 객체이다.(물론 객체가 실행되는건 아니고 객체의 메서드가 실행된다)
public abstract Student extends Person
{
}
public Student2 extends Person
{
public void move(){....} // 오버라이딩
}
4. 인터페이스
인터페이스는 클래스의 또 다른 이름이다. 자바의 경우 클래스의 다중 상속은 문법적으로 안되는 것으로 명시되어있어 인터페이스를 이용하여 다중상속의 효과를 낸다.
다중 상속에서 발생하는 문제는 A,B클래스 두개의 클래스를 상속받은 C가 있다고 할때 A,B에 동일한 이름의 메서드를 가지고 있을때 문제가 발생한다.(동일한 이름의 멤버변수도 마찬가지다) 하지만 만약에 A클래스가 추상메서드만을 가지고 있는 경우라면 C입장에서는 중복이 되는 메서드를 가지고 있어도 오버라이딩 해야 하기때문에 다중상속이 가능해진다. 하지만 자바는 다중상속을 지원하지 않으므로 이런 A같은 클래스(추상메서드만 가지는 클래스)를 인터페이스라는 다른 이름으로 정의한다. 인터페이스는 상속이 아닌 구현되어 지면 클래스가 된다.
(인터페이스를 구현이 아닌 상속하면 클래스가 아닌 인터페이스가 된다. 인터페이스간 상속은 다중 상속도 가능하다)
public interface Testable
{
void test();
/* 인터페이스내 모든 메서드는 오버라이딩 되어어야 하는 추상메서드이므로public abstract가 생략한다. */
}
public class MyTest implements Testable
{
// 오버라이딩
public void test()
{
System.out.print("myTest");
}
}
- 인터페이스를 이용한 다중상속의 효과
인터페이스는 클래스의 또 다른 이름이지만 문법적으로는 클래스라는 명칭을 사용하지 않고 extends라는 키워드를 사용하지 않기때문에 다음과 같은 방법이 가능하다.
// A클래스는 B클래스를 상속받고 I 인터페이스를 구현한 클래스이다.
public class A extends B implements I
{
....
}
- 인터페이스 내 멤버변수
인터페이스 내에는 static상수도 올 수 있다. (어차피 하위클래스단에서 값을 바꿀수도 없고 static상수는 클래스명이나 인터페이스명으로 접근하니까...)
public interface Testable
{
int x = 100;
/* static상수 x를 의미하는것으로 public static final int x;의 의미다. public static final는 생략한다. 변할수 없는 상수이므로 초기화도 같이 하는것이 좋다 */
void test();
/* 인터페이스내 모든 메서드는 오버라이딩 되어어야 하는 추상메서드이므로 public abstract가 생략한다. */
}
외부에서 참조할때는 System.out.print(Testabel.x); 형태로 참조하면 된다.
5. 인터페이스의 다형성
인터페이스 클래스이다.(100%의 추상클래스 라고 할까...)
구현된 클래스의 부모형이라 할수 있다. 다형성이 적용된다.
interface CarInterface{...}
class Eclass implements CarInterface{...}
CarInterface ci = new Eclass();
그럼 상속과 구현을 동시에 한 다음과 같은 클래스의 경우는 어떨까?
interface A{
void testA();
}
class B {
viod testB(){...}
}
class C extends B implements A{
void testA(){...} // 오버라이딩
void testC(){...}
}
class MainTest{
public static void main(String[] args){
A a = new C(); // a.testA()만 호출가능
B b = new C(); // b.testB()만 호출가능
C c = new C(); // c.testA(), c.testB(), c.testC() 모두 호출 가능
// 물론 a와 b의 경우도 강제형변환 후에 호출은 가능하다.
(C)a.testC();
}
[출처] [28] OOP - 추상클래스와 인터페이스 (JAVA 개발자) |작성자 zeroDay
'Basic > etc' 카테고리의 다른 글
싱글톤 패턴 (0) | 2014.11.10 |
---|---|
extends 와 implements의 차이? (0) | 2014.11.09 |
접근제어자와 캡슐화 (0) | 2014.11.09 |
객체지향? 추상화? (0) | 2014.11.09 |
다형성 (0) | 2014.11.09 |