2011. 1. 6. 00:21
추상:낱낱의 구체적 표상이나 개념에서 공통된 성질을 뽑아 이를 일반적인 개념으로 파악하는 정신 작용
 
추상화 - 클래스간의 공통점을 찾아내서 공통의 조상을 만드는 작업 
구체화 - 상속을 통해 클래스를 구현, 확장하는 작업
추상클래스? 왜 구현할까? 자식클래스에 반드시 구현해야 하기 때문에 사용.
1) fA(){}
2) abstract void fB(); =>규격

 2)번 함수는 상속받아야 하는 자식에이 반드시 구현을 해야 하는 함수이기에, abstract로 선언을 하여 강제성을 주어 상속받은 클래스가 "반드시 구현"할 것을 요구.
ex) 탈것이라는 부모클래스에 abstract 키워드를 사용한 연비계산 추상메소드를 만들고
이를, 자동차 배, 기차등이 상속하여 연비계산을 반드시 구현하도록 함.


1. 추상클래스 ( abstract class 클래스이름{} )

  - 추상클래스에도 생성자가 있으며, 멤버변수와 메서드도 가질 수 있다.
  - 추상메서드가 있으면 반드시 abstract.(추상메소드를 단 하나라도 가지고 있는 클래스를 의미한다.)
  - 추상메서드가 없는 완성된 클래스라 할 지라도 추상클래스로 지정되면 클래스의 인스턴스를 생성할 수 없다.
  - abstract class A -> 객체생성 못 (규격으로 쓰겠다.)
public abstract class Flyer{
   abstract public void takeOff();
   public void getSpeed(){
      System.out.println(" ");
   }
}
클래스를 설계도에 비유한다면, 추상클래스는 비완성 설계도에 비유할 수 있다. 미완성 설계도란, 단어의 뜻 그대로 완성되지 못한  채로 남겨진 설계도를 말한다.
추상클래스 자체로는 클래스로서의 역할을 다 못하지만, 새로운 클래스를 작성하는데 있어서 바탕이 되는 조상 클래스로서 중요한 의미를 갖는다. 새로운 클래스를 작성할 때 아무 것도 없는 상태에서 시작하는 것보다 완전하지 못하더라도 어느 정도 틀을 갖춘 상태에서 시작하는 것이 나을 것이다.


2. 추상메서드
- 선언부만 작성하고 구현부는 작성하지 않은 채로 남겨 둔 것.
- 추상클래스로부터 상속받는 자손클래스는 오버라이딩을 통해 조상인 추상클래스의 추상메소드를 모두 구현해중어야 한다.
  만일 조상으로 부터 상속받은 추상메서드 중 한라도 구현하지 않는다면, 자손클래스 역시 추상클래스로 지정해 주어야 한다.

[예제] - [추상클래스의 사용예와, inner class]
public abstract class ParentNode {
//The type ParentNode must be an abstract class to define abstract methods
 int age;
 String name;
 
 public abstract void display();
 //The abstract method display in type ParentNode can only be defined by an abstract class
 public void hello(){
  System.out.println(name + "님 안녕하세요");
 }
}
public class NodeTest {

public static void main(String[] args) {
  // TODO Auto-generated method stub
  //ParentNode pn = new ParentNode();
  //Cannot instantiate the type ParentNode
  
  
  NodeTest nt = new NodeTest();
  NodeTest.ChildNode cn = nt.new ChildNode();

  //multiple markers at this line
 }
 
 class ChildNode extends ParentNode{
  //The type NodeTest.ChildNode must implement the inherited abstract method ParentNode.display()
  @Override
  public void display() {
      // TODO Auto-generated method stub
   
  }
 }
}
내부클래스는, 해당 클래스 안에서만 쓸 수 있다.
내부 클래스를 사용 하기 위해서는,
NodeTest node = new NodeTest();
NodeTest.ChildNode pn = nod.new ChildNode();
의 식으로 선언한다.
 1)
 Class NodeTest{
     ......
 }
 Class ChildNode{
    .....
 }
 2)
 Class NodeTest{
    .....
    Class ChildNode{
       ...
    }
 }
 클래스 NodeTest와 클래스 ChildNode는 별개의 클래스다.
 NodeTest.java 파일을 컴파일하면,
 NodeTest.class와
 ChildNode.class 두 클래스 파일이 생성된다.
 [내부클래스이다.]
