1. Enum

enum Direction {
    EAST(1),
	SOUTH(2),
	WEST(3),
	NORTH(4);

	private final int value;
	private Direction(int value) { this.value = value }
}


TO

1. Class

class Direction {
    static final Direction EAST = new Direction(“EAST”);
	static final Direction SOUTH = new Direction(“SOUTH”);
	static final Direction WEST = new Direction(“WEST”);
	static final Direction NORTH = new Direction(“NORTH”);

	private final String name;

	private Direction(String name) {
		this.name = name;
	}
}

2. Extends Enum

class MyEnum<? extends MyEnum<T>> implements Comparable<T> {
    static in id = 0;

	int ordinal;
	String name = “”;

	public int ordinal() { return ordinal; }

	MyEnum(String name) {
		this.name = name;
		ordinal = id++;
	}

	public int compareTo(T t) {
		// t.ordinal()은 MyEnum<? extends MyEnum<T>> 때문에 에러 없이 사용가능하다.
		// MyEnum<T> 였다면 T에 ordinal()이 있는지 확인이 되지 않아 에러가 발생했을 것이다.
		return ordinal - t.ordinal();
	}
}

3. Enum Abstract Method

3.1 Enum EX)

enum Direction {
    EAST(1) {
        Point move(Point p) { … }
    },
    SOUTH(2) {
        Point move(Point p) { … }
	},
    WEST(3) {
        Point move(Point p) { … }
    },
    NORTH(4) {
        Point move(Point p) { … }
    };
	
    // protected인 이유는 추상 메서드를 구현하는 상수에서 접근 하기 위함이다.
    protected final int value;
	
    Direction(int value) { this.value = value }
	
    abstract Point move(Point p);
}

3.2 Class EX)

abstract class Direction extends MyEnum {
    // 추상 클래스인 Direction을 생성하였기에 익명 클래스 형태로 추상 메서드인 move구현
    static final Direction EAST = new Direction(“EAST”) {
        Point move(Point p) { … }
    }

    // 추상 클래스인 Direction을 생성하였기에 익명 클래스 형태로 추상 메서드인 move구현
    static final Direction SOUTH = new Direction(“SOUTH”) {
        Point move(Point p) { … }
    }

    // 추상 클래스인 Direction을 생성하였기에 익명 클래스 형태로 추상 메서드인 move구현
    static final Direction WEST = new Direction(“WEST”) {
        Point move(Point p) { … }
    }

    // 추상 클래스인 Direction을 생성하였기에 익명 클래스 형태로 추상 메서드인 move구현
    static final Direction NORTH = new Direction(“NORTH”) {
        Point move(Point p) { … }
    }

    private String name;
    private Direction(String name) { this.name = name }

    // Direction의 추상 메서드 move 선언
    abstract Point move(Point p);
}

'개발 언어 > Java' 카테고리의 다른 글

[Java] Double Underscore  (0) 2021.10.22
[Java] 예외 처리  (0) 2021.08.27
[Java] 내부 클래스  (0) 2021.08.27
[Java] 인터페이스  (0) 2021.08.27
[Java] 추상 클래스&추상 메서드  (0) 2021.08.26

1. 예외 처리 (exception handling)

예외처리란?

프로그램이 실행 도중 발생하면 비정상적으로 프로그램이 종료되지만 발생할 수 있는 상황을 미리 예측하여 처리하는 것을 말한다. 예외 처리의 목적은 프로그램의 비정상 종료를 막고, 정상적인 실행상태를 유지하기 위함이다.

발생하는 예외를 처리하지 못하면 JVM의 예외 처리기가 받아서 예외를 화면에 출력한다.

 

* 프로그램의 오류

  • 컴파일 에러 : 컴파일 과정 중 발생하는 에러
  • 런타임 에러 : 프로그램 실행 도중 발생하는 에러
  • 논리적 에러 : 실행은 되지만 의도와 다르게 동작하는 에러

컴파일러가 잘못된 구문들을 체크하여 컴파일 후 class 파일이 생성된다. 하지만 실행 도중 발생하는 잠재적 에러는 파악할 수 없다.

 

* 런타임 에러의 종류

  1. 에러 : OutOfMemory, StackOverFlow 등 발생하면 복구할 수 없는 심각한 상태를 말하며 프로그램 코드에 의해 수습될 수 없는 심각한 오류이다.
  2. 예외 : 발생하더라도 수습이 가능한 상태이며 프로그램 코드에 의해 수습될 수 있는 다소 미약한 오류이다.

