Java - accidentlywoo/sec GitHub Wiki

Java 정리

객체지향 프로그래밍을 하자!

  • 목적 : 클래스 재사용성을 높이자.

객체지향언어의 조건

  1. 상속 단일 상속

    extends : class 하위클래스 extends 상위클래스{}

    상속은 "Is A"||"Kind Of" 관계일때 사용한다. 논리적인 설계를 하자!

    "Has A"관계로 표현할 수 있어야 한다.

  2. 캡슐화 - 접근제어

  3. 다형성

접근제어

  • public : 누구나
  • protected : 동일 패키지에서 접근가능, 다른 패키지의 하위클래스에서 접근가능
  • deault(package) : 동일 패키지에서 접근가능
  • private : 자기자긴만 쌉 가능

캡슐화

은닉된 정보에 접근할 수 있는 기능을 제공한다. 설정(set) / 얻기(get)

컴포넌트[JavaBean]

자바빈이 되기위한 조건 4가지.

  1. public class

  2. public 매개변수없는 새성자

  3. 프로퍼티용 인스턴스변수는 public 이면 안됨

  4. 프로퍼티용 public setter 메서드 / public getter 메서드

public class Star{
 private String color;
 private String size;

 public void setColor(String color) {
  // 설정 제어문 작성 
  this.color = color;
 }
 public String getColor(){return color;}
}

정적 멤버와 static

클래스 로딩시 초기화된다. this 키워드 사용불가. 클래스 이름으로 접근하는게 메모리 효율에 좋다.

class Single{
	static int sv;
	private Single() {}
	static void plus(int i) {
		sv =  sv+i;
	}
	static Single getInstance() {
		return new Single();
	}
}

class Main{
 public static void main(String[] args) {
  System.out.println(Single.sv);

  Single s1 = Single.getInstance();
  System.out.println(s1.sv);
 }
}

static 필드를 인스턴스화해서 인스턴스 객체로 접근하면 스택에서 힙영역을 뒤지고 없으면 ClassArea를 뒤지기 때문에 효율이 떨어진다.

System.out.println(s1.sv); //효율 쌉 손해, IDE에서 warning을 표시한다.
System.out.println(Single.sv); // 이렇게 사용하자.
lass Single{
	int iv;
	static int sv;
	private Single() {}
	static void test() {
//		System.out.println(this);
//		System.out.println(iv);
//		System.out.println(this.iv);
//		System.out.println(plus);
//		System.out.println(this.plus);
	}
	static void plus(int i) {
		sv =  sv+i;
	}
	static Single getInstance() {
		return new Single();
	}
}

static method는 인스턴스화한 객체의 method영역에서 메서드 시그니처가 없다. class Area에서 뒤적거림

static method를 사용함으로써 장점을 뽑을 수 있는 메소드

  • 유틸 클래스
  • 정적 팩토리 메서드
  • 빌더 패턴
  • 싱글톤

상속

힙 메모리를 그릴때, 자식객체의 메모리안에 부모객체의 영역이 먼저 생긴다. (책이 잘못됨. 따로 생겨서 상속받거나 그렇지 않다.)

Is A 관계

class Person{
  String name;
  String addr;
}

class Customer extends Person{
  String id;
  String pwd;
}

Customer은 Person이다.

class Person{
  String name;
  String addr;
}

class Account extends Person{
  String id;
  String pwd;
}

Account는 Person이 아니다.

Has A 관계

class Person{
  String name;
  String addr;
}

class Account{
  String id;
  String pwd;
  Person PersonInfo;
}

Account는 Person정보를 갖는다.

상속시 멤버필드명 중복

class GrandParent{
int i;
}
class Parent extends GrandParent{
  String i;
  void pm(){
    super.i = 10;
  }
}
class Child extends Parent{
  boolean i;
  void m(){
    this.i = true;
    super.i = "hello";
    pm();
  }
}

new Child().i = false;

super 키워드는 현재 객체에서 부모객체에 접근.

super() 부모 생성자 호출하라!

다형성의 개념을 체크하자.

  • auto up casting
  • 강제 down casting

오버라이드 규칙

  1. 상속관계 메서드
  2. 메서드명 동일, 매개변수(자료형, 개수, 순서) 동일, 반환형도 동일
  3. 상위 메서드 접근범위 <= 하위메서드 접근범위
class P{  // 컴파일러에서 class P extends Object{ 로 변환
 void m(){}
 void m1(){}
}
class C extends P{
 public void m(){}
 private void m1(){} // 컴파일 오류
}
  1. 예외선언

Object 최상위 객체

Object

  • +hashCode():int
  • +toString():String
  • +equals(Object):boolean

String

  • +hashCode():int
  • +toString():String
  • +equals(Object):boolean

StringBuffer

  • +toString():String

Final Class 와 Abstract Class

클래스의 역할

  • 객체를 만드는 틀(final class)
  • 하위 클래스들의 공통점을 모아둠(abstract class)

일반적인 클래스들은 이둘의 특징을 모두 갖는다.

Final Method 와 Abstract Method

  • final 메서드 : 재정의(overriding 못함) 금지
  • abstract 메서드 : 반드시 재정의 필요, 추상 메소드를 갖고있는 클래스는 반드시 추상 클래스여야 한다.

Abstract Class

new 키워드를 사용해서 인스턴스화 할 수 없다.

생성자가 있는데 protected 접근 제어자가 붙어있다.

-> 하위 클래스에서 확장했을때, 생성자가 필요하기 때문에 만들어져있다.

ex) Abstract Class 인 Calendar 클래스는 Calendar(), Calendar(TimeZone zone, Locale aLocale) 생성자가 있는다.

Calendar 클래스의 하위 클래스인 GregorianCalendar는 Calendar.getInstance()로 인스턴스화할 수 있다.

GregorianCalendar클래스는 확장한 Calendar 추상 클래스의 생성자를 사용해(super()) 생성자 활용한다!

Interface

interface A{
  int A_CNT = 1;
  void a();
}

interface B{
  void b();
}

interface ABC extends A, B{
  void abc(); // public abstract void abc();
}

class ABCImp implements ABC{
 //void abc(){} 접근제어자 컴파일 에러
 public void abc(){}
 public void a(){}
 public void b(){} 
}

abstract class ABCImp2 implements ABC{} // 컴파일 에러 나지 않는다.

class ABCImp3 extends Parents implements ABC{
 public void abc(){}
 public void a(){}
 public void b(){} 
}

Exception

  • 효율성을 생각하고 코드를 작성하는 것이 좋다.

ex) for문에서 Exception 체크를 해야할 때는

// Bad Code
for(int i = 0 ; i < 10000; i++){
  try{
    exceptionCheckPlease(i);
  }catch{}
}
// good code
try{
  for(int i = 0; i < 10000; i ++){
    exceptionCheckPlease(i);
  }
}catch{}

매번 체크하는 것보다. for문이 깨질때 catch하는 것이 좋다. (설계에 따라 다름)

Exception 에서 setMessage() 는없다. 메세지를 설정하고 싶다면?

강제로 Exception을 발생시키고, 생성자에 메시지를 담고, 클래스 생성한다.

throw new IOException("예외 발생");

throws를 JVM으로?

throws를 뒤지게 써서 main메소드까지 넘기면 JVM까지 넘길 수 있다.

멀티 Exception

디테일한 Exception catch구문을 작성하고 싶다면, 하위클래스부터 catch 구문을 작성해야 flow에 맞다.

사용자 정의 Exception

서비스단의 Exception때문에 코드가 지저분해질 수 있기때문에 사용자 정의 Exception을 작성할 수 있다.

주로 기능별, 메소드별로 만들 수 있다.