ChildNode를 쓸려면 NodeTest를 만들어야 가능하다.
컴파일 하면, NodeTest.class와
                  NodeTest$ChildNode.class 파일이 생성된다.
그냥 ChildNode cn = new ChildNode()로 선언하면 에러
=>해결법 ? static으로 클래스를 선언하든지,
   내부 클래스를 1)의 형식으로 해주면 OK.

 
# 인터페이스는 왜 사용하는가?
예)
  * 핸드폰과 핸드폰 충전기가 있을 때,
 - 핸드폰 종류별로 충전기가 다 다를 경우 외부 출장 등을 갔을 때 핸드폰 충전을 하기가 불편합니다.
 - 핸드폰 종류별 동일한 충전기를 사용할 수 있도록 하기 위해서는 핸드폰 제조 업체와 충전기 제조 업체 쪽에 동일한 인터페이스를 사용할 수 있도록 하기 위한 규약서를 만들어서 제공해야 합니다.
 - 이 규약서는 핸드폰과 충전기 사이의 인터페이스가 됩니다.
이러한 규약서를 자바 프로그래밍으로 표현할 때 인터페이스가 된다.

<인터페이스> : 규격을 정하는 용도로 사용(규약서)
- 인터페이스는 형태적으로 추상 클래스가 더욱 추상화된 형태로, 모든 메소드가 추상 메소드인 클래스를 의미합니다.
- 인터페이스는 일종의 추상클래스이다.
- 인터페이스는 추상클래스처럼 추상메서드를 갖지만 추상클래스보다 추상화 정도가 높아서,
   추상클래스와 달리 몸통을 갖춘 일반 메서드 또는 멤버변수를 구성원으로 가질 수 없다.
- 오직 추상메서드와 상수만을 멤버로 가질 수 있으며, 그 외의 다른 어떠한 요소도 허용하지 않는다.
- 접근제어자로 public 또는 default를 사용한다.
- 인터페이스는 인터페이스로부터만 상속받을 수 있으며, 
  클래스와는 달리 다중상속, 즉 여러 개의 인터페이스로부터 상속을 받는 것이 가능하다.

interface 인터페이스이름{
     public static final 타입 상수이름 = 값;
     public abstract 메서드이름(매개변수 목록);
     //static final과 abstract 생략가능 
}
public interface Flyer{
     public void takeOff();
     public void land();
     public void fly();
}
public class Airplane implements Flyer{
     public void takeOff(){
     /*                      구현                      */
     }
     public void land()(){
     /*                      구현                      */
     }
     public void fly()(){
     /*                      구현                      */
     }
}

 

일반적인 클래스의 멤버들과 달리 인터페이스의 멤버들은 다음과 같은 제약사항을 가지고 있다.
- 모든 멤버변수는 public static final 이어야 하며, 이를 생략할 수 있다.
    -> 상수값만 가능. (멤버 변수x)
- 모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다.
    ->인터페이스에 추상 메소드 선언 시 abstract이라는 키워드를 사용하지 않습니다. 왜냐하면 인터페이스는 추상메소드만 가질 수 있기 때문입니다.
[참고] 인터페이스에 정의된 모든 멤버에 예외없이 적용되는 사항이기 때문에 제어자를 생략할 수 있는 것이며, 편의상 생략하는 경우가 많다. 생략된 제어자는 컴파일 시에 컴파일러가 자동으로 추가해준다.


*인터페이스 구현
class 클래스이름 implements 인터페이스이름 {
   //인터페이스에 정의된 추상메서드를 구현해야 한다.
}
만일 구현하는 인터페이스의 메서드 중 일부만 구현한다면, 추상클래스로 선언되어야 한다.


예제소스1)
public interface Flyer {
 public void takeOff();
 public void land();
 public void fly();
}
public class Airplane implements Flyer {
 @Override
 public void takeOff() {
  System.out.println("앞바퀴부터 떨어짐.");
 }
@Override
 public void land() {
  System.out.println("뒷바퀴부터 닿음");
 }
 @Override
 public void fly() {
  System.out.println("쌩하고 날라감");
 }
}
public class Bird implements Flyer {
 @Override
 public void takeOff() {
  System.out.println("열심히 뛰어서 날아오름");
 }
 @Override
 public void land() {
  System.out.println("바람을 타고 내려옴.");
 }
 @Override
 public void fly() {
  System.out.println("훨훨 날아다님");
 }
 public void eat(){
  System.out.println("부리로 쪼아서 먹음.");
 }
}
public class TestFlyer {
 public static void main(String[] args) {
  Flyer airplane = new Airplane();
  Flyer bird = new Bird();
        //Flyer flyer = new Flyer();//error
  //Cannot instantiate the type Flyer
  System.out.println("\n비행기========");
  airplane.takeOff();
  airplane.land();
  airplane.fly();
  
  
  System.out.println("\n\n새========");
  bird.takeOff();
  bird.land();
  bird.fly();
  //bird.eat(); //error. Flyer로 선언된 bird는 eat()메소드에 접근하지 못함
  if(bird instanceof Bird)
  {
   Bird b = (Bird)bird;
   b.eat();
  }
 }
}
[console]
비행기========
앞바퀴부터 떨어짐.
뒷바퀴부터 닿음
쌩하고 날라감


