제네릭 (Generic)

제네릭이란

  • 대상 객체의 타입을 입력받아 사용할 수 있는 형식
  • 미리 사용할 수 있는 타입을 명시하여 컴파일 타임에 체크할 수 있음
    • 입력을 Object로 한 경우 런타임을 체크하기 위한 instanceof를 많이 사용해야 함
    • 제네릭을 사용할 경우 간결하게 코드를 작성할 수 있다.

제네릭 클래스

제네릭 타입

  • 클래스와 인터페이스에 제네릭이 적용된 타입

  • 클래스를 선언할 때에는 타입이 알려지지 않으며, 타입 파라미터를 사용

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class GenericClass<T> { // T: 타입 파라미터
    ...
    }

    public interface GenericInterface<T> { // T: 타입 파라미터
    ...
    }

    public class HashMap<K,V> { // K, V: 타입 파라미터
    ...
    }
  • 제네릭 타입은 실제로 사용될 때 타입 파라미터에 자료형을 입력받는다.

    1
    2
    GenericClass<String> generic = new GenericClass<String>();
    GenericClass<String> generic2 = new GenericClass<>();

타입 파라미터 주의점

  • static 멤버 변수는 타입 파라미터를 사용할 수 없다.

  • 정적 메소드에도 타입 파라미터를 사용할 수 없다.

  • 이유 : 객체를 생성했을 때 타입 T가 결정되기 때문이다.

    1
    2
    3
    4
    public class Generic<T> {
    static T classVar; // not possible
    static void method(T localVar) {} // not possible
    }
  • new 키워드를 사용하여 객체 생성을 할 수 없다. - 안전성

    1
    2
    3
    public class Generic<T> {
    T var = new T(); // not possible
    }
  • instanceof의 피연산자로 사용할 수 없다. - 안전성

    1
    2
    3
    4
    5
    6
    7
    8
    public class Generic<T> {
    {
    Object obj = new Object();
    if(obj instanceof T) { // not possible
    ...
    }
    }
    }

제네릭 타입의 상속

  • 부모 클래스 또는 인터페이스에 선언한 타입 파라미터는 반드시 자식에서도 선언

  • 자식 클래스에서 추가적인 타입 파라미터 선언할 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Foo<T> {
    ...
    }

    interface IBar<D> {
    ...
    }

    class FooBar<C, T, D> extends Foo<T> implements IBar<D> {
    ...
    }

파라미터 타입의 제한

  • extends를 이용하여 파라미터 타입을 제한할 수 있다.

    • 인터페이스의 경우에도 extends 키워드를 사용한다.
    • 클래스와 인터페이스를 동시에 제약하려면 &로 연결한다.
  • 제한한 자료형의 자식 클래스는 모두 사용할 수 있다.

    1
    2
    3
    4
    5
    6
    7
    class Generic<T extends Number> {
    ...
    }

    class Generic<T extends Number & Cloneable> {
    ...
    }

제네릭 메소드

메소드에 선언된 제네릭

  • 메소드의 리턴 타입 앞에 타입 파라미터 변수를 선언하여 사용

    1
    2
    3
    4
    5
    class GenericMethod {
    public <T> T method(T x) {
    return x;
    }
    }
  • 메소드에 선언된 제네릭은 정적 메소드에도 사용 가능

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class GenericMethod<T> {
    public static void method(T t) { // Error
    ...
    }

    public static <P> P method (P p) { // Possible
    ...
    }

    public static <P, V> V methodA(P p){
    // Error : V Type Not Definition
    ...
    }
    }
  • 와일드카드

    • <?> => <? extends Object>와 동일
    • <? extends T> => 와일드카드의 상한을 제한, T 포함 상속 클래스
    • <? super T> => 와일드카드의 하한을 제한, T 포함 상위 클래스
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class Foo {
    ...
    }

    class Bar extends Foo {
    ...
    }

    class Generic<T> {
    ...
    }

    class WildCard {
    public void method1(Generic<?> x) {}
    public void method2(Generic<? extends Foo> x) {}
    public void method3(Generic<? super Bar> x) {}
    }

Comment and share

열거형 (Enumeration)

열거형이란

  • 몇가지 한정된 상수로 표현될 수 있는 자료형을 구현
  • enum 키워드를 이용하며, 내부적으로는 java.lang.Enum 클래스를 상속

