'상속'은 클래스를 확장하기 위해 편리한 방법이지만 클래스간의 연결을 강하게 고정시킨다. 소스코드 상에서

  1. class SomethingGood extends Something {
       ...
    }

라고 쓰면 SomethingGood 클래스는 Something 클래스의 하위 클래스가 됩니다. 그리고 이 관계는 소스 코드를 고쳐 쓰지 않는 한 바꿀 수 없는 매우 견고한 연결이 된다. 프로그램의 필요에 따라서 클래스 간의 관계를 척척 바꾸고 싶을 때에 상속을 사용하는 것은 부적절하다. 교체할 때마다 소스 코드를 변경할 수 없기 때문이다. 이와 같은 경우에는 '상속'이 아니라 '위임'을 사용한다.

 

예제 프로그램 Display.java

  1. public class Display {
        private DisplayImpl impl;
        public Display(DisplayImpl impl) {
            this.impl = impl;
        }

        public void open() {
            impl.rawOpen();
        }

        public void print() {
            impl.rawPrint();
        }

        public void close() {
            impl.rawClose();
        }

        public final void display(){
            open();
            print();
            close();
        }

    }

예제 프로그램(추상 클래스) DisplayImpl.java

  1. public abstract class DisplayImpl {
        public abstract void rawOpen();
        public abstract void rawPrint();
        public abstract void rawClose();
    }

 

예제 프로그램에서는 Display 클래스 내에서 위임이 사용되고 있다. Display 클래스의 impl 필드에는 구현되는 인스턴스가 저정되어 있어서

... open을 실행할 때에는 impl.rawOpen()을 호출한다.

... print를 실행할 때에는 impl.rawPrint()을 호출한다.

... close를 실행할 때에는 impl.rawClose()를 호출한다.

 라는 식으로 '떠넘기기:위임'을 하고 있다. 이것이 위임이다. 상속은 견고한 연결이고 위임은 느슨한 연결이다. DIsplay 클래스의 인스턴스를 만드는 단계에서 인수로 전달되어온 것과 연결되기 때문이다. 상속과 위임의 관계에 대해서는 Template Method 패턴에서 등장하므로 참고하기 바란다.

이 글은 스프링노트에서 작성되었습니다.

Java에서는 다음과 같이 인스턴스(객체)를 만드는 방법이 있다.

 

   new
 


일반적으로 인스턴스는 Java의 예약어 new를 사용해서 만든다. 다음과 같이 하면 Something 클래스의 인스턴스를 만들고 변수 obj에 대입할 수 있다.

--> obj라는 이름을 가지는 Something 클래스 타입의 객체를 가진다 라고 말할 수 있겠다.

Something obj = new Something();

 이 경우 클래스 이름(여기에서는 Something)을 소스 안에 기술할 필요가 있다.

 

   clone()
 

Prototype 패턴에서 등장했던 clone 메소드를 사용하면 이미 존재하는 인스턴스를 기초로 새로운 인스턴스를 만들 수 있다. 다음과 같이 하면 자신(this)을 기초로 새로운 인스턴스(객체)를 만들 수 있다(단, 생성자는 호출되지 않는다).

java.lang
클래스 Class<T>

java.lang.Object 
java.lang.Class<T>

java.lang
클래스 Object

java.lang.Object

clone

protected Object  clone()


throws
CloneNotSupportedException

이 객체의 카피를 작성해, 돌려줍니다. 「카피」의 정확한 이유는, 객체의 클래스에 의해 다릅니다. 일반적으로는, 임의의 객체 x 에 대해, 다음의 식
 x.clone() ! = x
하지만 true 이며, 다음의 식
 x.clone(). getClass() == x.getClass()
도 true 인 것입니다만, 이것들도 절대적인 요건이 아닙니다. 또 다음의 식
 x.clone(). equals(x)
도 일반적으로 true 가 됩니다만, 이것도 절대적인 요건이 아닙니다.

