상속(Inheritance)과 구성(Composition) 상속을 사용하는 이유 공통적인 부분을 가지고 있는 상위 클래스를 활용하여 하위 클래스는 본인 고유의 상태와 행동을 정의하기 위함이다. 코드의 확장성, 재사용성이 용이하고 중복된 코드를 상위 클래스로 뺐으므로 코드가 간결해진다. 결과적으로, 유지보수가 쉬워진다는 점이다. 상속 정의 하위 클래스는 상위 클래스의 모든 메소드를 재사용할 수 있고, 재정의를 하여 하위 클래스만의 메소드로 변경할 수도 있다. public class Car{ public void print() { System.out.println("부릉부릉"); } } public class Tico extends Car{ @Override public void print() { Syste..
오버로딩 왜 오버로딩을 사용하는가? 객체가 커지면 커질수록 메소드의 개수는 많아진다. 이 때, 근본적으로는 같은 기능을 하지만 이름 짓기가 애매하고 사용하는 쪽도 메소드만 보고 확실한 개념을 잡기에 어려워 오버로딩을 사용한다. 객체적으로 접근해봤을 때는, 사용하려는 객체의 메소드만 알고 있으면 해당 메소드(오버로딩 메소드)는 여러 파라미터를 가지고 있어 객체간의 메시지 전송이 원활하다. 흔히 알고 있는 오버로딩 오버로딩 조건 메소드 이름은 같아야 한다. 파라미터 개수나 타입이 달라야 한다. return 타입은 상관이 없다. //생성자 오버로딩 public class BasicOverLoading { String brandName; int since; public BasicOverLoading(int si..
enum 열거형이라고 칭하고, JDK5부터 추가되었다. JDK5 전에는 상수를 활용하여 열거형의 개념을 표현했다. public class EnumStudy { public static final String MALE = "MALE"; public static final String FEMALE = "FEMALE"; public static void main(String[] args) { String gender; gender = EnumStudy.MALE; gender = EnumStudy.FEMALE; } } 상수를 사용했을 때 문제가 발생한다는 것을 찾을 수 있었다 gender라는 String 변수는 처음 "MALE"이라는 변수로 고정되기를 원하는데, 다음 라인에서 "FEMALE"로 변경되는 것을 볼..
변수의 Scope와 static 변수가 선언된 블럭이 해당 변수의 사용범위이다 public class ValueScope{ int global = 0; public int func(int val) { int local = 1; } } 클래스 속성의 변수 global 변수로서, ValueScope 전체 범위가 해당 변수의 Scope이다. 매개변수로 선언된 변수 val 변수로서, func 메소드 블럭만이 해당 변수의 Scope이다. 메소드 블럭 내에 선언된 변수 local 변수로서, 매개변수와 마찬가지로 func 메소드의 블럭만이 해당 변수의 Scope이다. static 공유 자원이며, 객체가 인스턴스화 되지 않아도 호출하여 사용할 수 있는 특징을 가지고 있다. 좀 더 자세한 설명을 봐보자 메모리 할당 지역..
자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 많은 클래스가 하나 이상의 자원을 의존한다. 맞춤법 검사기(SpellChecker)가 사전(Dicitonary)에 의존하는 예를 확인해보자 //정적 유틸리티 활용 public class SpellChecker { private static final Lexicon dictionary = ...; //정적 유틸리티 private SpellChecker() {} //객체 생성을 방지 public static boolean isValid(String word) {...} public static List suggestions(String typo) {...} } //싱글턴 활용 public class SpellChecker { private final Le..
불필요한 객체 생성을 피하라 똑같은 기능의 객체를 매번 생성하기보다는 객체 하나를 재사용하는 편이 나을 때가 많다. 한 코드의 예를 통해 살펴보자 String s = new String("Effective Java"); String s = "Effective Java"; 첫번 째 문장은 실행될 때마다 String 인스턴스가 새로 만들어진다. 이 문장은 매우 쓸데 없다.. 만약 반복문이나 빈번히 호출되는 메서드 안에 있다면 쓸데없이 해당 인스턴스가 새로 만들어질 수 있다. 그냥 재사용하면 되는데.. 두번 째 문장을 살펴보면 새로운 인스턴스를 매번 만드는 대신 하나의 String 인스턴스를 사용한다. 즉, 반복문이나 빈번히 호출되는 메서드 안에 있어도 가상 머신 안에서 재사용함이 보장되는 것이다 생성자 대신..
인스턴스화를 막으려거든 private 생성자를 사용하라 단순히 정적 메서드와 정적 필드만을 담은 클래스를 만들고 싶을 때가 있을 것이다. 정적 메서드와 정적 필드(static) 사용 시 클래스 인스턴스 없이 호추링 가능 다른 객체와 공유 가능 유틸리티 함수를 만드는데 유용 Math.max(); 추상 클래스로 만드는 것으로는 인스턴스화를 막을 수 없다. 이는 하위 클래스를 만들어 인스턴스화 하면 그만인것을.. 결과적으로, private 생성자를 추가하면 클래스의 인스턴스화를 막을 수 있다. private UtilityClass() { throw new AssertionError(); } 명시적 생성자가 private이니 밖에서 접근 불가하다. 꼭 AssertionError를 던질 필요는 없지만, 클래스 안..
제네릭 제네릭이란 무엇인가? 제네릭은 간단히 말해 데이터 타입을 명시하지 않은 상태를 말한다. 쉽게 생각해보면 클래스의 데이터 타입을 미리 정의하지 않고, 클래스가 인스턴스화 되는 시점에 데이터 타입을 지정해주는 방식이다. 제네릭은 를 활용하여 구현한다. 제네릭을 사용하는 이유는 무엇인가? 제네릭을 사용하는 이유 즉, 장점을 살펴보겠다. 제네릭을 활용하면 강제적인 타입 변환이 발생하지 않아 성능 저하를 방지할 수 있다. 중복 코드를 제거하고 코드의 재사용성을 증진시킨다. 컴파일 시에 타입 오류를 체크하여 안정적으로 데이터 타입을 체크할 수 있다. 하나씩 코드와 함께 살펴보자. 제네릭을 활용하면 강제적인 타입 변환이 발생하지 않아 성능 저하를 방지할 수 있다. 제네릭을 사용하지 않는 코드를 확인해보자 pu..
- Total
- Today
- Yesterday
- java8
- package-private
- 정적팩터리메서드
- 스프링부트
- try catch finally
- 생성자
- 점층적 생성 패턴
- 복사 팩토리
- 자바8
- java
- 빈 순환 참조
- 이펙티브 자바
- 김영한
- jdk버전
- ifPresent
- Effective Java
- flatMap
- mustache
- try with resources
- 빌더 패턴
- @Lazy
- 이펙티브자바
- effectivejava
- Spring
- 팩토리 메소드 패턴
- JPA
- 인프런
- 연관관계
- junit
- springboot
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |