upcasting, downcasting
package test.oop2; public class PointA { int x; int y; } public class PointB { int x; int y; } public class Point2D { int x; int y; } public class Point3D extends Point2D{ int z; } public class PointTest { public static void main(String[] args) { PointA ptA = new PointA(); PointB ptB = new PointB(); // PointB ptB1 = new PointA(); //error // PointA ptA1 = new PointB(); //error Point2D pt2 = new Point3D(); //ok. 클래스사이의 형변환. Upcasting pt2.x = 10; pt2.y = 20; // pt2.z = 30; //error // Point3D pt3 = pt2; //error Point3D pt3 = (Point3D) pt2; //DownCasting pt3.x = 100; pt3.y = 200; pt3.z = 400; } }
추상클래스를 쓰니까 좋아. 뭔가를 강제할 수 있으니까.
이렇게 스펙을 정해놓은걸 만들어 놓은게 interface지..
package test.oop2; public abstract class Shape { //추상메서드를 가진 클래스는 반드시 추상클래스 double res; //넓이 public abstract void area(); //넓이 계산. 반드시 자식클래스에서 구현하도록. //누구는 size() 이따위로 안하게 강제하는것이지..} }
package test.oop2; public class Circle extends Shape { int r = 10; @Override public void area() { res = r*r*3.14; } }
package test.oop2; public class Rectangle extends Shape { int w = 10; int h = 23; @Override public void area() { res = w*h; } }
package test.oop2; public class Triangle extends Shape implements Poly{ int w = 23; int h = 30; @Override public void area() { res = w*h/2; } @Override public void draw() { // TODO Auto-generated method stub System.out.println("삼각형을 그리다"); } }
package test.oop2; public interface Poly { int poly = 3; //interface내의 변수는 변수가 아니라 상수지. public void draw(); //당연히 바디를 가질 수 없지. }
package test.oop2; public class ShapeTest { public static void main(String[] args) { printArea(new Circle()); printArea(new Rectangle()); printArea(new Triangle()); } private static void printArea(Shape s) { //각각의 printArea 만들 필요없이 업캐스팅, 다운캐스팅 사용,, s.area(); System.out.println(s.res); if (s instanceof Circle) { Circle c = (Circle) s; //down casting System.out.println("반지름이 " + c.r + "인 원의 넓이는 " + c.res + "입니다."); } else if (s instanceof Rectangle) { Rectangle r = (Rectangle) s; System.out.println("가로가 " + r.w + ", 세로가 " + r.h + "인 사각형의 넓이는 " + r.res); } else if (s instanceof Triangle) { Triangle t = (Triangle)s; System.out.println("가로가 " + t.w + ", 세로가 " + t.h + "인 삼각형의 넓이는 " + t.res); t.draw(); } else { System.out.println("에러입니다."); } } }
interface는 왜 쓰는걸까. 상속(재사용)이 아닌데..
우선 스펙을 강제적으로 정의하기 위해서지.
다중상속을 위해서 ? interface는 코드 재사용을 할 수 있는게 아닌데. 내가 어짜피 다 만들어야 하는데? 이게 어떻게 상속이야..
Thread의 예
Thread : 프로세스내의 수행의 흐름
Multi Thread : 하나의 프로세스에서 수행의 흐름이 두개 이상으로 갈라질 때
package test.oop2; public class ThreadTest{ public void run() { for(int i=1; i <= 5; i++) { System.out.println("run : " + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { ThreadTest t = new ThreadTest(); t.run(); for(int i=1; i <= 5; i++) { System.out.println("main : " + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
package test.oop2; public class ThreadTest extends Thread{ //상속받아 Thread구현 public void run() { for(int i=1; i <= 5; i++) { System.out.println("run : " + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { ThreadTest t = new ThreadTest(); t.start(); //run()을 자동으로 호출 for(int i=1; i <= 5; i++) { System.out.println("main : " + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
상속을 이미 받아 Thread를 상속받을 수 없을 경우
Thread에 shift+F2 누르면 메뉴얼이 떠.. (http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html)
package test.oop2; public class ThreadTest implements Runnable{ public void run() { for(int i=1; i <= 5; i++) { System.out.println("run : " + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { ThreadTest t = new ThreadTest(); Thread nt = new Thread(t); //Runnable로 upcasting해서 넣으면 //받는 생성자가 있어. nt.start(); for(int i=1; i <= 5; i++) { System.out.println("main : " + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
결국 상속을 안받고 구현을 한거네. 즉 interface는 반드시 필요한 규격을 정해놓은 거네.
기억나나.. IBM 하드사서 꼽아쓰기와 DeLL의 주문서..