열거형의 특징

  • 접근 제한자는 publicdefault만 사용 가능
  • 다른 클래스를 상속받을 수 없으나, 인터페이스 구현은 가능
  • 열거형 타입에는 열거형 상수와 null 값을 할당할 수 있음

열거형의 구현

  • 일반적인 열거형의 구현

    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
    enum Job {
    STUDENT, MARKETING, DEVELOPER, CHIEF_EXECUTIONAL_OFFICER;
    }

    public class Main {
    public static void main(String[] args) {
    Job job = Job.STUDENT;

    if (job == Job.CHIEF_EXECUTIONAL_OFFICER) {
    System.out.println("사장님, 안녕하세요?");
    }

    switch (job) {
    case STUDENT: // case에서는 'Job.' 을 쓰지 않는다.
    System.out.println("You will be a great one.");
    break;
    case MARKETING:
    System.out.println("You make things sold.");
    break;
    case DEVELOPER:
    System.out.println("You usually don't go home.");
    break;
    case CHIEF_EXECUTIONAL_OFFICER:
    System.out.println("You choose your company's fate.");
    break;
    default:
    System.out.println("I don't recognize what you do.");
    }
    }
    }
  • 클래스 내부에서 열거형 구현

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Foo {
    enum MyEnum {
    ONE, TWO;
    }
    }

    public class Main {
    public static void main(String[] args) {
    System.out.println(Foo.MyEnum.ONE);
    }
    }
  • 열거형에 메소드 구현

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    enum Symbol {
    ONE, TWO, THREE, FOUR;

    public Symbol nextSymbol() {
    if(this.equals(ONE)) {
    return TWO;
    } else if(this.equals(TWO)) {
    return THREE;
    } else if(this.equals(THREE)) {
    return FOUR;
    } else {
    return ONE;
    }
    }
    }

    public class Main {
    public static void main(String[] args) {
    Symbol sym = Symbol.ONE; // ONE
    Symbol nextSym = sym.nextSymbol(); // TWO
    nextSym = nextSym.nextSymbol(); // THREE
    }
    }

  • 열거형 생성자를 이용한 enum 상수 초기화

    • 열거형의 생성자는 항상 private이며 생략 가능
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    enum Family {
    FATHER("아버지"), MOTHER("어머니"), SON("아들"), DAUGHTER("딸"); // 생성자 호출
    private String koreanWord;

    Family(String koreanWord) { // private 생성자
    this.koreanWord = koreanWord;
    }

    public String getKoreanWord() {
    return koreanWord;
    }

    public void setKoreanWord(String koreanWord) {
    this.koreanWord = koreanWord;
    }
    }

    public class Main {
    public static void main(String[] args) {
    Family fam = Family.SON;
    System.out.println(fam.koreanWord) // 아들
    }
    }

Comment and share

인터페이스 (Interface)

인터페이스란

  • 클래스를 사용하는 방식, 접점만을 선언하는 클래스와 유사한 틀
  • 아무런 구현이 되어 있지 않으며, 모든 메소드가 추상 메소드

인터페이스의 특징

  • class가 아닌 interface 키워드로 선언

    • public 또는 default 접근 제어자만 사용 가능
  • 멤버 변수는 항상 public static final이며, 생략 가능

  • 멤버 메소드는 항상 public abstract이며, 생략 가능

  • 클래스와 달리 인터페이스는 여러 개 상속받을 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public interface IFoo {
    public static final int MEMBER_VAR = 10;
    int MEMBER_VAR2 = 20; // public static final

    public abstract void methodA(int param);
    void methodB(int param); // public abstract
    }

    public class Foo implements IFoo {
    @Override
    void methodA(int param) {
    System.out.println(param);
    }

    @Override
    void methodB(int param) {
    System.out.println(param);
    }
    }

인터페이스간의 상속

  • 인터페이스 간의 ‘IS-A’ 관계

  • 인터페이스가 인터페이스를 상속할 경우 extends로 상속

  • 클래스-클래스와 달리 다중 상속 가능

    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
    interface Walkable {
    void walk();
    }

    interface Runnable {
    void run();
    }

    public interface Jumpable extends Walkable, Runnable {
    void jump();
    }

    public class Jumper implements Jumpable {
    @Override
    void walk() {
    System.out.println("walk");
    }

    @Override
    void run() {
    System.out.println("run");
    }

    @Override
    void jump() {
    System.out.println("jump");
    }
    }

JDK 1.8

  • 기본 메소드 (Default method): 자식 클래스에서 구현할 필요가 없는 메소드

    • 인터페이스에 default 메소드를 구현할 수 있다.
    • default 메소드는 항상 public이다.
    • 인터페이스의 철학과 맞지 않으나, 인터페이스가 개선되었을 때 손쉽게 기능 추가를 위해 만들어짐
    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
    32
    33
    34
    35
    interface IFoo {
    void abstractMethod();

    default void defaultMethod() { // 구현 클래스에서 구현할 필요가 없다.
    System.out.println("Default method");
    }
    }

    class SuperFoo {
    void defaultMethod() {
    System.out.println("Super method");
    }
    }

    class FooOne implements IFoo {
    void abstractMethod() {
    return;
    }
    }

    class FooTwo extends SuperFoo implements IFoo {
    void abstractMethod() {
    return;
    }
    }

    public class Main {
    public static void main(String[] args) {
    FooOne fooOne = new FooOne();
    fooOne.defaultMethod(); // Default method

    FooTwo fooTwo = new FooTwo();
    fooTwo.defaultMethod(); // Super method
    }
    }
  • static 메소드: 클래스 메소드와 동일하게 사용 가능

    • 인터페이스 이름으로 호출 가능
    • 클래스 구현체의 이름으로도 호출 가능
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    interface IFoo {
    static void staticMethod() {
    System.out.println("static method");
    }
    }

    public class Main {
    public static void main(String[] args) {
    IFoo.staticMethod(); // static method
    }
    }

Comment and share

추상 클래스 (Abstract Class)

추상 클래스란

  • 일부 메소드가 구현되지 않고 선언만 되어 있는 클래스
    • 자식 클래스에서 반드시 구현해야 하는 메소드를 abstract로 선언
    • 필요한 모든 클래스가 구현될 수 있도록 강제

추상 클래스의 선언

  • abstract 키워드를 이용해 클래스를 선언

  • abstract 키워드를 이용해 메소드를 선언

    1
    2
    3
    4
    5
    6
    7
    abstract class AbstractFoo {
    public void method() {
    return;
    }

    public abstract void abstractMethod();
    }

Comment and share

OOP-7(Polymorphism)

in Java, OOP

다형성 (Polymorphism)

다형성의 다양한 특징

  • 부모 클래스 타입으로 자식 클래스 객체를 참조하는 특징

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public class Foo {
    public void methodA() {
    return;
    }
    }

    public class Bar extends Foo {
    public void methodB() {
    return;
    }
    }

    public class Main {
    public static void main(String args[]) {
    Bar bar = new Bar();

    Foo foo = (Foo)bar;
    }
    }
  • 부모 클래스로 자식 클래스를 참조한 경우, 자식 클래스의 메소드는 사용할 수 없다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class Main {
    public static void main(String args[]) {
    Bar bar = new Bar();
    Foo foo = (Foo)bar;

    foo.methodA(); // works
    // foo.methodB(); // error
    }
    }
  • 자식 클래스로 부모 클래스를 참조하려 하면 java.lan.ClassCastException 오류 발생

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Main {
    public static void main(String args[]) {
    Foo foo = new Foo();
    Bar bar;

    // bar = (Bar)foo; // error
    if (foo instanceof Bar) { // returns false
    bar = (Bar)foo;
    }
    }
    }
  • 멤버 변수 재정의는 선언된 객체의 타입을 따른다.

  • 메소드 오버라이딩은 메모리상의 객체의 타입을 따른다. (가상 메소드 호출; Virtual method call)

    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
    public class Foo {
    public String x = "Super";

    public void methodA() {
    System.out.println("Super");
    }
    }

    public class Bar extends Foo {
    public String x = "Sub";

    @Override
    public void methodA() {
    System.out.println("Sub");
    return;
    }
    }

    public class Main {
    public static void main(String args[]) {
    Bar bar = new Bar();
    Foo foo = (Foo)bar;

    System.out.println(bar.x); // Sub
    bar.methodA(); // Sub

    System.out.println(foo.x); // Super
    foo.methodA(); // Sub
    }
    }
  • 공변 반환 타입 (Covariant return type)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Foo {
    public Foo getInstance() {
    return this;
    }
    }

    class Bar extends Foo {
    public Bar getInstance() { // Foo 대신 Bar로 리턴 가능
    return this;
    }
    }

Comment and share