2. 예외 클래스의 계층 구조

상속 계층도

예외 클래스를 나누면 Exception class와 RuntimeException class 두 가지로 나눌 수 있다.

  • RuntimeException 하위 클래스들은 프로그래머의 실수로 발생하는 예외이다. (uncheckd 예외)
    ex)
    IndexOutOfBoundException
    NullPointerException
    ClassCastException
    ArithmeticException
  • Exception 하위 클래스들은 사용자의 실수로 발생하는 예외이다. (checkd 예외)
    ex)
    FileNotFoundException
    ClassNotFoundException
    DataFormatException

3. 예외 처리하기 - try - catch문

public class Sample {
    public int getAge() {
        try {
            // 예외가 발생할 가능성이 있는 코드
        } catch(ArithmeticException e1) {
            // ArithmeticException이 발생할 경우 실행되는 코드
        } catch(IOException e2) {
            // IOException이 발생할 경우 실행되는 코드
        }
    }
}

try 다음에 여러 종류의 catch 블록이 올 수 있으며 해당 예외 발생 시 발생한 예외의 catch 문이 실행된다. catch에 없는 예외 발생 시 예외가 처리되지 않는다.

try - catch문은 실행 코드가 한 줄 이어도 중괄호 생략 불가능하다.

try - catch문안에 또 다른 try - catch 문이 올 수 있으며 같은 레벨에 여러 try - catch문이 올 수 있다.

4. try - catch 문에서의 흐름

* 실행 순서

try 블록 내에서 예외가 발생한 경우

  1. 발생한 예외와 일치하는 catch 블록이 있는지 확인
  2. 일치하는 catch 문을 찾았다면
     - 해당 catch문을 실행하고 try - catch문을 빠져나간다.
    일치하는 catch문을 못 찾았다면 예외 처리되지 않는다.

try 블록 내에서 예외가 발생하지 않는 경우

  1. catch 문을 거치지 않고 try - catch 문을 빠져나간다.

try 안에서 예외가 발생할 때 발생한 라인 이하의 코드는 실행되지 않고 catch문으로 빠져나간다.

5. 예외의 발생과 catch 블록

catch문은 괄호와 블록으로 나뉜다.

괄호에는 예외 처리할 예외 타입의 참조 변수를 정의한다.

try {
    ...
} catch (ArithmeticException e) {
    ...
}

첫 번째 catch부터 마지막 catch까지 예외 인스턴스와 catch의 참조 변수 종류를 instanceof 연산자를 이용해 검사하고 검사 결과 true인 catch 블록을 만날 때까지 검사한다.

catch문에 'Exception'을 지정하면 모든 예외가 잡힌다. 그 이유는 모든 예외가 Exception의 자식이기 때문이다.

try {
    ...
} catch (ArithmeticException e) {
    ...
} catch (Exception e) {
    ...
}

위의 예제의 경우 두 번째 catch는 ArithMeticException을 제외한 나머지 Exception을 처리한다.

반대로 첫 번째에 Exception e를 선언하면 모든 예외는 첫 번째 catch문에서만 실행된다.

5.1. printStackTrace()와 getMessage()

printStackTrace와 getMessage는 catch의 참조 변수를 통해 많이 사용되는 함수이다.

  • printStackTrace() : 예외 발생 당시에 호출 스택에 있었던 메서드의 정보와 예외 메시지를 화면에 출력하는 함수이다.
  • getMessage() : 발생한 예외 클래스의 인스턴스에 저장된 메시지를 얻을 수 있는 함수이다.
try {
    ...
} catch (ArithmeticException e) {
    e.printStackTrace();
    e.getMessage();
}

* 예외 정보를 파일로 저장할 수 있는 printStackTrace(PrintStream p), printStackTrace(PrintWriter p)가 있다.

5.2. 멀티 catch 블록

try {}
catch (Exception1 e1) {}
catch (Exception2 e2) {}
catch (Exception3 e3) {}


catch (Exception1 | Exception2 | Exception3 e) {}

파이프 ( | )를 이용 시 클래스가 상위, 하위 관계에 있다면 컴파일 에러가 발생한다. 그 이유는 상위 클래스만 넣어도 예외 처리가 잡히기 때문이다.멀티 catch 블록을 사용 시 어떤 예외로 들어왔는지 모르기 때문에 예외 클래스들의 공통분모인 상위 멤버만 사용 가능하다. 또한 instanceof를 이용하여 예외처리해도 된다.

catch (Exception1 | Exception2 e) {
    if(e instanceof Exception1) {
        ...
    } else if(e instanceof Exception2) {
        ...
    }
}

멀티 catch 블록의 참조 변수는 상수이다.

6. 예외 발생시키기

'new' 연산자를 이용해 발생시키고자 하는 예외 클래스를 객체로 만든 후 throw 키워드로 예외를 발생시킨다.

Exception e = new Exception("고의");

throw e;

// or 

throw new Exception("고의");

7. 메서드에 예외 선언하기

메서드 선언부에 'throws' 키워드로 예외 클래스를 선언한다. 예외가 여러 개일 경우 ', '(쉼표)로 구분하여 선언한다.

public void method throws IOException, ArithmeticException {}

* 주의) throw와 throws 구분 필요

반드시 처리해야 하는 예외만 처리하고 보통 RuntimeException은 처리하지 않는다.

throws는 예외 처리를 하는 것이 아닌 어떤 예외가 발생할 수 있는지 전달해주는 것이다.

메서드를 호출 한 곳에서 에러 처리를 할 것인지 호출된 메서드에서 에러 처리를 할 것인지 정해야 한다.

// 1. 호출 한 곳에서 에러처리
main() {
    try {}
    catch (Exception e) {}   
}

// 2. 호출 된 메서드에서 에러 처리
main() {
    Sample s = new Sample();
    
    s.method();
}

public class Sample {
    public void method() {
        try {}
        catch (Exception e) {}
    }
}

8. finally 블록

try - catch와 함께 선택적으로 사용되며 예외와 관계없이 무조건 실행된다.

선언 순서는 try - catch - finally 순서이다.

try에서 메서드가 return 되어도 finally가 실행되고 메서드가 return이 된다.

try {
    return 1;
} catch (Exception e) {
    ...
} finally {
    return 0;
}

9. 자동 자원 반환 - try - with - resources문

입출력에 유용하며 열려 있는 자원을 반환할 때 사용된다.

public class CustomAutoCloseable implements AutoCloseable {
    public void close() throws Exception {
        System.out.println("닫기");
    }
}

try (CustomAutoCloseable c = new CustomAutoCloseable()) {
    ...
} ...

try에 괄호를 넣어 참조 변수를 선언할 수 있으며 AutoCloseable 인터페이스로 구현된 것만 가능하며 AutoCloseable의 close() 함수를 자동으로 실행해주어 자원을 반환할 수 있다.

10. 사용자 정의 예외 만들기

public class CustomException extends Exception {
    CustomException(String msg) {
        super(msg);
    }
}

Exception 클래스를 상속받은 하위 클래스에서 상위 클래스의 생성자를 호출하여 사용자 정의 예외 클래스를 만들 수 있으며 단순 메시지 입력뿐만 아니라 다양한 구현을 할 수 있다.

* 되도록 기존의 예외 클래스를 사용해야지 다른 사람이 봤을 때도 공통으로 예외 처리하기 편하다

11. 예외 던지기 (exception re-throwing)

main() {
    try {
        Sample s = new Sample();
        s.method();
    } catch (Exception e) {}
}

public class Sample {
    public void method() {
        try {}
        catch (Exception e) {
           throw new Exception("고의");
        }
    }
}

호출당한 쪽에서 예외를 처리하고 throw를 통해 예외를 발생시켜 main 메서드에서 예외를 한 번 더 실행시키는 것을 예외 던지기라고 한다.

주의할 점은 try - catch 문으로 예외 처리와 동시에 throws로 예외를 지정해 줘야 한다.

12. 연결된 예외 (chained exception)

A 예외가 B예외를 발생시킨다면 A를 B의 '원인 예외(cause exception)'이라 한다.

try {}
catch (IOException e1) {
    ArithmeticException ae = new ArithmeticException();
    ae.initCause(e1); // IOException을 원인 예외로 지정
    throw ae;
} catch (ArithmeticException e2) {
    ...
}

위의 예제에서 initCause(e) : 원인 예외를 e (IOException)으로 지정하였고 주로 여러 예외들을 묶어서 분류할 때 사용한다. 여러 클래스를 묶어 상위 클래스를 사용하면 상속 관계 변경, 실제 인스턴스 판단 미스 등의 이유로 인해 부담되는 이유로 사용한다.

* Exception 클래스의 상위인 Throwable에 initCause(), getCause()가 정의되어 있다.

