Home Java 프로그래밍 교육 3일차
Post
Cancel

Java 프로그래밍 교육 3일차

배열(Array)의 각 인자에는 Primitive Type(원시타입)과 Class Type(클래스 타입) 두 가지 타입이 올 수 있다.

자바 서비스단 구현 시 서비스 메서드명에는 몇가지 규칙이 있다. 꼭 정해진 규칙은 아니나 지켜진 경우 훨씬 가독성이 좋다.

  • 조회 메서드는 getObject와 같이 get으로 시작한다. 전체를 조회하는 경우 getAllObjec 또는 getObjects와 같이 작성한다.
  • 검색 메서드의 경우 search나 find로 시작한다. 검색 조건등이 있는 경우 뒤에 ByParameter를 붙여 구분한다.

평소 서비스 메서드 작성할 때 DAO 이름을 따라가거나 대충 짓는 경우가 많았는데 앞으로 위 규칙을 따라 깔끔하게 작성해야겠다.


메서드 오버로딩(Method Overloading) 
하는 일은 같지만 처리해야하는 데이터나 메서드마다 로직이 다를 때 쓰는 기법이다. 예를 들어, 검색이란 기능은 동일하나 검색 조건이나 범위등이 달라질 때 구현 시 사용된다.

  • 메서드명은 동일하다.
  • 메서드 인자(순서, 데이터 타입, 수 등)는 반드시 달라야한다. 
  • 메서드 리턴 타입은 같거나 다르거나 상관없다.

메서드 오버라이딩(Method Overriding)
같은 기능이나 상속받는 클래스마다 그 로직이 달라질 때 사용한다. 부모 클래스에서 이미 정의된 메서드를 자식 클래스에서 같은 시그니쳐를 갖는 메서드로 다시 정의하는 것이다. 자바에서 자식 클래스는 부모 클래스의 private 멤버를 제외한 모든 메서드를 상속받는다.

  • 메서드의 선언부는 동일하다. 반환 타입은 부모 클래스의 반환 타입으로 타입 변환할 수 있는 타입이라면 변경할 수 있다.
  • 구현부는 상속받은 클래스마다 달라진다.
  • 부모 클래스의 메서드보다 접근 제어자를 더 좁은 범위로 변경할 수 있다.
  • 부모 클래스의 메서드보다 더 큰 범위의 예외를 선언할 수 있다.


상속(Inheritance) 
부모 클래스의 멤버(필드와 메서드)를 물려받음과 동시에 자식은 자식만의 멤버를 갖을 때를 의미한다. 모든 클래스의 근원은 Object 클래스이며 모든 클래스는 Object 클래스를 상속받는다.
[Java Object Docs] https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html

Object 클래스가 물려주는 중요한 메서드에는 두 가지가 있다

  • equals()
    객체가 같은지 다른지 주소값을 비교하여 boolean값을 리턴한다.
    String 객체의 경우 주소값이 아닌 실제 객체 내 값이 같은지 아닌지 비교하여 리턴한다. 이러한 이유는 각 객체에 맞게 해당 메서드를 오버라이딩하여 사용하기 때문이다.
  • toString() 
    사실 모든 객체 뒤에는 .toString()이 숨겨져있다. 객체를 콘솔에 찍어보면 주소값이 적히는 걸 확인할 수 있는데, toString() 메서드는 메모리에 현존하는 객체의 주소값을 String으로 리턴하여준다.
    이 또한 필요 시 객체 내 필드값을 리턴하는 메서드로 오버라이딩하여 사용할 수 있다.


추상화(Abstraction) 

image

관련성 없는 모듈 사이에서 공통적으로 포함된 성질들을 찾아 그 성질들을 일반적인 필드로 갖는 모듈 하나로 상정하는 것이다.
추상화한 객체는 부모 클래스(Parent Class, Super Class)이고 상속받은 객체들은 자식 클래스(Child Class, Sub Class)라고 한다.

아래 세 직업군의 필드 중 name, birthday, salary 필드는 공통으로 들어가는 필드들이다. 이런 공통점들을 모아 Employee라는 객체를 만들었다. 이 과정을 추상화라고하며 Employee 객체를 가지고 Manager, Engineer, Teacher 라는 객체를 구현하는 것을 구체화 또는 실체화라고 한다.