OOP-6(Modifier)

in Java, OOP

제어자 (Modifier)

제어자란

  • 클래스, 변수, 메소드에 부가 기능을 부여하는 키워드
  • 접근 제어자 (Access modifiers)
    • 접근할 수 있는 범위를 정하는 키워드
    • public, protected, (default = package), private
  • 그 외 제어자 (Other modifiers)
    • 특별한 기능을 부여하는 제어자
    • static, final, abstract, synchronized

제어자의 기능

접근 제어자

  • 접근 가능한 범위를 정해, 데이터 은닉/보호 (Encapsulation) 기능을 추가한다.

  • 접근 제어자별 접근 범위

    제어자 같은 클래스 같은 패키지 다른 패키지에 속한 자식 클래스 전체
    public O O O O
    protected O O O
    default O O
    private O
  • private 또는 protected 변수에 접근하기 위해 getter와 setter 사용

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    class public Foo {
    private int x = 0;
    private int y = 1;

    public void setX(int x) { // setter
    this.x = x;
    }

    public void setY(int y) { // setter
    if (y >= 0) {
    this.y = y;
    }
    }

    public int getX() { // getter
    return x;
    }

    public int getY() { // getter
    return y;
    }
    }

그 외의 제어자

  • final

    • 더 이상 바뀔 수 없음을 의미

    • 클래스, 메소드, 변수에 사용할 수 있음

      • 클래스: 더 이상 상속이 불가능해진다.

      • 메소드: 자식 클래스에서 오버라이드할 수 없다.

      • 변수: 변수의 값이 초기화 이후에 변하지 않는다.

        • 생성자에서 초기화가 이루어지는 것을 blank final 변수라 한다.
        1
        2
        3
        4
        5
        6
        7
        8
        9
        public class Foo {
        final int x = 0; // final variable
        final int y; // blank finial variable

        public Foo(int y) {
        this.y = y; // blank final variable initialization
        }

        }
  • static

    • 클래스 변수, 클래스 메소드 등을 선언하기 위해 사용
  • abstract

    • 추상 클래스에서 사용
  • synchronized

    • 동시성 프로그래밍에 사용

싱글톤 패턴 (Singletone)

  • 객체가 단 하나만 존재할 수 있는 클래스

  • private 생성자를 이용한다.

    1
    2
    3
    4
    5
    6
    7
    8
    class SingletonClass {
    private static SingletoneClass instance = new SingletonClass();
    private SingletonClass() {}

    public static SingletonClass getInstance() {
    return instance;
    }
    }

Comment and share

OOP-5(Package)

in Java, OOP

패키지와 임포트 (Packages and Imports)

패키지 (Packages)

  • Java에서 소스 코드를 관리하는 방식
  • 물리적으로 디렉토리로 구분된 파일을 .으로 계층적으로 구분
  • 패키지 이름을 짓는 규칙: package 소속.프로젝트.용도
    ex) package com.google.dev.utils
    ex) package com.fastcampus.catcare.service

임포트 (Imports)

  • 다른 패키지에 선언된 클래스를 사용하기 위한 키워드

  • 패키지에 속한 모든 클래스를 import (하위 패키지는 포함하지 않음)

    1
    import com.example.project.utils.*;
  • 패키지에 속한 특정 클래스를 import

    1
    2
    import com.fastcampus.dogcare.service.WebAPI;
    import java.io.InputStream;
  • 클래스의 이름이 겹치는 경우, 패키지명을 포함하여 사용

    1
    2
    3
    4
    5
    6
    7
    8
    import java.util.List;

    public class Foo {
    public static void main(String args[]) {
    List list = new List();
    java.awt.List list2 = new java.awt.List();
    }
    }
  • static 멤버는 static import하여 클래스를 생략하고 사용 가능

    1
    2
    3
    4
    5
    6
    7
    8
    9
    import static java.lang.Math.random;
    import static java.lang.System.out;

    public class StaticImport {
    public static void main(String args[]) {
    out.println(random());
    }
    }

Comment and share

OOP-4(Inheritance)

in Java, OOP

상속 (Inheritence)

상속이란

  • 클래스의 모든 멤버 변수 및 메소드를 계승하여 새로운 클래스를 생성하는 것
  • 상속 대상 - 조상 클래스, 부모 클래스, 상위 클래스, 슈퍼 클래스
  • 상속 결과 - 자손 클래스, 자식 클래스, 하위 클래스, 서브 클래스
  • 상속 대상일 필요 조건을 달성하므로 IS-A 관계라고도 부른다.