12.1. checked 예외 -> unchecked 예외

// checked 예외
public void getName() throws SpaceException, MemoryException {
    ...
}


// unchecked 예외
public void getName() throws SpaceException {
    if(공간부족) {
        throw new SapceException("공간이 부족합니다.");
    }
    
    if(메모리 부족) {
        throw new RuntimeException(new MomoryException("메모리가 부족합니다."));
    }
}

MemoryException을 RuntimeException으로 감싸면서 checked예외가 unchecked예외로 바뀌었다. 또한 RuntimeException의 원인을 등록하는 생성자를 사용하여 원인 등록까지 해주었다.

'개발 언어 > Java' 카테고리의 다른 글

[Java] Double Underscore  (0) 2021.10.22
[Java] Enum to Class  (0) 2021.09.07
[Java] 내부 클래스  (0) 2021.08.27
[Java] 인터페이스  (0) 2021.08.27
[Java] 추상 클래스&추상 메서드  (0) 2021.08.26

1. 내부 클래스

내부 클래스란?

클래스 내에 선언되어 있는 클래스를 의미한다.

외부 클래스와 내부 클래스 간의 밀접한 관계가 있을 때 주로 사용한다.

public class Outer {
    class Inner {
        ....
    }
}

1.1. 내부 클래스의 장점

  1. 내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근 할수 있다.
  2. 서로 관련 있는 클래스를 묶어서 표현함으로써 코드의 캡슐를 증가시킨다.
  3. 외부에서 내부 클래스를 접근할 수 없음으로 코드의 복잡성을 줄일 수 있다.

2. 내부 클래스의 종류와 특징

2.1. 정적 클래스 (static class)

static 키워드를 분인 클래스로 멤버 변수 위치에 선언되며 static 멤버처럼 다루어 진다. 조로 static 메서드에서 사용한다.

2.2. 인스턴스 클래스 (instance class)

static 키워드를 붙이지 않은 클래스로 멤버 변수 위치에 선언되며 인스턴스 멤버들과 관련된 작업을 진행할 때 사용한다.

2.3. 지역 클래스 (local calss)

메서드나 초기화 블럭에서 선언된다. 지역 클래스는 선언된 블록 안에서만 사용된다.

2.4. 익명 클래스 (anonymous class)

클래스 선언과 객체의 생성을 동시에 하는 단 하나의 객체만을 생성하는 일회성 이름 없는 클래스이다. 일회성이다 보니 생성자를 구현할 수 없으며, 단 하나의 클래스, 단 하나의 인터페이스를 상속받거나 구현할 수 있을 뿐인다.

익명 클래스는 매우 제한적인 용도로 사용되며, 구현해야 하는 메서드가 적거나 변수가 적을 때 사용한다.

 

* 익명 클래스 컴파일 시 파일 명

  • Outer.class
  • Outer$1.class
  • Outer$2.class
public interface Able {}
public class Parent {}

public class Outer {
    public Able a = new Able() {
        public int a;
    }
    
    public Parent a = new Parent() {
        public int a;
    }
}

3. 내부 클래스의 선언

public class Outer {
    class InstanceInner {} // instance 클래스
    static class StaticInner {} // static 클래스
    
    void method() {
        class LocalInner {} // local 클래스
    }
}

4. 내부 클래스의 제어자와 접근성

  • final, abstract, private, protected와 같은 제어자 사용 가능하다.
  • instance, local 내부 클래스에서는 static 키워드를 사용할 수 없다.
  • 모든 내부 클래스에서 final static 키워드를 사용할 수 있다.
  • static 내부 클래스에서만 static을 사용할 수 있다.
  • static과 instance의 효과를 그대로 사용한다.
    - static은 instance 사용 불가
    - instance는 static 사용 가능
  • 인스턴스 내부 클래스를 생성하려면 외부 클래스의 인스턴스부터 생성해야 한다.

* final은 상수이기 때문에 어떤 경우라도 static이 붙는 게 가능하다.

 

Outer oc = new Outer();

oc.new InstanceInner(); // Outer 클래스 생성 후 InstanceInner 클래스 생성

* 컴파일 시 생성되는 파일 명

  • Outer.class
  • Outer$InstanceInner.class
  • Outer$StaticInner.class
  • Outer$1LocalInnter.class
  • Outer$2LocalInner.class

'개발 언어 > Java' 카테고리의 다른 글

