W.A 저장소

서울대학교 교육 2일차. 본문

Programing

서울대학교 교육 2일차.

W.A 2010. 8. 10. 14:23
자. 오늘은 2일차 오늘은 어제 나쁜남자를 봐서 그런지 아무래도 좀 늦게 일어났다. 대략 한 6시 30분쯤? 부랴부랴 샤워를 마치고 집에서 출발하니 7시 정되가 되었다. 집 밖을 나서는 순간. 이게 왠일이람. 제길. 왠. 비가 내려 ㅠ.ㅠ 다시 집으로 들어가서 우산을 가지고 어제와 같은 루트로 하여 서울대에 도착. 2일차 교육을 시작하고 오전 시간을 끝 마친 다음에 아래와 같이 오늘 배운 내용 정리를 하겠다.

1. 상속(Inheritance)
모 대부분의 사람들이 상속이라고 하면은 유산? 모 이런거 생각 하실것이다. 여기 자바에서도 마찬가지가 B가 A를 상속 받으면 B라는 넘은 A의 모든것을 가지는 것이다.(여기서 private은 제외) 그래서 이 상속관계에서는 IS-A관계가 생성이 된다.

A <- B   = B is a A

그렇기 때문에 코드 상에서 보았을 때 아래와 같이 쓸 수가 있다.

A a = new B();

간단하게 예를 들어보겠다. 밑의 소스를 보자.

class A {
int f; // 인스턴스 변수
void m() { } // 인스턴스 메서드
static int sf;  // 클래스 변수
static void sm() { } // 클래스 메서드
}

class B extends A {
int f2;
void m2() { }

public static void main(string[] args) {
B b = new B();
b.f2++; // B의 필드 1.
b.m2(); // B의 메서드 2.
b.f++; // A로부터 상속된 B의 필드 3.
b.m(); // A로부터 상속된 B의 인스턴스 메서드 4.
B.sf++; // A로부터 상속된 클래스 필드 5.
B.sm(); // A로부터 상속된 클래스 메서드 6.

A a;
a = b;
m3(b);
a.f2++; // 오류 7.
a.m2(); // 오류 8.
}

public static void m3(A a) {
a.f++;
a.f2++; // 오류 9.
}
}


위와 같이 되는 이유를 한번 보자. 간단하게 7,8,9번이 오류가 나는 이유는 B가 A를 상속을 받았지만 중간 부분에서
A a; a = b;
구문으로 인하여 앞으로 a는 b라는 인스턴스를 가르키고 있지만 따르는 설계자체는 A클래스를 따르기 때문에 7,8,9번과 같이 B클래스에서 구현한 메서드나 변수들을 사용할 수 없다.

또 다른 소스를 보며 살펴보자.
DrawObj[] objs = new DrawObj[10];

objs[0] = new Circle();
objs[1] = new Line();
objs[2] = new PolyLine();
objs[3] = new Rectangle();
. . . 
objs[9] = new Line();

for(int i = 0; i < objs.length; i++)
         objs[i].draw();

외와 같이 하는 소스는 밑의 for문에서 각 각의 모양들이 그려질 것이다.(Circle(), Line(), PolyLine(), Rectangle() 각각의 클래스들은 Objs클래스를 상속받아 draw메서드를 오버라이딩 한 것이다.)

위의 진하게 한 부분처럼 IS-A관계가 성립되기 때문에 위 소스 밑부분에서 보이는 for문처럼 사용이 가능하다.

2. 인터페이스(interface)
인터페이스의 사용 이유는 하나의 클래스는 단 하나의 클래스만을 상속받을수 있기 때문에 이런 문제를 해결해기 위해서 사용된다. 예를들어 현실에서 수륙양용차를 만든다고 했을때 현실에서는 차와 배를 합쳐 만들수 있다. 하지만 자바에서는 이런것을 구현하기 위해서는 차와 배 둘중하나만은 상속받아서 만들어야 한다. 이러한 문제를 해결하기 위해서 인터페이스라는것이 생긴것이다. 
인터페이스를 살펴보면 인터페이스는 인터페이스와 구현부분이 분리되어있다. 구현부분이 없기 때문에 객체를 인스턴스화 시킬수가 없고 그 안은 추상메서드로만 이루어져 있다. 그리고 한가지의 인터페이스로 여러 구현을 실행할수가 있다.
간단하게 밑의 소스를 보며 살펴보자.

interface Colorable {
        int WHITE = 0, RED = 1, BLUE = 2, GREEN = 3, BLACK = 4; // 상수

// 추상 메서드 (public abstract)
void setColor(int color);
  int getColor();
}

class Colored implements Colorable {
private int color;

@Override
public int getColor() {
// TODO Auto-generated method stub
return color;
}

@Override
public void setColor(int color) {
// TODO Auto-generated method stub
this.color = color;
}
}
abstract class Colored2 implements Colorable {
private int color;

@Override
public void setColor(int color) {
// TODO Auto-generated method stub
this.color = color;
}
}
public class InterfaceTest {
public static void main(String[] args) {
Colorable c = new Colored();
c.setColor(Colorable.GREEN);
System.out.println(c.getColor());
}
}

위 소스부분에서 interface안의 진한부분은 따로 추상화 선언을 하지 않아도 컴파일러에서 자동으로 public abstract를 추가하여 추상화처럼 인식을 하고 변수 선언처럼 보이는 것은 final을 추가하여 상수처럼 취급한다. 그리고 이 또 한 마찬가지로 중간부분의 빨간색으로 되어 있는 부분처럼 인터페이스를 구현하여 class를 만들게 되면 소스 밑부분의 진한곳처럼 사용이 가능하게 된다.

(추후 예시) : 쓰던거 날아가 버려서 ㅠ.ㅠ