클래스의 관계

클래스의 상속

  • 부모 클래스

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Person {
    String name;

    public void work() {
    System.out.println("일하기");
    }

    public void sleep() {
    System.out.println("잠자기");
    }
    }
  • 자식 클래스

    1
    2
    3
    4
    5
    6
    7
    public class Developer extends Person {
    String mainLang;

    public void writeCode() {
    System.out.println("코딩하기");
    }
    }
    1
    2
    3
    4
    5
    6
    7
    public class Student extends Person {
    String major;

    public void writeCode() {
    System.out.println("밤새 코딩하기");
    }
    }

클래스의 포함

  • 상속과 유사하나, 한 클래스가 다른 클래스의 인스턴스를 포함하는 관계로 되어 있다.

  • 내부에 포함하고 있어, HAS-A 관계라고 부른다.

  • 클래스 컴포지션 (Composition)이라 부른다.

    1
    2
    3
    4
    5
    6
    7
    public class MainMachine {
    String model;

    public MainMachine(String model) {
    this.model = model;
    }
    }
    1
    2
    3
    4
    5
    6
    7
    public class Developer extends Person {
    MainMachine machine = new MainMachine("Macbook Air");

    public void writeCode() {
    System.out.println(machine.model + "(으)로 코딩하기");
    }
    }

메소드 재정의

  • 메소드의 기능을 재정의하는 것을 메소드 재정의 (Method overriding)이라 부른다.

    1
    2
    3
    4
    5
    public class Person {
    public void writeCode() {
    System.out.println("아무 코드나 일단 적어보았다.");
    }
    }
    1
    2
    3
    4
    5
    6
    public class Developer extends Person {
    @Override
    public void writeCode() {
    System.out.println("깔끔하고 예쁜 코드를 적어보았다.");
    }
    }

super 키워드

  • this가 현재 객체를 참조하듯, super는 부모 객체를 참조한다.

  • super로 부모의 부모 객체에는 접근할 수 없다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class Foo {
    String x = "foo";
    }

    public class Bar extends Foo{
    String x = "bar";

    void method() {
    String x = "method";
    System.out.println(x);
    System.out.println(this.x);
    System.out.println(super.x);
    }
    }
  • 부모의 생성자를 호출하는 super

  • 반드시 생성자의 첫줄에만 올 수 있음

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public class Foo {
    String x;

    public Foo(String x) {
    this.x = x;
    }
    }

    public class Bar extends Foo {
    String y;

    public Bar(String x, String y) {
    super(x);
    this.y = y;
    }
    }

Comment and share

OOP-3(JavaDoc)

in Java, OOP

JavaDoc 주석

JavaDoc 주석이란

  • Java 클래스 및 패키지를 문서화 하기 위한 주석
  • 클래스의 용도와 사용법 등을 설명하는 규칙
  • 자동으로 JavaDoc 문서를 생성할 수 있음

JavaDoc 작성 방법

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
32
33
34
/**
* Class description
* @author Author Name
*/
public class ClassA {
/**
* Comments for a member variable
*/
public int memberVar;

/**
* Comments for another member variable
*/
public int secondMemberVar;

/**
* Constructor description
* @param x description for parameter x
* @param y description for parameter y
*/
public ClassA(int x, int y) {
this.memberVar = x;
this.secondMemberVar = y;
}

/**
* A member method description
* @param string description for parameter string
* @return description for the return value
*/
public int ClassA(String string) {
return 0;
}
}

Comment and share

OOP-2(Class)

in Java, OOP

클래스 (Classes)

클래스와 객체

  • 클래스: 객체를 생성하기 위해 사용하는 추상화된 설계도
  • 객체: 클래스가 구체화하여 값으로 생성된 것
    • Instantiation: 클래스에서 객체를 생성하는 과정
    • Object, Instance: Instantiation으로 인해 생성된 객체

클래스의 구성

1
2
3
4
5
6
7
public class Car {
int speed = 0; // 멤버 변수 (속성)

void move() { // 멤버 함수 (메소드)
this.speed = 10;
}
}
  • 속성(Attribute, field) - 클래스에 속하는 멤버 변수, 상태, 필드
  • 메소드(Method) - 클래스에 속하는 멤버 함수, 행동

