*객체지향언어
1. 코드의 재사용성이 높다
-새로운 코드를 작성할 때 기존의 코드를 이용하여 쉽게 작성
2. 코드의 관리가 용이
-코드간의 관계를 이용해서 적은 노력으로 쉽게 코드를 변경할 수 있다.
3. 신뢰성이 높은 프로그래밍을 가능하게 한다.
-제어자와 메서드를 이용해서 데이터를 보호하고 올바른 값을 유지한다.
-코드의 중복을 제거하여 코드의 불일치로 인한 오동작을 방지한다.
*main 메소드에 static을 사용하는 이유
- 먼저 static이 무엇인지 알아야 한다. static은 정적, 즉 java프로그램이 실행하기 전에 static변수나 static메소드를
첫 단계로 메모리에 올려 프로그램을 실행시킨다. (static은 실행시 1순위) 프로그램 종료시까지 사라지지 않음
- main함수가 실행되기 위해서는 메모리에 미리 올라가야한다. 메모리에 올라가있지 않으면 시작점인 main() 메소드를
호출하려고 하는데 메모리에는 main이 없기때문에 실행을 할 수가 없다.
-main메소드도 누군가의 호출되기 전에는 메모리에 올라가지 않는다.
-main을 호출하기 위해서는 메모리에 main메소드 내용이 있어야하는데 이 main메소드는 누군가
호출하기 전에 미리 메모리에 있어야하기 때문에 static을 붙인다.
정리 : static을 메소드에 붙이면 정적 메소드가 되고, 이렇게 '정적'으로 선언한 경우에는 객체를 생성하지 않아도 프로그램 실행시 자동으로 메모리에 적재된다. main메소드는 객체를 생성하지 않아도 자동으로 실행되는 작업을 수행해야하는 부분이기 때문에 static을 선언한다.
static 으로 선언한 함수나 변수는 자바 가상 머신에서 객체의 생성 없이 메모리에 할당시켜 호출 가능한 형태로 만든다.
■접근 제어자의 접근범위
(넓음) public -> protected -> default -> private (좁음)
■ EL (Expression Language) -JSP
- EL(Expression Language)은 <%= abc %>를 ${abc} 로,
- JSTL의 Core에서 c를 이용해 <%= if%>문을 <c:if>로 , <%=for%>문을 <c:forEach>로 대체하여 사용한다.
■ Integer는 null값이 가능하다.
오버라이딩(overriding)
-조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것을 오버라이딩(overriding)이라고 한다. 상속받은 메서드를 그대로 사용하기도 하지만, 자손 클래스 자신에 맞게 변경해야하는 경우가 많다. 이럴 때 조상의 메서드를 오버라이딩 한다.
-오버라이딩(overriding)은 메서드의 내용만을 새로 작성하는 것이므로 메서드의 선언부는 조상의 것과 완전히 일치해야 한다.
-조상 클래스의 메서드와 이름,매개변수,반환타입이 동일해야 한다.
-조상 클래스의 메서드의 접근 제어자 범위보다 좁은 범위로 변경 할 수 없다.
오버로딩(overloading)
-기존에 없는 새로운 메서드를 추가(정의) 하는 것을 오버로딩(overloading)이라고 한다.
-메서드도 변수와 마찬가지로 같은 클래스 내에서 서로 구별될 수 있어야 하기 때문에 다른 이름을 가져야한다.
그러나 자바에서는 한 클래스 내에 이미 사용하려는 이름과 같은 이름을 가진 메서드가 있더라도, 매개변수의 개수 또는 타입이 다르면 같은 이름을 사용할 수 있다.
class Parent {
void parentMethod() {
}
}
class Child extends Parent {
void parentMethod() {} // (1)
void parentMethod(int i) {} // (2)
void childMethod() {} // (3)
void childMethod(String s) {} // (4)
(1) -> 오버라이딩
(2) -> 오버로딩
(3) -> 그냥 Child클래스에 정의된 메서드
(4) -> 오버로딩
다형성(polymorphism)
-상속과 함께 객체지향개념의 중요한 특징 중의 하나로, '여러 가지 형태를 가질 수 있는 능력'을 의미한다.
-자바에서는 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 하는 기능
-즉, 조상타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있다는 것.
class Tv {
boolean power;
int channel;
void power() {
power = !power;
}
void channelUp() {
++channel;
}
void channelDown() {
--channel;
}
}
class CaptionTv extends Tv {
String text;
void caption() {
// 내용생략 //
}
}
CaptionTv c = new CaptionTv();
Tv t = new CaptionTv();
- 두개의 CaptionTv 인스턴스를 생성했을 때, t 인스턴스는 CaptionTv 타입이라 할지라도 CaptionTv인스턴스의 모든 멤버를 사용할 수 없다. 즉, text와 caption()메서드는 사용이 불가능하다는 것이다.
반대로 자손타입의 참조변수로 조상타입의 인스턴스를 참조하는 경우
CaptionTv c = new Tv(); // 에러
이 경우는 에러가 발생한다. 그 이유는 실제 인스턴스인 Tv의 멤버 개수보다
참조변수인 c의 멤버 개수가 더 많기 때문이다.
조상타입의 참조변수로 자손타입의 인스터스를 참조할 수 있다.
자손타입의 참조변수로 조상타입의 인스턴스를 참조할 수는 없다.
*참조변수의 형변환
자손타입 -> 조상타입 (Up-casting) : 형변환 생략가능
조상타입 -> 자손타입 (down-casting) : 형변환 생략불가
super
-super는 자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조 변수이다.
-조상클래스로부터 상속받은 멤버도 자손 클래스 자신의 멤버이므로 super 대신 this를 사용해도 된다.
-조상의 멤버와 자손(자신)의 멤버를 구별하는데 사용된다는 점을 제외하면 super와 this는 근본적으로 같다.
-this와 마찬가지로 super도 static메서드(클래스메서드)에서는 사용할 수 없다.
인터페이스(interface)
-인터페이스는 일종의 추상(abstract) 클래스 이다. 그러나 추상클래스보다 추상화 정도가 높아서 일반 메서드와 멤버변수를 구성원으로 가질 수 없다. 오직 추상메서드와 상수만 가질 수 있다.
-추상클래스를 부분적으로만 완성된 '미완성 클래스' 라고 한다면, 인터페이스는 구현된 것은 아무 것도 없고 밑그림만 그려져 있는
'기본 설계도' 라 불린다. 즉, 다른 클래스들에 도움을 줄 목적으로 작성된다.
-인터페이스가 가지는 모든 멤버 변수는 무조건 public static final 이어야 한다.
-인터페이스가 가지는 모든 메서드는 public abstract 이어야 한다.
-단 , static메서드와 default에서는 예외.
-개발시간을 단축시킬 수 있다.
-표준화가 가능하다.
-서로 관계없는 클래스들에게 관계를 맺어 줄 수 있다.
-독립적인 프로그래밍이 가능하다.
클래스와 인터페이스의 차이점
*문법적인 부분에서의 차이
-인터페이스는 abstract(추상) 메서드만 정의가 가능하고, 상수 또는 final로만 정의가 가능하다.
-인터페이스로는 객체생성이 불가능하다
*활용적인 부분에서의 차이
-인터페이스는 객체의 사용법을 정의하기 위한 용도
-다른 클래스들에 도움을 줄 목적으로 작성됨.
배열 vs ArrayList
*배열
-배열의 크기는 한번 정의하면 수정할 수 없다.
-배열 초기화시 메모리에 바로 할당되어 ArrayList보다 속도가 빠르다.
*ArrayList
-ArrayList는 크기가 가변적이다.
-ArrayList는 저장하는 데이터 수에 따라 크기가 변경된다.
-데이터 삽입 및 삭제시 add() 메서드와 remove() 메서드가 사용된다.
-데이터의 추가 및 삭제시 메모리를 재할당하기 때문에 속도측면에서는 배열보다 느리다.
List
-순서가 있는 데이터의 집합, 데이터의 중복을 허용한다.
-ArrayList, LinkedList, Stack, Vector 등
Set
-순서를 유지하지 않는 데이터의 집합, 데이터의 중복을 허용하지 않는다.
-HashSet, TreeSet
Map
-키(Key)와 값(value)의 쌍(pair)으로 이루어진 데이터의 집합
-순서는 유지되지 않으며, 키는 중복을 허용하지 않고 값은 중복을 허용한다
-HashMap, TreeMap, Hashtable, properties
Vector, Stack, Hashtable, Properties와 같은 클래스들은 컬렉션 프레임웍이 만들어지기 이전부터 존재하던 것이기 때문에 컬렉션 프레임웍의 명명법을 따르지 않는다.
Vector나 Hashtable과 같은 기존의 컬렉션 클래스들은 호환을 위해, 설계를 변경해서 남겨두었지만 가능하면 사용하지 않는 것이 좋다.
Collection interface method
boolean add(E e) : 객체 e를 내부 목록에 추가한다.
boolean addAll(Collection<E> c) : 목록 객체 c에 들어있는 항목들을 전부 내부 목록에 추가한다.
void clear() : 목록에 들어있는 항목 전체를 제거한다.
boolean contains(Object o) : 파라미터 o와 동일한 값이 내부 목록에 들어있다면 true
boolean containsAll(Collection<E> c) : 컬렉션 객체 c에 들어있는 항목들이 this객체에 전부 들어있으면 true
boolean equals(Object o) : 객체 o와 this객체의 equality 를 비교한다.
int hashCode() : 내부 객체 목록을 hash code 값을 계산해서 리턴한다.
iterrator <E> iterator() : 내부 목록에 들어있는 항목을 하나씩 탐색하기 위한 Iterator 객체를 생성하여 리턴
*Iterator 사용예시
static void solution(List a) {
Iterator it = a.iterator();
while(it.hasNext()) {
int value = it.next();
if(value % 2 == 0 || value % 3 == 0) { it.remove();
}
}
}
boolean remove(object o) : 파라미터 o와 동일한 값을 목록에서 찾아서 제거한다.
boolean removeAll(Collection c) : 파라미터로 주어진 목록 객체 c에 들어있는 항목을 전부 제거한다.
boolean retainAll(Collection c) : 파라미터로 주어진 목록 객체 c에 들어있지 않는 항목들을 전부 제거한다.
int size() : 내부 목록에 들어있는 항목의 수를 리턴한다.
Object[] toArray() : 목록 객체에 들어있는 항목들을 배열로 리턴한다.
Comparable
-객체와 객체간의 일반적인 정렬이 필요할 때, Comparable 인터페이스를 확장해서 정렬의 기준을 정의하는
compareTo() 메서드를 구현한다.
일반적인 정렬
: 객체 간의 정렬에 있어서 오름차순, 내림차순등의 일반적인 순서를 잡는 기준이 필요할 때 객체클래스에 확장해서 사용한다.
public class Person implements Comparable<Person> {
String name;
int age;
public Person(String name, int age){
this.name = name;
this.age =age;
}
// .... getter , setter 생략 ..... //
@Override
public boolean equals(Object obj) {
if ((obj instanceof Person) == false)
return false;
Person p = (Person) obj;
return (this.name == null ? p.name == null : this.name.equals(p.name)) && this.age == p.age;
}
@Override
public int compareTo(Person p) {
int r = this.name.compareTo(p.name); // 먼저 이름(name)을 비교한다.
if (r != 0) // 0은 동일, 1은 this객체가 크고 0은 this객체가 작음
return r; // 이름이 같지 않다면, 이름 비교 결과를 리턴한다.
return this.age - p.age; // 이름이 같다면, 나이순으로 리턴한다.
}
}
위 코드는 이름 순서로 출력하는 코드이다.
이름이 동일하다면 , 나이순서로 출력한다.
#전역변수의 사용을 줄이자.
-프로젝트 규모에 따라 코드가 커지면서 여러 메소드에서 전역 변수의 값을 변경하기 시작하면, 전역 변수에 저장되어 있는 값을 파악하기가 어려워진다.
-단, 읽기 전용 값을 공유해서 전역 상수로 쓰는것은 적극적으료 활용해도 된다. ex) 원주율(PI)
'Java' 카테고리의 다른 글
[Java 8] 메서드 레퍼런스(Methods Reference) (0) | 2020.09.15 |
---|---|
[Java] 유용한 Math 메소드 (0) | 2020.07.05 |
Map의 유용한 인터페이스 (0) | 2020.06.19 |
CompareTo / Comparator 사용하기 (0) | 2020.03.13 |
deque [java] (0) | 2019.09.19 |