공지
자바 기본개념
객체지향?
객체지향 프로그래밍의 개념은 1960년대 중반에 유행한 시뮬레이션 언어인 SIMURA에서 유래한 것이다.
모든 사물을 객체(Object)로 취급하며, 이 객체라는 것을 프로그래밍 코드로 구현한 것이 "클래스(class)"이다. 클래스에는 상위 클래스와 하위 클래스의 개념이 있어서, 하위 클래스를 생성할 때 상위 클래스로부터 상속받아 생성하게 된다. 클래스의 사용은 메모리를 할당받아 실제 사용되는 인스턴스(instance)를 통해서이다.
객체지향의 가장 중요한 개념은 코드의 재사용과 정보의 은닉이다. 코드의 재사용은 클래스를 컴포넌트화하여 필요한 곳 어디서나 사용하는 것으로 상속을 통해 구현되고, 정보의 은닉은 캡슐화를 통해 구현된다.
객체지향의 특징 중 하나는 객체 간에는 메시지의 전달 방식으로써 상호 통신을 한다는 것이며, 가장 특징적인 것은 각 클래스에 그 메시지를 처리하기 위한 방식이 있다는 것이다.
JAVA
자바는 1991년 썬사의 제임스 고슬링이 이끄는 팀에 의해 지능적 전자소비장치 컨트롤을 목적으로 개발된 그린 프로젝트의 결과물인 C와 C++에 기반을 둔 'Oak'라는 언어로부터 시작되었다. 개발한 연구소 근처에 떡갈나무가 많아서 이렇게 이름을 붙였지만 공교롭게도 Oak라는 이름의 언어가 이미 존재했었다. 이 난감한 사태를 수습하기 위해 썬사의 개발자들이 커피숍에 모여 이름을 무엇으로 할지 고민하다가 마시던 커피의 이름을 따서 자바라고 부르기로 했다.
자바는 기존의 프로그래밍 언어인 C/C++ 계열과 비슷한 문법을 보이면서도 내부적으로 실행될 때는 확연한 차이점을 가지고 있다. C는 기계어로 번역되고 메모리에 적재되어 CPU에서 직접 처리된다. 반면 자바는 바이트 코드라는 특수한 코드로 번역이되어 가상의 CPU은 JVM이 그 실행을 맡고 CPU에 처리를 맡긴다. 따라서 자바는 JVM이라는 가상의 CPU를 가지고 있기 때문에 플랫폼에 독립적이다.
캡슐화와 정보은닉
클래스는 내부에 데이터 자료와 그것을 처리하기 위한 메소드를 가지고 있다. 이런 데이터 자료와 메소드를 클래스에 포함시킨 것을 캡슐화라고 하는데 캡슐이란 것은 겉모양은 볼 수 있으나 안에 있는 내용은 볼 수 없다.
다른 클래스에서 어떤 클래스 객체를 생성해서 접근할 수 있지만 클래스 내의 데이터를 가지고 있는 멤버 변소에는 직접 접근할 수 없다. 메소드를 통해 우회해서 멤버 변수에 접근하도록 하는 것이 캡슐화를 하는 방법이고, 캡슐화가 정보의 은닉을 제공한다.
다형성
여러 개의 서로 다른 형식과 모양을 가진다는 의미로, 다형성을 이용하면 객체의 유형에 따라 서로 다른 작업을 수행하도록 할 수 있다. 객체는 한 가지 타입에 하나의 형태만을 생성하는 고정적인 형태보다, 한 가지 타입으로 여러 형태를 생성할 수 있는 유동적인 형태가 프로그램을 더욱 편하게 작성하게 해준다.
상속
객체지향 프로그램에서 가장 중요한 부분으로서 새로운 클래스를 생성할 때 처음부터 새로 작성하는 것이 아니라, 기존에 정의된 클래스로부터 중복되는 부분을 물려받아서 사용하면 된다. 프로그램을 전체를 새로 개발하는 것이 아니므로 프로그램 개발 기간의 단축과 비용 감소를 가져올 수 있고, 이미 실제 시스템에서 안정적으로 돌아가는 코드 부분을 사용하기 때문에 시스템이 더 안정적이다. extends라는 키워드를 써서 표현한다.
상속을 받는 클래스를 서브 클래스, 자식 클래스, 파생 클래스(derived class)라 한다.
상속해 주는 클래스를 슈퍼 클래스, 베이스 클래스, 부모 클래스라 한다.
오버로딩과 오버라이딩
오버로딩 |
오버라이딩 |
같은 이름으로 여러 개의 메소드를 선언하는 것이다. 오버라이딩과 더불어서 자바에서 다형성을 구현하는 중요한 부분 중의 하나이다. 한 클래스 내에서 메소드의 이름은 같고, 메소드의 매개 변수의 개수, 매개 변수의 타입이 다를 경우 가능하다. 같은 작업을 수행하지만, 여러 데이터 타입을 처리해야 하는 경우에 유용하게 사용될 수 있다. |
상속 관계에서 발생하는데, 슈퍼 클래스에서 상속 받은 메소드를 그대로 사용하는 것이 아니라 서브 클래스에 맞도록 고쳐서 사용하는 것이다. 슈퍼 클래스와 서브 클래스에 같은 이름을 가진 메소드가 존재할 때, 슈퍼 클래스의 메소드를 무시하고(override) 서브 클래서의 메소드를 사용하는 것으로, 메소드를 재정의하는 것이다. |
다중상속
클래스를 상속받아서 새로운 클래스를 생성해야 할 경우, 여러 개의 클래스로부터 상속받아 생성해야 할 때가 있다. 이렇게 여러 개의 클래스로부터 상속받는 것을 다중 상속이라 하는데, 자바는 다중 상속을 지원하지 않는다. 보완하기 위해서 직접적인 다중 상속은 되지 않으나 간접적으로 인터페이스를 사용한 다중 항속을 사용한다. 인터페이스는 implements를 사용해서 일종의 상속을 구현한다.
abstract와 interface
abstract |
interface |
클래스가 갖고 있는 메소드가 바디를 가지고 있지 않고 메소드의 인터페이스 부분만 갖고 있는 메소드가 하나라도 있으면 이 클래스를 추상 클래스라 부른다. 바디 없이 메소드의 선언부만 갖고 있는 메소드를 추상 메소드라 한다. 추상 클래스와 추상 메소드는 선언시에 abstract 키워드를 기술한다. abstract 함수 에서는 로직 구현이 불가능 하지만 일반메소드도 로직을 구현할 수 있다. |
스펙(spec)만을 기술해 놓은 것으로서 인터페이스를 사용하려면 클래스에 인터페이스를 구현하여야 한다. 클래스가 인터페이스를 구현하도록 선언하고, 인터페이스 내에 선언된 각 메소드의 코드를 클래스 정의의 일부로 작성해 넣어야 한다. 인터페이스가 가지고 있는 메소드가 모두 추상 메소드이므로 인터페이스는 구현하는 클래스에서 해당 메소드를 반드시 모두 오버라이딩해야 한다. 인터페이스에 들어있는 메소드는 항상 public abstract 이지만 abstract 키워드는 생략 가능하다. 인터페이스의 멤버 변수는 항상 public static final이다. interface라는 키워드로 정의한다. |
this 레퍼런스와 this()
자바에서 클래스를 실행하다보면 자기 자신의 클래스를 가리켜야 할 때가 있다. 클래스에서 자기 자신을 가리킬 때는 this 레퍼런스를 사용한다.
this()는 생성자에서 다른 생성자를 호출할 때 사용된다. 호출되는 생성자는 this() 안에 기술되는 매개 변수의 개수, 타입에 의해 결정된다. this()는 생성자 내에서 첫 번째 줄에 기술한다.
상위클래스의 생성자를 호출하려면 어떻게? 반드시 해야 하는것?
super 레퍼런스와 super()
super 레퍼런스는 슈퍼 클래스를 가리키는 레퍼런스이고, super() 메소드는 슈퍼 클래스의 생성자를 호출한다.
this 레퍼런스나 super 레퍼런스는 static이 붙은 메소드에서는 사용할 수 없다.
this는 현재 자신의 instance를 뜻합니다. this()는 자신의 생성자를 뜻하며,
super는 상위 클래스의 instance를 뜻합니다. super()는 상위 클래스의 생성자를 호출합니다.
this |
1) 클래스 내에서 자기 자신을 가리키는 레퍼런스이다. |
this() |
1) 클래스 내에서 다른 생성자를 호출하는 메소드이다. |
super |
1) 상위 클래스를 지칭하는 레퍼런스이다. |
super() |
1) 상위 클래스의 생성자를 의미하며, 상위 클래스의 생성자를 호출한다. |
가비지 콜렉팅, finalize()와 System.gc()
더 이상 객체가 사용되지 않을 때는 리소스를 반환해야 하는데 이것이 가비지 콜렉팅이다. 자바에서는 자동으로 메모리의 가비지 콜렉팅을 수행하기 때문에 메모리를 시스템으로 반환하는 것은 신경 쓰지 않아도 된다. 대부분의 리소스들은 객체가 더 이상 사용되지 않을 때 반환된다. 그러나 호스트 운영체제가 제공하는 글꼴이나 그래픽 관련 자원, 하드 디스크의 외부 파일과 같은 경우는 자동 리소스 반환이 되지 않을 수 있으므로 finalize()를 사용해서 리소스를 반환해야 한다. finalize()는 매개 변수를 갖지 않으며, 리턴 타입은 아무 값도 반환하지 않는 void를 사용한다.
finalize()는 원래 Object 클래스의 메소드이다. Object 클래스는 모든 클래스들의 최상위 클래스로서 클래스를 생성할 때 명시하지 않아도 자동으로 상속이 되는 클래스이다. 따라서 finalize()는 어떠한 클래스에서도 필요시에 재정의해서 사용할 수 있다. finalize()는 객체의 레퍼런스 변수에 null 값을 넣으면 자동으로 호출된다.
접근제어자 void finalize(){ } |
finalize()와 비교해서 생각해야 하는 것이 System.gc()이다. finalize()는 리소스를 해제할 때 쓰는 것이다. 리소스가 해제되면 가비지 콜렉터가 메모리에서 제거한다. 앞에서도 설명했듯이 가비지 콜렉션이 일어나는 시점은 알 수 없다. 가비지 콜렉터의 우선순위가 중간 정도이기 때문에 프로세서가 한가해야만 작동된다. System.gc()은 가비지 콜렉션이 좀 더 빨리 일어나도록 할 때 사용되는 메소드이다. 즉, 가비지 콜렉터를 호출하는 명령이다. 그러나 이 경우에도 가비지 콜렉션이 일어나는 기점은 알 수 없다. 가비지 콜렉터를 호출하더라도 우선순위가 높은 작업이 들어오면 프로세서의 점유권을 빼앗기고 대기 행렬 큐로 돌아가서 대기해야 하기 때문이다.
이 외 예상문제들
JDBC connect, ResultSet
Math.log()를 이용해서 입력받은 숫자의 맨 앞자리 수와 맨 뒷자리 수 구하기
컴파일 오류와 런타임오류
출처 :http://killmewild.blog.me/30098303930