객체의 생성

1
2
Car car = new Car();
클래스명 변수명 = new 클래스명();
  • 클래스를 구체화하여 값을 생성한 것을 객체라 한다.
  • 하나의 클래스로 여러개의 객체를 만들 경우, 같은 타입의 독립적인 객체가 된다.

클래스와 객체의 메모리 구조

  • 클래스 영역 (Class Area, Method Area, Code Area, Static Area)

    • Field 정보
    • Method 정보
    • Type 정보
    • Constant Pool
  • 스택 영역 (Stack Area)

    • Method 호출 시 선언된 로컬 변수
  • 힙 영역 (Heap Area)

    • new 키워드로 생성된 객체

변수 (Variables)

  • 로컬 변수와 멤버 변수

    구분 선언 위치 변수 종류 특징
    멤버 변수 클래스 영역 클래스 멤버 변수 static 키워드 o
    멤버 변수 클래스 영역 인스턴스 멤버 변수 static 키워드 x
    로컬 변수 메소드 및 블록 내부 로컬 변수
    로컬 변수 메소드 내부 파라미터 변수 메소드의 입력 인자
    1
    2
    3
    4
    5
    6
    7
    8
    public class Variables {
    int instanceVar; // 인스턴스 멤버 변수
    static int classVar; // 클래스 멤버 변수

    public void method(int parameterVar) { // 파라미터 변수
    int localVar = 0; // 로컬 변수
    }
    }

인스턴스 멤버 변수 (Instance Variables)

  • 인스턴스 변수는 객체를 생성할 때 힙 영역에 생성됨

  • 인스턴스 변수는 힙 영역에 생성되므로 초기화가 이루어짐

    자료형 기본값
    boolean false
    char ‘\u0000’
    byte, short, int 0
    long 0L
    float 0.0f
    double 0.0
    Ref. type null

클래스 멤버 변수 (Class Variables)

  • 클래스 멤버 변수는 프로그램 시작 시 클래스 영역에 생성됨

  • 객체가 아닌 클래스로 접근하는 것이 권장됨 (객체로 접근도 가능하나 비권장)

    1
    2
    3
    4
    5
    6
    7
    8
    public class Foo {
    static int classVar = 10;
    }

    Foo.classVar = 0; // Recommended

    Foo foo = new Foo();
    foo.classVar = 0; // Not recommended

로컬 변수 (Local Variable)

  • 메소드 또는 중괄호 블록 내부에서 생성되는 변수

  • 스택 영역에 생성되며, 초기화가 이루어지지 않음

  • 생명 주기(Life cycle)은 생성된 중괄호 블록이 종료될 때 까지

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void method(int paramVar) {
    int localVar;
    // System.out.println(localVar); // 초기화가 이루어지지 않음
    localVar = 10;
    System.out.println(localVar);
    {
    int localVar2 = 10;
    System.out.println(localVar2);
    }
    // System.out.println(localVar2); // 생명주기가 끝남
    }

메소드 (Methods)

메소드란

  • 객체가 하는 동작을 정의하는 어떠한 작업을 수행하는 코드의 집합
  • 코드의 중복을 방지하고 유지보수성을 향상시키기 위해 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Car {
String name;

void printModel() { // 메소드의 정의 (Method definition)
System.out.println(name);
}
}

Car hyundai = new Car();
Car kia = new Car();

hyundai.name = "Hyundai";
kia.name = "Kia";

hyundai.printModel(); // 메소드의 호출 (Method call)
kia.printModel();