새========
열심히 뛰어서 날아오름
바람을 타고 내려옴.
훨훨 날아다님
부리로 쪼아서 먹음.
[인터페이스를 자료형으로 사용]
Flyer airplane = new Airplane();
Flyer bird = new Bird();

[형변환]
if ( bird instanceof Bird)
    Bird b = (Bird)bird;



[클래스 상속, 인터페이스 구현 클래스]
클래스는 상속(extends)과 구현(implement)을 동시에 할 수있다.
순서 중요!!!!! (extends가 먼저 쓰여지고 뒤에 implement를 써야 함.)
public interface Human {
}
public interface Flyer {
}
public class Bird implements Flyer {
}

public class SuperMan2 extends Bird implement Human {
}

public class 클래스명 extends 부모클래스명 implements 인터페이스명1, 인터페이스명2 { }


[비교] abstract클래스와 interface의 용도를 비교하여 설명.
 * abstract
    1) 일부기능은 제공, 일부기능 규격을 제공
    추상메서드를 한개이상 가지고 있는 클래스
    단일상속만 된다.

 * interface
    1) 규격을 제공
    모든메서드가 추상메서드인 클래스
    다중상속이 가능하다.



 인터페이스의 장점
- 개발시간을 단축시킬 수 있다.
- 표준화가 가능하다.
- 서로 관계없는 클래스들에게 관계를 맺어 줄 수 있다.
- 독립적인 프로그래밍이 가능하다.

'Java' 카테고리의 다른 글

표현언어(Expression Language)  (0) 2011.01.27
파일과 입출력 API  (0) 2011.01.11
java.util 패키지(유틸리티 API)  (0) 2011.01.11
static정리  (0) 2011.01.06
instanceof연산자  (0) 2011.01.05
Posted by Triany
2011. 1. 5. 22:49
참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위해 사용한다. 주로 조건문에 사용되며, instanceof의 왼족에는 참조변수를 오른쪽에는 타입(클래스명)이 피연산자로 위치한다. 그리고 연산의 결과로 boolean값인 true, false 중의 하나를 반환한다.
instanceof를 이용한 연산결과로 true를 얻었다는 것은 참조변수가 검사한 타입으로 형변환이 가능하다는 것을 뜻한다.
[참고] 값이 null인 참조변수에 대해 instanceof연산을 수행하면 false를 결과로 얻는다.

void dowork(Car c){
     if ( c instanceof FireEngine) {
          FireEngine fe = (FireEngine)c;
          fe.water();
     }
    else if( c instance of Ambulance) {
          Ambulance a = (Ambulance)c;
          a.siren();
    }

  . . . . . . .
}




참조변수와 인스턴스의 연결
-메서드 : 조상클래스의 메서드를 자손의 클래스에서 오버라이딩 한 경우에도 참조변수의 타입에 관계없이 항상 실제 인스턴스의 메서드(오버라이딩된 메서드가 호출됨)

멤버변수의 경우 참조변수의 타입에 따라 달라짐
-멤버변수가 조상 클래스와 자손 클래스에 중복으로 정의된 경우,
조상 타입의 참조변수를 사용했을 때 조상 클래스에 선언된 멤버변수가 사용되고,
자손타입의 참조변수를 사용했을 때는 자손 클래스에 선언된 멤버변수가 사용된다.

예1)
class Parent{
     int x = 100;
  
     void method() {
          System.out.println("Parent Method");
     }
}

class Child extends Parent {
     int x = 200;

     void method() {
          System.out.println("Child Method");
     }
 
}