extends 키워드는 대표적인 상속 키워드로 부모 클래스의 메서드를 그대로 이용하거나 오버라이딩(재정의)할 수 있다. 말 그대로 부모 클래스를 확장하는 것이다.

그 외에도 implementsabstract키워드, interface 등이 있는데 추후 추가할 예정!


this 키워드는 객체 자신을 의미한다. 객체 자신의 정보를 담고 있다.
생성자 작성 시 동일한 이름의 로컬 변수와 필드명을 구분하고자 사용하거나 생성자 안에서 또 다른 생성자를 호출을 위해 사용한다.

아래 name, birthday, salary 세 필드를 갖는 객체 Employee가 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Employee{
   private String name;
   private Date birthday;
   private double salary;
   
   public Employee() {} //명시적 생성자있을 경우 기본 생성자 필수
   
   public Employee(String name, Date birthday, double salary){
      this.name = name;
      this.birthday = birthday;
      this.salary = salary;
   }  
}

만약 salary에 값이 입력되지 않은 경우 기본값으로 세팅 후 객체를 생성하고 싶다면 모든 인자를 받는 생성자를 이용하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Employee{
   private String name;
   private Date birthday;
   private double salary;
   
   private static final double BASIC_SALARY = 0.0;
   
   public Employee() {} //명시적 생성자있을 경우 기본 생성자 필수
   
   public Employee(String name, Date birthday, double salary){
      this.name = name;
      this.birthday = birthday;
      this.salary = salary;
   }  
   
   public Employee(String name, Date birthday){
      this(name, birthday, BASIC_SALARY); //salary = 0.0
   }  
}

비어있는 salary 대신 0.0으로 초기화된 상수 BASIC_SALARY를 인자로 전달하여 객체를 생성한다.

The field ~~ is not visible.
만약 자식 클래스에서 부모 클래스의 멤버 필드 접근하려 하면 위와 같은 에러 메시지가 뜬다. 자식 클래스 생성자 작성 시 부모 클래스의 멤버변수는 직접 초기화하지 못한다. 이때 사용하는 것이 super 키워드이다.

this가 객체 자신을 가리키는 것처럼 super는 부모 클래스를 의미한다.

1
2
3
4
5
public Child(String f1, int f2..) extends Parent{
    super(); // Parent()
    this.f1 = f1;
    this.f2 = f2;
}

클래스 작성 시 자동생성으로 생성자를 작성하면 super(); 구문이 자동으로 작성되는데 이것이 바로 부모 클래스 생성자 호출이다.
만약 자식 클래스에서 부모 클래스의 멤버 필드까지 초기화하여 생성자를 작성하고 싶다면 아래와 같이 활용할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
// 부모 클래스
class Parent {
   private String p1;
   private int p2;
   
   public Parent(){};
   public Parent(String p1, int p2){
      this.p1 = p1;
      this.p2 = p2;
   }
}
1
2
3
4
5
6
7
8
9
10
// 자식 클래스
class Child extends Parent{
   private double f1;
   
   public Child(){};
   public Child(String p1, int p2, double f1){
      super(p1, p2); // Parent(p1, p2);
      this.f1 = f1;
   }
}

비슷하게 toString()을 객체 주소가 아닌 필드 정보를 리턴하도록 재정의한 경우, 부모 클래스의 필드도 함께 출력할 수 있다.

1
2
3
public String toString(){
   return super.toString() + ...; // 부모 클래스 toString() 호출
}


부모 클래스를 extends한 자식 클래스 생성 시 메모리 구조는 새로 할당이 아닌 말 그대로 확장 이다.
자식 객체 생성 시(생성자 호출 시) 부모 클래스의 생성자가 반드시 먼저 호출된다.

image

  1. Stack에 Child를 위한 공간이 생긴다.
  2. Heap에 Child 생성 전, 부모 클래스인 Parent가 먼저 생긴다. 그리고 값이 기본값으로 초기화(묵시적 초기화)된다.
  3. Heap에 Chid가 새로 생성되는 것이 아니라 Parent 클래스에 Child만의 필드들이 추가되어 Child로 확장된다. 추가된 필드들도 기본값으로 초기화된다.
  4. 이 공간에 주소가 라벨링되고 Stack에 해당 주소값이 저장된다.
This post is licensed under CC BY 4.0 by the author.