일반적으로,super.clone 를 호출하는 것으로 반환되는 객체를 취득할 수 있습니다. 클래스 및 그 슈퍼 클래스 모든 것 (Object 를 제외한다)이 이 규칙에 따르는 경우,x.clone(). getClass() == x.getClass() 가 성립합니다.

일반적으로, 이 메소드에 의해 반환되는 객체는, 이 객체 (복제되고 있다)로부터 독립하고 있을 필요가 있습니다. 이 독립성을 달성하기 위해(때문에),super.clone 가 돌려주는 객체의 필드를 1 개 이상 (객체가 돌려주기 전에) 변경하는 것이 필요하게 되는 경우가 있습니다. 이것은, 일반적으로, 복제하는 객체의 내부 「심층 구조」를 구성하는 가변 객체의 카피, 및 이러한 객체에의 참조를 카피에의 참조에 옮겨놓는 것을 의미합니다. 클래스에 프리미티브(primitive) 필드 또는 불변 객체에의 참조만이 포함되는 경우, 일반적으로,super.clone 에 의해 반환되는 객체내의 필드를 변경할 필요는 없습니다.

Object 클래스의 clone 메소드는, 특정의 복제 처리를 실행합니다. 우선, 이 객체의 클래스가 Cloneable 인터페이스를 구현하고 있지 않는 경우는,CloneNotSupportedException 가 throw 됩니다. 배열은 모두, 인터페이스 Cloneable 를 구현하고 있는 것이라고 보여지는 것에 주의해 주세요. 구현하고 있지 않는 경우, 이 메소드는 이 객체의 클래스의 새로운 인스턴스를 생성해, 그 필드를 모두, 이 객체의 대응하는 각 필드의 내용으로 초기화합니다. 이것은 대입과 같아, 필드의 내용 자신이 복제되는 것은 아닙니다. 즉 이 메소드는, 객체의 「shallow 복사」를 생성합니다만, 「딥 카피」는 생성하지 않습니다.

Object 클래스 자체는,Cloneable 인터페이스를 구현하지 않기 때문에, 클래스가 Object 인 clone 메소드를 호출하면(자), 실행시에 예외가 throw 됩니다.

반환값:
이 인스턴스의 복제
예외:
CloneNotSupportedException - 객체의 클래스가 Cloneable 인터페이스를 지원하고 있지 않는 경우. clone 메소드를 오버라이드(override) 한 서브 클래스도, 인스턴스를 복제할 수 없는 것을 나타내기 위해서(때문에) 이 예외를 throw 하는 일이 있는
관련 항목:
Cloneable

JDK 1.6 API 상에 설명되는 clone() 메소드의 개요

 

  1. class Something {
        ...
        public Something createClone() {
            Something obj = null;
            try {
                obj = (Something)clone();
            } catch ( CloneNotSupportedException e ) {
                e.printStackTrace();
            }
            return obj;
        } 
    }

 

   newInstance()
 

java.lang.Class 클래스의 newInstance 메소드를 사용하면 Class의 인스턴스(객체)를 기초로 그 Class가 표시하고 있는 클래스의 인스턴스(객체)를 만들 수 있다(인수 없는 생성자가 호출된다).

newInstance

public T  newInstance()


throws
InstantiationException ,


IllegalAccessException
이 Class 객체가 나타내는 클래스의 새로운 인스턴스를 생성합니다. new 식에 빈 상태(empty)의 인수 리스트를 지정했을 경우와 같이, 클래스의 인스턴스가 생성됩니다. 클래스는, 초기화되어 있지 않으면 초기화됩니다.

이 메소드는 확인이 끝난 예외 등, 인수 없음의 생성자 에 의해 throw 된 예외를 보내는 것에 주의해 주세요. 이 메소드를 사용하는 것으로, 그 외의 경우에는 컴파일러에 의해 실행되는 컴파일시의 예외 확인을 효과적으로 우회도로 할 수 있습니다. Constructor.newInstance 메소드는, (확인 끝난) InvocationTargetException 의 생성자 에 의해 throw 된 예외를 랩 하는 것으로, 이 문제를 회피합니다.


