다형성(Polymorphism)
하나로 여러 일을 할수 있는 것. ex)오버로딩, 상속..



#1 abstract(추상)
: 일부가 추상메서드인 클래스 / extends로 구현
: 완전하지 않은 클래스, 미완성 클래스
"클래스, 메소드" 앞에 abstract가 붙으면 "추상 클래스, 추상 메소드"라 한다.

public abstract class Test{
         public void sayHello(){ };
         public abstract void sayHowareyou();               <- 몸체({})가 없다..
}

(여기 설명에서 말하는 완전한 클래스는 그 클래스만으로 객체를 생성이 가능하다는 것이다)
-추상 클래스는 객체를 생성하지 못한다.
-추상 메서드를 포함하면, 그 클래스는 무조건 추상 클래스다.
-추상 클래스는 하위 클래스가 상속을 해서 쓰려는 용도이다.
-하위 클래스가 상속을 해서 상위(추상) 클래스의 추상메소드를 모두 완전히 구현해주어야 한다. 구현하지 못하면 하위 클래스도 추상클래스가 된다. 구현하면 완전한 클래스가 된다.
-추상 메서드가 없는 추상 클래스는 완전한 클래스이다.(클래스에 abstract만 붙은 것)
-구조

 










#2 interface(인터페이스)
: 전체가 추상 메서드인 클래스 / implements로 구현

인터페이스가 전체가 추상메소드, 상수(final) 멤버변수를 가지므로,
멤버베소드에 public abstract 가 자동으로 붙는다.
멤버변수에 public static final 가 자동으로 붙는다.

키워드를 명시한 경우 키워드를 명시하지 않은 경우
public interface Power{ 
        int volt1 = 100;
        int volt2 = 200; 
        void powerOn();
        void powerOff();
}
public interface Power{
        public static final int volt1 = 100; 
        public static final int volt2 = 200; 
        public abstract void powerOn(); 
        public abstract void powerOff();
}

클래스의 멤버 변수를 접근하려 할때는,
Math 클래스 - public static final double PI     =>     Math.PI 로 접근한다.


JAVA는 다중 상속을 금지한다.
      public class grandfather{ ... attack메소드 ... }
      public class father1 extends grandfather{ ... attack메소드 ... }
      public class father2 extends grandfather{ ... attack메소드 ... }
      public class child extends father1, father2{ ... attack메소드 ... }       <-- 잘못된 사용방식
      이렇게 될 때, child안에서 attack메소드는 father1, father2 중에 뭘선택할 것인가? 또, child가 father1의 grandfather, father2의 grandfather 중에 어디로 캐스팅 될 것인가? 문제가 생긴다.

따라서, implement를 이용해 다중 상속의 개념을 지원한다.

예를 들면, 
              public class VideoShop extends Shop implements IQueue{ ... }
              public class VideoShop extends Shop implements IQueue, IClientManager, IAccount{ ... }
extends 로는 1개만,  implements로는 1개 이상 사용가능하다.










#3 upcasting(업캐스팅)
: 하위 클래스 상위 클래스로 캐스팅 되는 것 / 관련기술 : 상속, 오버라이딩, 가상메서드, 추상클래스, 인터페이스
: 상위클래스 이름으로 하위 클래스 메소드를 사용한다.

예를들면,
             public class Animal { ..A메서드.. } 
             public class Dog extends Animal { ..A메서드, B메서드.. } 
             Animal ani = new Dog();         <-- 업캐스팅


위 ani객체로 A메서드만 사용가능하고, B메서드는 사용할수 없다. 일반적으로 캐스팅은 "작은->큰"인데 반해, 업캐스팅은 "큰->작은"이기 때문에 Animal ani는 자신과 같은 영역공간에 있는 메모리만 접근이 가능기때문이다. 접근할수 없는 부분의 메소드를 사용가능케 하는 이 방법이 오버라이딩가상메서드 기법이다. (C++에서는 virtual 키워드를 붙여 사용한다.)