[Java] Enum to Class  (0) 2021.09.07
[Java] 예외 처리  (0) 2021.08.27
[Java] 인터페이스  (0) 2021.08.27
[Java] 추상 클래스&추상 메서드  (0) 2021.08.26
[Java] 다형성  (0) 2021.08.25

1. 인터페이스

인터페이스란?

일종의 추상 클래스이다. 오직 추상 메서드와 상수만을 멤버로 가질 수 있으며 추상 클래스보다 추상화 정도가 높다. 추상 클래스가 "미완성 설계도"라면 인터페이슨느 "기본 설계도"이다. 인터페이스도 다른 클래스를 도우는데 목적이 있다.

클래스를 이용한 다중 상속은 어느 클래스에 해당 메서드가 있는지 모호하기 때문에 다중 상속을 지원하지 않는다.

하지만 인터페이스는 다중 상속을 지원하고 다른 클래스를 작성할때 기본 틀이 되며 클래스 사이에서 중간 매개 역할을 하는 일종의 추상 클래스이다.

2. 인터페이스의 선언

인터페이스는 class 대신 interface 키워드를 접근 제어자와 같이 사용한다.

public interface 인터페이스 이름 {
    ...
}

2.1. 인터페이스의 제약 사항

모든 멤버 변수는 public static final 이어야 하며, 생략이 가능하다.

모든 메서드는 public abstract 이어야 하며, 생략이 가능하다. 단 static 과 default 메서드는 제어

생략된 제어자는 컴파일러가 자동으로 추가한다.

3. 인터페이스의 상속 과 구현

3.1. 상속

인터페이스는 인터페이스로 부터만 상속받을 수 있다.

다중 상속, 즉 여러 개의 인터페이스를 상속받을 수 있다.

Object와 같은 최상위 클래스가 없다.

3.2. 구현

인터페이스는 인스턴스를 생성할 수 없다.

인터페이스의 몸통을 구현해주는 클래스가 필요하다.

implements 키워드를 이용하여 인터페이스를 구현한다.

public interface Able {}

public interface Aable extends Able {}
public interface Bable extends Able {}

public class Sample implements Aable, Bable {
    ...
}

Sample 클래스는 Aable, Bable 인터페이스를 구현한다 라고 표현한다.

인터페이스에 메서드 중 일부만 구현 한다면 나머지 메서드는 하위 클래스에서 abstract를 붙여 추상 클래스로 선언한다.

또한 상속과 구현을 동시에 할수 있다.

public interface Able {}
public class Parent {}

public class Child extends Parent implements Able {}

인터페이스 명은 주로 'able'로 끝나도록 작성한다.

인터페이스도 instaceof를 통해 타입을 확인할 수 있다.

if(f instanceof Aable) {}

4. 인터페이스를 이용한 다중 상속

클래스의 다중 상속이 되지 않아 A는 상속 받고 B는 멤버 변수로 사용하는데 이때 인터페이스를 이용하여 다형적 특성을 유지할 수 있다.

public class A {}
public class B {void method() {}}

public interface Bable {
    void method() {}
}

public Sample extends A implements Bable {
    B b = new B(); // 멤버 변수로 B 인스턴스 생성
    
    void method() { // interface 구체화
        b.method(); // B 클래스의 메소드 실행
    }
}

5. 인터페이스를 이용한 다형성

상속 받은 하위 클래스를 인터페이스 타입으로 형 변환이 가능하다.

// 1. 형 변환
Bable b = (Bable) new B();

// 2. 메서드의 매개변수로 인터페이스 사용가능
public void method(Bable b) {} 
method(new B()); // 인자 값으로 B 클래스 사용

// 3. return 타입으로 인터페이스 지정 가능
public Bable method() {}

// 4. Manager 클래스를 통한 다형성
public class ParseManager {
    public static Parseable getParse(String type) {
        if(type.equals("1")) {
            return new Parse1();
        } else {
            return new Parse2();
        }
    }
}

public class Parse1 implements Parseable {}
public class Parse2 implements Parseable {}

public static void main(String[] args) {
    Parseable parser = ParseManager.getParse("2");
}

Manager의 getParse 함수로 Parseable로 구현된 클래스 인스턴스를 받아서 사용할 수 있다.