반환값:
이 객체가 나타내는, 클래스의 새롭게 할당할 수 있었던 인스턴스
예외:
IllegalAccessException - 클래스 또는 그 인수 없음의 생성자 에 액세스 할 수 없는 경우
InstantiationException - 이 Class 가 abstract 클래스, 인터페이스, 배열 클래스, 원시형, 또는 void 를 나타내는 경우, 클래스가 인수 없음의 생성자 을 보관 유지하지 않는 경우, 혹은 인스턴스의 생성이 다른 이유로써 실패했을 경우
ExceptionInInitializerError - 이 메소드에 의한 초기화가 실패했을 경우
SecurityException - 시큐리티 매니저 s 가 존재해, 이하의 조건의 어떤 것인가가 채워지는 경우
  • s.checkMemberAccess(this, Member.PUBLIC) 의 호출이 이 클래스의 신규 인스턴스의 작성을 허가하지 않는다
  • 호출측의 클래스 로더가 같지 않은지, 현재의 클래스 로더의 상위 클래스 로더와 s.checkPackageAccess() 의 호출이 이 클래스의 패키지에의 액세스를 허가하지 않는다

다음은 newInstance의 예입니다. Something 클래스의 인스턴스 someobj가 있다면 다음 식에서 Something 클래스의 인스턴스를 새롭게 만들 수 있다.

  1. someobj.getClass().newInstance();

 

실제로 newInstance 메소드는 InstantiationException이나 IllegalAccessException을 예외로 제공하기 때문에 try{ } catch() {}로 묶든지 메소드에 throws을 선언해야 한다.

 

이 글은 스프링노트에서 작성되었습니다.

현재 CJ기술교육센터에서 JAVA EXPERT 과정에서 2개월의 교육과정으로 들어서고 있습니다.
첫 2주에는 HTML/CSS/JAVASCRIPT에 대해서 배우고, 또 3주간 Java Fundmental을 하고, 또 3주간 Oracle 과정을 공부하였습니다. 지금은 JBCD->JSP로 넘어갈 준비를 하고 있습니다.

이 과정에서 허니몬이 절실히 느낀 것은 자신이 공부한 것들, 혹은 경험한 것들에 대해서 기록을 남기는 것 입니다. 공부하거나 경험하는 그 순간에야, '필요하면 다 기억나겠지~' 하는 생각으로 지나치지만, 막상 시간이 지나고 나면 기억이 나지 않습니다.

지금 교육 과정을 진행하면서 꾸준하게 나만의 위키로 스프링노트(http://sunfuture.springnote.com)를 작성하고 있습니다. 이제 서서히 습관이 들어가고 있는 듯 합니다. 스프링노트의 장점이라면, 작성해둔 문서들을, 검색을 통해서 쉽게 찾을 수 있다는 겁니다. 배웠던 것들에 대해서 문득 떠오르는 단어나 키워드만으로도 다시 찾아볼 수 있는 것이죠.


더불어서 그림에서 볼 수 있는 것처럼, 제가 작성했거나 수정한 페이지들도 보여지는 기능을 보여줍니다.

결론을 말씀 드리자면, 자신이 편하게 사용할 수 있는 도구를 이용하여 자신이 공부한 내용을 기록하는 습관을 가지자 라는 것입니다. 사람의 기억력은 우리의 상상 이상으로 그리 오래 가지 못합니다. 기억력을 오래 유지하는 방법은 꾸준하게 자주 배운 것들을 열어보는 습관을 가지는 것입니다. ^^

출처 :  http://www.okjsp.pe.kr/seq/307

끔찍한 java 에러입니다.
jdbc연결시 에러입니다.


classes12.zip 이 연결이 안된 경우입니다.

java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:297)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:286)
at java.lang.ClassLoader.loadClass(ClassLoader.java:253)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:313)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:120)
at getEmp.main(getEmp.java:18)

해결1: classes12.zip을 classes12.jar 로 이름을 바꾼 뒤에 <CATALINA_HOME>/common/lib 에 놓고 재시동