Class BindingTest{
     public static void main(String[] args) {
          Parent p = new Child();
          Child c = new Chile();
          System.out.println("p.x = " + p.x);
          p.method();
          System.out.println("c.x = " + c.x);
          c.method();
     }
}      
[결과값]
p.x = 100;
Chiild Method
c.x = 200;
Child Method




예2)
public class Parent {
    public int su = 10;
    void pr(){
          System.out.println(su);
    }
}
public class Child extends Parent {
    public int su = 20;
    void pr(){
         System.out.println(su);
    }
}
public class TestParentChild { 
   public static void main(String[] args) {
  
       System.out.println("*Parent p1 = new Parent() *");
       Parent p1 = new Parent();
       System.out.print("Parent의 pr(): su = "); p1.pr();
       System.out.println("p1.su = " + p1.su);
  
       System.out.println("\n *Child c1 = new Child() *");
       Child c1 = new Child();
       System.out.print("Child의 pr() : su = "); c1.pr();
       System.out.println("c1.su= "+c1.su);
  
       System.out.println("\n *Parent p2 = new Child() *");
       Parent p2 = new Child();
       System.out.print("Child의 pr(): su = "); p2.pr();
       System.out.println("p2.su = " +p2.su);
   }
}
[Console]
*Parent p1 = new Parent() *
Parent의 pr(): su = 10
p1.su = 10

 *Child c1 = new Child() *
Child의 pr() : su = 20
c1.su= 20

 *Parent p2 = new Child() *
Child의 pr(): su = 20
p2.su = 10
마지막 선언 Parent p2 = new Child() 를 보면,
p2.su의 값을 출력해 보면 Parent클래스의 멤버변수 su값이 출력된다.
(조상타입의 참조변수를 이용하여 Child()클래스를 접근했으므로 참조 변수는 Parent의 su이다.)
하지만 참조메소드는 현재 인스턴스가 접근하는 클래스(Child())의 멤버 메소드 이므로,
void pr(){
         System.out.println(su);
    }
함수의 su가 this.su를 생략하고 있다고 보면, Child의 멤버변수 su의 값이 출력된다.