추상클래스(abstract), 인터페이스(interface)를 이용하여 업캐스팅이 모두 가능하다.
둘다 사용한 예를 들면,

                interface IFork {...} 
                interface ITank {...}
                abstract class AutoCar {...}

                public class MadCar extends AutoCar implements IFork, ITank{...}

                MadCar m = new MadCar();
                AutoCar c = m;                     <----- 업캐스팅
                IFork f = m;                          <----- 업캐스팅
                ITank t = m;                         <----- 업캐스팅

IFork, ITank, AutoCar에 각각 메소드들이 조금씩 들어있다고 하면, MadCar에서는 상속한 부모3개의 클래스 안에 있는 모든 메소드들을 구현해 주어야한다.(안그럼 MadCar도 추상클래스된다.)
MadCar가 부모의 메서드들을 모두 구현했다고 하자. 그러면, c 객체는 MadCar의 메서드들 중에서 c메모리영역에 있는 메서드만 사용이 가능하다. f, t 객체도 마찬가지이다.

즉, 업캐스팅이 됫더라고 해도 MadCar 에 많은 기능이 있지만, 객체들은 자신의 메모리 영역에 있는 메서드만 사용할수 있다.

업캐스팅이 어디에 사용될까요? 음..
1. 리모콘을 봅시다. 회사가 다른 TV들을 하나의 리모콘으로 조작이 가능합니다. 
2. SUN에서 데이터베이스 인터페이스를 공개했다고 하면, 다른 데이터베이스 회사들은 이 인터페이스로 데이터베이스에 접근해서 내용을 구현해주면 됩니다. 이렇게 되면 SUN의 인터페이스를 알면, 다른 데이터베이스 회사들이 만든 데이터베이스에 접근이 가능합니다.









 #4 dawncasting(다운캐스팅)
: 업캐스팅 한 것을 다시 원래형으로 복구시키는 작업

[참고]
java에서 모든 클래스는 최상위 클래스는 Object 클래스를 상속받게 된다.
       class DownTop extends Object{ ... }      ==        class DownTop{ ... }

[다운캐스팅 예를 들면]
class DownTop extends Object{ ... }
public class DownTopMain{
    public static void main(String[] args) {
       DownTop d = new DownTop();
       Object obj = d;                                              //Object <- DownTop : 업캐스팅은 묵시적캐스팅
       System.out.println("Object obj => " + obj);
       DownTop t = (DownTop)obj;                          //DownTop <- Object :업캐스팅된 것을 다시 다운캐스팅-강제캐스팅 
       System.out.println("DownTop t => " +t);
    }
}
____________실행화면______________
Object obj => DownTop@192d342
DownTop t => DownTop@192d342
----------------------------------

위에서, DownTop t = (DownTop)obj 이부분을 instanceof 사용으로 강제캐스팅 전에 정확하게 객체 메모리에 대한 형을 확인할 수도 있습니다.
       if(obj instanceof DwonTop){   DownTop t = (DownTop)obj;   }


다운캐스팅을 하기전에 업캐스팅을 먼저 한다면, 주로 어떤데 쓰이는지 예를 들어보겠습니다.
java.util.Vector 클래스안에 

   public Object elementAt(int index)
   public void addElement(Object obj)

의 메소드가 있습니다. addElement의 받는 자료형이 Object군요.. 대충 느낌이 오네요. 모든 객체들을 받을 수 있을거같네요

                    업캐스팅

String str = new String("안녕하세요");
Integer ig = new Integer(1000);
v.addElement(str);
v.addElement(ig);
                     자료추출



Object obj1 = v.elementAt(0);
Object obj2 = v.elementAt(1);
                  다운캐스팅



String str = (String)obj1;
Integer num = (Integer)obj2;
참고로, 업캐스팅 할때 int a=1000으로 v.addElement(a); 를 한다면, 오류가 발생합니다. int처럼 기본 데이터 타입변수는 클래스객체와 다른 것입니다. 때문에 기본 데이터 타입을 클래스화 시킨 래퍼(Wrapper)클래스가 있습니다.
[래퍼(Wrapper) 클래스의 예]
     1000 -> new Integer(1000) 
     3.14f -> new Float(3.14f) 
     2000 -> new Long(2000L)






아~ 이제 자바가 조금은 어떤건지 알겟네요. 다형성..폴리포피즘..