6. 인터페이스의 장점

  1. 개발 시간을 단축 시킬 수 있다.
    인터페이스와 이를 구현하는 클래스를 동시에 구현 가능하며 인터페이스를 구현하는 클래스의 개발을 기다리지 않아도 된다.
  2. 표준화가 가능하다.
    표준화 된 인터페이스를 개발자들에게 전달함으로써 일관되고 정형화된 개발이 가능하다.
  3. 서로 관계 없는 클래스들에게 관계를 맺어 줄 수 있다.
    관계없는 클래스들에게 공통의 인터페이스를 구현하도록 하여 관계를 맺어 줄 수 있다.
  4. 독립적인 프로그래밍 가능하다.
    클래스와 클래스의 직접적인 관계를 인터페이스를 이용해서 간접적인 관계로 변경하면 클래스 간 서로 영향을 미치지 않아 독립적인 프래그래밍이 가능하다.
public class Marig {}
public Tank implements Repairable {}
public Scv implements Repairable {
    public int repair(Repairable r) {
        ...
    }
}

public static void main(String[] args) {
    Scv s = new Scv();
    
    s.repair(new Marin()); // Marin 클래스에 repair가 없어 에러
    s.repair(new Tank()); // 성공
}

위의 예제에서 Repariable에 아무런 멤버가 없지만 기계 유닛에 Repairable을 상속하면서 repair 메서드를 다양한 매개변수로 이용할 수 있다.

만약 4개의 클래스 중 2개의 클래스만 건물이동 메서드를 만들고 싶은 경우 각 클래스에 똑같은 메서드를 넣으면 중복이 생긴다. 그래서 인터페이스를 구현한 새로운 클래스를 각 클래스에서 멤버로 사용할 수 있다.

public class A implements Moveable {
	MoveImpl move = new MoveImpl();
}

public class B implements Moveable {
	MoveImpl move = new MoveImpl();
}

MoveImpl에서 Move메서드를 구현하여 A, B 클래스에서 호출만 하도록 한다.

7. 인터페이스의 이해

인터페이스의 이해 2가지 조건

  1. 클래스를 사용하는 쪽(User)와 제공하는 쪽(Provider)이 있다.
  2. 메서드를 사용(호출)하는 쪽(User)에서는 사용하려는 메서드(Provider)의 선언 부만 알고 내용은 몰라도 된다.

아래의 예제는 좋지 못한 예와 좋은 예이다.

// 좋지 못한 예
public class B {}
public class A {
    public void method(B b) {
        b.method();
    }
}

// 좋은 예
public interface Able {}
public class C implements Able {}
public class B implements Able {}
public class A implements Able {
    public void method(Able a) {
        a.method();
    }
}

public static void main(String[] args) {
    A a = new A();
    
    a.method(new B());
    a.method(new C());
}

좋지 못한 예의 경우 B클래스가 A클래스보다 먼저 작성되어 있어야 하고 B가 C로 변경되면 A도 변경해줘야 하는 단점이 있다.

좋은 예의 경우 A는 Able만 알고 있으면 되고 A의 method가 안에서 어떤 인스턴스의 메서드를 호출하는지 상관이 없는 장점이 있다.

8. default method와 static method

JDK 1.8부터 인터페이스에 default method와 static method를 추가할 수 있게 되었다.

Collection Interface와 Collections 클래스를 예제로 들 수 있으며 인터페이스의 static 메서드의 접근제어자는 항상 public이다.

8.1. default method

인터페이스에 변경이 생기면 인터페이스를 구현하는 모든 클래스에 변경이 생긴다. 그래서 default 메서드가 고안되었다.

default 메서드는 몸통이 있어야 하기 때문에 상속 클래스에서 변경점이 생기지 않는다. 즉, 상위 클래스에 메서드가 추가되는 것과 같다.

defulat메서드가 다른 메서드와 이름 충돌이 있을 수 있어 아래와 같은 해결책이 필요하다.

  1. 여러 인터페이스의 default 메서드 간 충돌
    - 인터페이스를 구현한 클래스에서 메서드를 오버라이딩 해야한다.
    public interface A {
        public int getAge();
    }
    
    public interface B {
        public int getAge();
    }
    
    public class Sample implements A, B {
        public int getAge() {
            ....
        }
    }​

default 메서드와 상위 클래스의 메서드 간 충돌
- 상위 클래스의 메서드가 상속되고 default 메서드는 무시된다.

'개발 언어 > Java' 카테고리의 다른 글

[Java] 예외 처리  (0) 2021.08.27
[Java] 내부 클래스  (0) 2021.08.27
[Java] 추상 클래스&추상 메서드  (0) 2021.08.26
[Java] 다형성  (0) 2021.08.25
[Java] 제어자  (0) 2021.08.25

+ Recent posts