예3)
public interface Drawable {
    public int PLAIN_PEN = 1;
    public int BOLD_PEN = 2;
    public int ITALIC_PEN = 3;
    public void draw();
    public void move(int x, int y);
}
public class Shape1 {
    protected int x = 0;
    protected int y = 0;
    public Shape1() {
          this(0,0);
    }
    public Shape1(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
public class Circle1 extends Shape1 implements Drawable {
     protected int radius;
     public Circle1(int x, int y, int radius) {
          super(x, y);
          this.radius = radius;
     }
  
    @Override
    public void draw() {
          System.out.println("x = " + x + ",  y = " + y + "  radius = "+radius);
    }

    @Override
     public void move(int x, int y) {
          System.out.println("x = " + (this.x + x) + ",  y = " + (this.y+y) + "   radius = "+ radius);
     }
}
public class Rectangle1 extends Shape1 implements Drawable {
    protected int width;
    protected int height;
 
    public Rectangle1(int x, int y, int width, int height) {
         super(x, y);
         this.width = width;
         this.height = height;
    }

    @Override
    public void draw() {
         System.out.println("x = " + x + ",  y = " + y + "  width = "+ width + ",  height = " + height);
    }

    @Override
    public void move(int x, int y) {
          System.out.println("x = " + (this.x + x) + ",  y = " + (this.y+y) + "  width = "+ width + ",  height = " + height);
    }
}
public class InterfaceTest {
    public static void main(String args[]){
  Circle1 c = new Circle1(10,10,100);
  Rectangle1 r = new Rectangle1(20,20,50,50);
  c.draw();
  c.move(5, 5);
  r.draw();
  r.move(5, 10);
  
    }
}
[Console] InterfaceTest.java
x = 10,  y = 10  radius = 100
x = 15,  y = 15   radius = 100
x = 20,  y = 20  width = 50,  height = 50
x = 25,  y = 30  width = 50,  height = 50
public class InterfaceTestEx {
    public static void main(String args[])
   {
  Circle1 c = new Circle1(10,10,100);
  Shape1 s = new Circle1(20,20,200);
  Drawable d = new Circle1(30, 30, 300);
  c.draw();
  //s.draw();  //The method draw()is undefined for the type Shape1
  d.draw();
  System.out.println("x = " + c.x + ",  y = " + c.y);
  System.out.println("x = " + s.x + ",  y = " + s.y);
  // System.out.println("x = " + d.x + ",  y = " + d.y);
//  Multiple makers at this line
// -x cannot be resolved or is not a fild
// -y cannot be resolved or is not a file
    }
}
[Console] InterfaceTestEx.java
x = 10,  y = 10  radius = 100
x = 30,  y = 30  radius = 300
x = 10,  y = 10
x = 20,  y = 20
InterfaceTestEx.java 부분을 살펴보자
s.draw();는 error가 뜬다. 이유는, 참조변수 Shape1으로 선언한 s 객체는 Shape1이 draw() 함수를 갖고 있지 않기 때문에
 //The method draw()is undefined for the type Shape1 이라는 메시지가 뜨며 에러라고 표시된다.
마찬가지로 System.out.println("x = " + d.x + ",  y = " + d.y);도 error 메시지가 뜨게 되는데, Drawable 클래스는 x, y라는 멤버변수를 갖고 있지 않기때문에,  "Multiple makers at this line   -x cannot be resolved or is not a fild   -y cannot be resolved or is not a file" 라는 메시지가 뜨면서 에러가 뜬다.





'Java' 카테고리의 다른 글

표현언어(Expression Language)  (0) 2011.01.27
파일과 입출력 API  (0) 2011.01.11
java.util 패키지(유틸리티 API)  (0) 2011.01.11
static정리  (0) 2011.01.06
추상클래스 / 인터페이스  (0) 2011.01.06
Posted by Triany
2011. 1. 5. 14:37
미셸 푸코 [Michel Paul Foucault, 1926.10.15~1984.6.25]
요약
프랑스의 철학자. 정신의학에 흥미를 가지고 연구했으며 서양문명의 핵심인 합리적 이성에 대한 독단적 논리성을 비판하고 소외된 비이성적 사고, 즉 광기(狂氣)의 진정한 의미와 역사적관계를 파해쳤다.
국적 프랑스
활동분야 철학
출생지 프랑스 중서부 프와티에(Poitiers)
주요저서 《광기와 비이성(非理性)》(1961) 《앎[知]의 고고학》(1969)
본문
1926년 10월 15일 프랑스 중서부 프와티에(Poitiers)에서 출생하였다. 그의 아버지는 외과의사였다. 포스트구조주의의 대표자로 파리대학교 벵센 분교 철학교수를 거쳐 1970년 이래 콜레주 드 프랑스 교수를 지냈다. 대학에서 철학을 전공한 후 정신의학에 흥미를 가지고 그 이론과 임상()을 연구하였다. 인간의 지식은 어떤 과정을 거쳐 형성되고 변화하는지 탐구하였고 해답을 모색하였다. 그 과정에서 각 시대의 앎[]의 기저에는 무의식적 문화의 체계가 있다는 사상에 도달하였다. 또한 업압적인 권력의 구조를 예리한 통찰력으로 파헤쳤으며 정신병의 원인을 사회적 관계속에서 밝혀내려 하였다. 1961년 정신의학의 역사를 연구한 《광기()와 비이성()―고전시대에서의 광기의 역사》에서 서양문명의 핵심인 합리적 이성에 대한 독단적 논리성을 비판하고 소외된 비이성적 사고, 즉 광기()의 진정한 의미와 역사적관계를 파헤쳤다. 이 저술로 푸코는 세계에서 주목받는 철학자로 떠올랐다.

정신병과 사회적 관계를 밝힌《임상의학의 탄생》(1963) 을 저술하였으며 1966년에는 역사를 통해 지식의 발달과정을 분석한 《언어와 사물》을 저술하였다. 서구 지식의 역사는 두 번의 단절된 과정이 있었다고 주장하였고 지식을 연속성을 가진 발달과정으로 보는 기존의 입장을 착각으로 규정하였다. 1969년 《지식의 고고학()》에서는 전통적인 사상사를 비판하였다. 1970년대에 푸코는 부르주아 권력과 형벌제도에 대한 분석의 결과물인 《처벌과 감시》(1975)를 저술하였다. 이 저술에서 푸코는 역사적으로 지배계급이 체제를 유지하기 위해 이용한 법률과 억압적 통치구조를 파헤쳤다. 인간의 알고자 하는 의지와 이를 억압하는 권력과의 관계를 주요 주제로 삼았다. 푸코는 지식은 권력과의 관계를 맺고 있으며 모든 지식은 정치적이라고 주장하였다. 1984년 6월 25일 후천성면역결핍증(AIDS)으로 사망하였다.

Posted by Triany