host 주소가 맞지 않은 경우입니다.
또는 listener가 떠있지 않은 상태입니다.

java.sql.SQLException: IO 예외 상황: The Network Adapter could not establish the connection
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:114)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:156)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:269)
at oracle.jdbc.driver.OracleConnection.(OracleConnection.java:210)
at oracle.jdbc.driver.OracleDriver.getConnectionInstance(OracleDriver.java:251)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:224)
at java.sql.DriverManager.getConnection(DriverManager.java:517)
at java.sql.DriverManager.getConnection(DriverManager.java:177)
at getEmp.main(getEmp.java:20)


db명이 틀릴경우입니다. 호스트스트링이라고도 합니다.
java.sql.SQLException:IO 예외 상황: Connectionrefused(DESCRIPTION=(TMP=)(VSNNUM=135290880)(ERR=12505)(ERROR_STACK=(ERROR=(CODE=12505)(EMFI=4))))
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:114)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:156)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:269)
at oracle.jdbc.driver.OracleConnection.(OracleConnection.java:210)
at oracle.jdbc.driver.OracleDriver.getConnectionInstance(OracleDriver.java:251)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:224)
at java.sql.DriverManager.getConnection(DriverManager.java:517)
at java.sql.DriverManager.getConnection(DriverManager.java:177)
at getEmp.main(getEmp.java:20)


아이디와 패스워드가 틀릴경우입니다.
java.sql.SQLException: 널 사용자나 암호가 THIN 드라이버에서 지원되지 않습니다
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:114)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:156)
at oracle.jdbc.dbaccess.DBError.check_error(DBError.java:803)
at oracle.jdbc.ttc7.TTC7Protocol.logon(TTC7Protocol.java:179)
at oracle.jdbc.driver.OracleConnection.(OracleConnection.java:198)
at oracle.jdbc.driver.OracleDriver.getConnectionInstance(OracleDriver.java:251)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:224)
at java.sql.DriverManager.getConnection(DriverManager.java:517)
at java.sql.DriverManager.getConnection(DriverManager.java:177)
at getEmp.main(getEmp.java:20)
   제가 만들고 싶은 것은 API를 이용한 매쉬업 형태로 개발을 해야할 것 같습니다. 그러기 위해서는 자바스크립트를 기반으로 하는 것이 좋을 듯 하구요. 과거에 단순히 복사하고 붙여넣기 방식으로 구현하면 된다고 생각했던 자바 스크립트였는데, 지금은 공부해야할 것이 자바 만큼이나 많은 분야가 되어버리는 군요. ㅡㅅ-); 그나저나... 스-);; 문제로군요. 우분투에서는 플래시로 작성되어 있는 영상들이 정상적으로 작동을 하지 않습니다. OTL... VirtualBox로 윈도우 XP를 사용하면서 시스템 자원이 모두 그쪽에서 점유하고 있어서 였을까요? 우분투 업데이트를 마치고 나니까 정상적으로 플래시에서 소리가 나는군요. 으흠!?

강연하시는 분(Douglas Crockford)의 블로그 : http://www.crockford.com/


Douglas Crockford: "Advanced JavaScript" (1 of 3) @ Yahoo! Video


Douglas Crockford: "Advanced JavaScript" (2 of 3) @ Yahoo! Video


Douglas Crockford: "Advanced JavaScript" (3 of 3) @ Yahoo! Video

이 글은, 제가 이해해서 올린다기 보다는 이해하기 위해, 올해 안에 공부해야할 것들 중 하나인 JavaScript 부분에 대한 내용을 기록해두는 것이라고 해도 될 것 같습니다. ㅠㅅ-) 공부해야할 것들은 점점 많아져 가고 머리에 주입할 수 있는 주입량은 한계가 있고... 이것 참 난감하네요. 매쉬업이 발달하면 하게 될수록 매쉬업 언어로서의 자바스크립트도 그 영역을 더욱 넓혀가게 될 것 같군요.

+ Recent posts