메소드의 구현

  • 메소드는 함수의 형태로 구성된다.

    • 파라미터 (Parameters, 입력)
    • 실행문 (Executional Statements)
    • 리턴 값 (Return Value, 출력)
  • 함수의 작성

    1
    2
    3
    4
    5
    6
    7
    public int add(int x, int y) {
    return x + y;
    }

    제한자 리턴타입 메소드명(파라미터타입1 파라미터이름1, 파라미터타입2 파라미터이름2, ...) {
    // 실행문
    }
  • 가변 인자 (Variable Arguments)

    • 입력 인자의 개수가 정해지지 않은 경우
    1
    2
    3
    4
    5
    6
    7
    public int sumAll(int... params) {
    int sum = 0;
    for (int i: params) {
    sum += i;
    }
    return sum;
    }
  • 기본형 vs. 참조형 변수

    • 기본형: 메소드 인자로 값이 전달됨 (Call by value)
    • 참조형: 메소드 인자로 참조가 전달됨 (Call by reference)
    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
    public class Foo {
    int value;
    }

    public class Bar {
    public void swapPrimitive(int x, int y) {
    int temp = x;
    x = y;
    y = temp;
    }

    public void swapReference(Foo x, Foo y) {
    int temp = x.value;
    x.value = y.value;
    y.value = temp;
    }
    }

    Bar bar = new Bar();

    int x = 1, y = 10;
    bar.swapPrimitive(x, y);
    System.out.println(x); // 1
    System.out.println(y); // 10

    Foo foo1 = new Foo(1);
    Foo foo2 = new Foo(10);
    bar.swapReference(foo1, foo2);
    System.out.println(foo1.value); // 10
    System.out.println(foo2.value); // 1
  • 클래스 메소드 (Class method)

    • static 키워드를 이용하여 선언된 메소드
    • 인스턴스가 아닌 클래스에 속하는 메소드
    • 대표적으로 main 메소드가 클래스 메소드이다.
    1
    2
    3
    4
    5
      public class Foo {
    static public void main(String args[]) {
    // class method
    }
    }
  • 메소드 호출 스택 (Method Call Stack)

    • 메소드가 호출될 때 마다 메소드 동작과 로컬 변수가 쌓이는 메모리 영역
    • 메소드가 종료될 때 메모리가 함께 반환됨

메소드 오버로딩

  • 동일 기능의 함수를 추가로 구현하는 방법

  • 입력 파라미터를 달리하는 동일 함수명으로 구현한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public class Foo {
    public int sumAll(int ... params) {
    int sum = 0;
    for (int i: params) {
    sum += i;
    }
    return sum;
    }

    public float sumAll(float ... params) {
    float sum = 0.0f;
    for (float x: params) {
    sum += x;
    }
    return sum;
    }
    }

    Foo foo = Foo();
    int sum1 = foo.sumAll(1, 2, 3, 4, 5);
    float sum2 = foo.sumAll(1.0f, 2.0f, 3.0f, 4.0f, 5.0f);

생성자 (Constructor)

  • 클래스에서 인스턴스를 생성할 때 사용되는 메소드

    • new 키워드를 이용해 호출
  • 기본 생성자 (Default Constructor)

    • 구현하지 않아도 자동으로 생성되는 생성자
    • 아무런 동작도 하지 않고, 객체만을 생성
  • 파라미터 생성자 (Parameter Constructors)

    • 입력 파라미터를 받는 생성자
    • 여러개의 파라미터 생성자를 오버로딩할 수 있음
    • 보통 멤버 변수를 초기화하는 동작 수행
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Foo {
int x;
int y;
String z;

// public Foo() {} // Default Constructor

public Foo(int a, int b, String c) { // Parameter Constructor
x = a;
y = b
z = c;
}
}

this 키워드

  • 객체가 스스로를 가르키는 참조

  • 멤버 변수와 로컬 변수의 이름이 같을 때, 멤버 변수임을 명시

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class Foo {
    int x;
    int y;

    public Foo(int x, int y) {
    this.x = x;
    this.y = y;
    }
    }
  • 생성자를 호출하는 데에도 사용할 수 있다.

  • 반드시 생성자의 첫 줄에서만 사용해야 한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public class Foo {
    int x;
    int y;
    String z;

    public Foo(int x, int y, String z) {
    this.x = x;
    this.y = y;
    this.z = z;
    }

    public Foo(String z) {
    this(0, 0, z);
    }

    public Foo(int x, int y) {
    this(x, y, "Nothing");
    }
    }

Getter와 Setter

  • 클래스의 멤버 변수를 간접적으로 다룰 수 있게 하는 메소드

  • 멤버 변수의 캡슐화(Encapsulation)를 구현하기 위해 사용

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Foo {
    private int x;

    public int setX(int x) {
    this.x = x;
    }

    public void getX() {
    return x;
    }
    }

초기화 블록 (Initializer)

  • 클래스 또는 인스턴스를 생성할 때 단 한번 실행되는 코드 블록

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public class Foo {
    static int classVar;
    int instanceVar;

    static { // Class Initializater
    classVar = 100;
    }

    { // Instance Initializer
    instanceVar = 10;
    }

    static {
    // May be more than one block
    }
    }

Comment and share

Yechan Kim

author.bio


author.job