패키지 (Package)
- 패키지(Package)는 프로젝트 내의 구조화를 위한 것이다. 사실은 디렉토리이다. 클래스 등의 구성요소의 이름이 같더라도 패키지 구조가 다르면 괜찮다.
- 베이스 패키지(Base-)는 프로젝트가 제 3자가 만든 프로젝트와 겹치지 않게하기 위해 본인 소유의 도메인의 역순으로 시작하는 것.
- 패키지는 클래스 등 구성요소 가장 상단에 "Package"라는 키워드와 함께 명시한다.
- 패키지의 명명은 스네이크 케이스(Snake Case)를 이용한다.
명명법
- 카멜케이스(Camel case) : 첫자 소문자로 작성하고 단어간 구분만 대문자로 작성한다. 변수, 비정적 상수, 메서드 등의 명명에 사용한다. 가령 someVariable, someMethod 등.
- 파스칼 케이스(Pascal Case) : 첫 자 대문자로 작성하고 단어간 구분도 대문자로 작성한다. 클래스, 인터페이스, 열거형 등의 명명에 사용한다. 가령 SomeClass, SomeInterface, SomeEnum 등.
- 스네이크 케이스(Snake Case) : 전체 소문자로 작성하고 단어간 구분을 언더스코어(_)로 한다. 패키지 명명에 사용한다. 가령 some_package.
- 어퍼 스네이크 케이스(Upper Snake Case) : 전체 대문자로 작성하고 단어간 구분을 언더스코어(_)로 한다. 정적인 멤버 상수명명에 사용한다. 가령 SOME_CONSTANT.
리터럴
- 리터럴(Literal)은 변수나 상수를 통하지 않고 값 그자체를 직접 명시하는 것을 의미한다. 중요한 의미를 가지는 값은 리터럴이 아닌 변수나 상수를 통해 사용하는 것이 좋다.
- 개발자가 필요해서 변수나 상수에 값을 초기화하기 위해 존재하는 리터럴은 관계없다.
- 전역적이지 않고 지역적이며 단발적인 값에 대한 리터럴 사용은 괜찮다.
변수(Variable)
- 기본적으로 변할 수 있는 값을 변수라 한다.
- 지역 변수(Local Variable) : 메서드 내에 존재하는 일반 변수 혹은 매개 변수를 의미한다. 지역 변수는 값이 초기화되지 않을 경우 값 대입을 제외한 나머지 접근을 할 수 없다.
- 멤버 변수(Member Variable) : 클래스 내에 존재하는 변수를 의미한다. 지역 변수와 달리 값을 초기화하지 않으면 기본 값으로 초기화가 이루어진다. 참조 타입(Reference Type)은 null, 기초 타입(Primitive Type)은 각 타입이 가지는 기본값이 들어간다.
상수(Constant)
- 상수의 종류는 두 가지로 나누어진다.
- 지역 상수(Local Constant) : 메서드 내에 존재하는 (일반)상수 혹은 매개 상수를 의미한다. 일반 상수의 경우 선언과 동시에 값을 초기화하지 않아도 괜찮으나 값을 초기화(혹은 대입)한 이후로는 값을 다시 대입할 수 없다.
- 멤버 상수(Member Constant) : 클래스 내에 존재하는 상수를 의미한다. 지역 상수와 달리 선언과 동시에 값을 초기화 하거나 생성자(Constructor)를 통해 값을 초기화 해야한다. 마찬가지로 값이 초기화되면 그 이후로는 값을 수정할 수 없다.
기초타입(Primitive Type)
- byte : 정수를 담는다.(-128 ~ 127)
- short : 정수를 담는다. (약 -3만 ~ 3만)
- int : 정수를 담는다. (약 -21억 ~ 21억)
- long : 정수를 담는다. (그이상)
- flaot : 실수를 담는다. (1.4E-45 ~ 3.4E38)
- double : 실수를 담는다.
- boolean : 논리값을 담는다. (true / false)
- char : 문자를 담는다. (문자 한 개) 문자를 아스키 코드 값(정수)으로 가지게 된다.
- 오버플로우(Overflow) : 어떠한 타입이 가질 수 있는 최대값을 양의 방향으로 넘어가면 최소값 부터 다시 시작
- 언더플로우 (Underflow) : 어떠한 타입이 가질 수 있는 최소값을 음의 방향으로 넘어가면 최대값 부터 다시 시작
배열
- 배열은 동일한 타입의 값을 하나의 변수에 여러개 담기 위한 것이다.
- T[] 형식으로 작성하며 이 때 T는 타입이다. 가령, int[], String[] 등.
- 모든 배열은 인덱스 번호를 가지는데, 일종의 방 번호이고, 항상 0부터 시작하며 (배열의 길이 -1)로 끝난다.
- 배열의 길이는 배열 객체가 가진 length 속성을 통해 접근할 수 있다.
- 2차 배열을 객체화 할 때 그 길이는 1차 배열의 것만 지정한다. 가령,
new int [0][] (O)
new int [5][5] (X)
선언(Declaration) [? 는 유무를 나타낸다]
- 지역 변수(상수) :
[ final ?][ 타입 ] [ 변수이름 ][ = 초기값? ];- 멤버 변수(상수) :
[ 접근제한자 ][ static ? ] [ final ? ][ 타입 ] [ 변수 이름 ][ =초기값 ? ];
접근제한자( Access Modifier )
- 접근제한자는 해당 변수, 상수, 클래스 등에 접근할 수 있는 대상을 제한하기 위해 사용한다.
- public : 해당 요소에 제한 없이 접근 할 수 있다.
- protected : 같은 패키지에 있거나 상호 상속 관계에 있는 경우에만 접근 할 수 있다.
- default : 같은 패키지에 있는 경우에만 접근할 수 있다. 별도로 명시하지 않으면 해당 접근 제한자이다. (절대로 default 라고 직접 쓰지 않는다.)
- private : 같은 클래스 내에 있는 경우에만 접근 할 수 있다.
메서드(Method)
- 메서드는 실행 단위이며 호출 대상이다. 클래스, 인터페이스 등이 가지고 있다.
- 구조 :
[ 접근제한자 ][ abstract | static | final ] [ 반환타입 | void ][ 이름 ] [ 매개변수,..? ] <throws <Throwable 타입>,...?> { 구현부? }- abstract : 해당 메서드의 추상적인가에 대한 여부. 추상적인 메서드를 추상 메서드(Abstract Method)라고 하고 이는 정적(static) 이거나 최종적(final)일 수 없으며 구현부를 가지지 않는다. 추상 메서드를 한 개 이상 가지는 클래스는 반드시 추상 클래스(Abstract Class)이다. 주로 해당 메서드의 구현부를 본 클래스를 상속 받는 자식 클래스로 하여금 직접 구현토록 하게 하기 위해 사용한다.
- static : 해당 메서드의 정적인가에 대한 여부. 정적인 메서드는 본 클래스의 객체가 아닌 클래스 이름으로 접근한다.(가령, Integer.parstInt(...)). 정적인 메서드는 추상적일 수 없고, 최종적이지 않아야 한다.
- final : 해당 메서드의 최종적인가에 대한 여부. 최종적인 메서드는 본 클래스를 상속 받는 자식 클래스가 재정의(Override)할 수 없다. 최종적인 메서드는 추상적일 수 없고, 정적이지 않아야 한다.
- void : 해당 메서드가 반환하는 값이 없음을 의미한다. 만약 해당 메서드가 반환 타입이 있다면 모든 경우에 'return' 키워드를 이용하여 적절한 값 혹은 객체를 반환해야 한다.
- 매개변수(Parameter) : 메서드 호출을 위해 필요한 변수들의 나열이다. 콤마(,)로 구분하여 여러개 사용가능 하다.
구조 :
[ final ][ 타입 ] [ 이름 ]- 구현부(Body) : 매서드 호출 시 실행할 코드를 포함하고 있다. 추상 메서드는 구현부를 가지지 않는다.
재정의, 오버라이딩(Override)
- 부모 클래스나 구현하고 있는 인터페이스의 메서드를 다시 정의하는 것.
- 재정의 된 메서드는 본 객체에 대한 접근 타입을 부모 타입으로 하여도 재정의된 내용이 실행된다.
- 단, 재정의하려는 메서드가 최종적(final)일 경우 재정의할 수 없다.
- 재정의시 Override 어노테이션(Annotation, @Override)을 붙이는 것도 좋고, 안 붙여도 재정의가 안 되지는 않는다.
- equlas(Object o)와 hashCode()메서드는 Object 클래스가 가지고 있는 메서드이고, 같은 타입의 서로 다른 두 객체의 비교를 위해 재정의 한다.
- 타입을 다르게 재정의 해서는 안된다.
오버로딩(Overload, Overloading)
- 같은 스코프(Scope)내에서 동일한 이름을 가지는 메서드에 대해 매개 변수 구조(타입이나 개수)를 달리하여 호출자(Caller)로 하여금 그 편의를 제공하기 위해 사용한다.
- 오버로딩된 대표적인 메서드는 System.out.println 이 있다.( 출력시 계속 같은 메서드를 이용 )
- main메서드에서 어떠한 메서드 호출후 값을 출력시, 각자의 타입에 맞는 메서드를 찾아서 실행이 된다.
- 추상 메서드 구현시에도 오버로딩을 할 수 있다.
클래스(Class)
- 클래스는 서로 연관있는 기능이나 값을 가지고 있는 타입(Type)이다.
- 구조 :
<접근제한자> <abstract | final?> <클래스 이름> <extends ...?> <implements...?> {...}- abcstract : 추상 클래스(Abstract Class)를 의미하며 추상 메서드를 한 개 이상 가지고 있다면 반드시 추상클래스여야 한다. 단, 추상 메서드가 하나도 없더라도 추상 클래스 일 수는 있다.
- final : 최종 클래스를 의미하며 이는 해당 클래스를 더 이상 상속 받을 수 없다는 의미이다. 선택적으로 클래스 이름의 접두어에 Immutable 이라는 단어를 붙인다.
- 상속관계에서 메서드 재정의시 부모 클래스의 의존하고있는 클래스의 메서드를 재정의 하는것이 아닌 현재 클래스가 의존하고있는 클래스의 것을 재정의 한다.
-extends : 어떤 클래스를 상속 받는가에 대한 정의이다. 반드시 1:1관계여야 하며 생략시 Object 클래스를 상속 받는 것으로 한다. 즉, 모든 참조 타입(Reference Type)은 결론적으로 Object 타입을 상속받는다. 순환 상속, 다중상속은 불가하다.- implements : 어떤 인터페이스를 구현할 것인가에 대한 정의이다. 콤마(,)로 구분하여 여러개의 인터페이스를 구현 할 수 있다.
- 생성자(Constructor)
- 해당 클래스를 객체화하기 위해 반드시 실행해야 하는 일종의 메서드이다.
- 생성자에 대한 명시가 없을 경우 기본 생성자(Default Constructor)가 존재하게 된다. 기본 생성자는 아무런 매개변수를 가지지 않고, 첫 구문으로 부모 생성자 호출(super())을 가진다.
- 생성자 또한 메서드의 일종임으로 오버로딩(Overloading)이 가능하다.
- 생성자의 첫 구문은 반드시 부모 생성자 호출이거나 자기 생성자 호출(this(...))이어야만 한다.
- 자식이 객체화되려면 반드시 상속 받고 있는 모든 부모 클래스가 가지는 생성자의 호출이 모두 완료되어야만 한다.
- (형식) :<접근 제한자> <클래스 이름> <매개변수,...?> {...}
- 정적 생성자(Static Constructor)
- 클래스와 무관하게 클래스가 가지고 있는 정적인 멤버에 접근할 수 있는 생성자이다. 명시적으로 호출할 수 있는 대상이 아님으로 메서드처럼 작성하지는 않는다.
- 프로그램 실행시 최초에 한번 만 실행되며 명시적으로 실행시킬 수 없음.
- (형식) : static{...} → 객체화와는 무관한다. 변수의 값이 로직을 통해 구현이 될 경우 사용하는게 좋다.