Interface
abstract, final과 함께 대표적인 규제로 어떤 객체가 있고 그 객체가 특정한 인터페이스를 사용한다면 그 객체는 반드시 인터페이스의 메소드들을 구현해야 한다. 만약 인터페이스에서 강제하고 있는 메소드를 구현하지 않으면 이 에플리케이션은 컴파일 조차 되지 않는다.
클래스 A 뒤의 implements I는 이 클래스가 인터페이스 I를 구현하고 있다는 의미다. 그것은 3행의 interface I의 맴버인 public void z() 메소드를 클래스 A가 반드시 포함하고 있어야 한다는 뜻이다. 인터페이스와 상속은 다르다. 상속이 상위 클래스의 기능을 하위 클래스가 물려 받는 것이라고 한다면, 인터페이스는 하위 클래스에 특정한 메소드가 반드시 존재하도록 강제한다.
인터페이스의 멤버는 반드시 public이다 인터페이스는 그 인터페이스를 구현한 클래스를 어떻게 조작할 것인가를 규정한다. 그렇기 때문에 외부에서 제어 할 수 있는 가장 개방적인 접근 제어자인 public만을 허용한다. public을 생략하면 접근 제어자 default가 되는 것이 아니라 public이 된다. JDK1.8부터는 인터페이스에 default,static 메소드가 추가 가능하다고 한다.
인터페이스와 추상 클래스는 서로 비슷한 듯 다른 기능이다. 인터페이스는 클래스가 아닌 인터페이스라는 고유한 형태를 가지고 있는 반면 추상 클래스는 일반적인 클래스다. 또 인터페이스는 구체적인 로직이나 상태를 가지고 있을 수 없고, 추상 클래스는 구체적인 로직이나 상태를 가지고 있을 수 있다.
인터페이스의 장점
- 개발시간을 단축할 수 있다.
- 변경에 유리한 유연한 설계가 가능하다.
- 표준화가 가능하다.
- 서로 관계없는 클래스들을 관계를 맺어줄 수 있다.
다형성
다형성이란 하나의 메소드나 클래스가 있을 때 이것들이 다양한 방법으로 동작하는 것을 의미한다.
이것이 상속과 오버라이딩 그리고 형변환을 이용한 다형성이다. 실행결과는
B.x
B2.x 이다
클래스 B의 데이터 타입을 클래스 A로 인스턴스화 했을 때 클래스 B의 메소드 y는 마치 존재하지 않는 것처럼 실행되지 않았다.
=> 클래스 B가 클래스 A화 되었다.
클래스 B의 데이터 타입을 클래스 A로해서 인스턴스화 했을 때 클래스 B의 메소드 x를 실행하면 클래스 A에서 정의된 메소드가 아니라 클래스 B에서 정의된 메소드가 실행 되었다.
=> 클래스 B의 기본적인 성질은 그대로 간직하고 있다.
-> 클래스 B를 클래스 A의 데이터 타입으로 인스턴스화 했을 때 클래스 A에 존재하는 맴버만이 클래스 B의 맴버가 된다. 동시에 클래스 B에서 오버라이딩한 맴버의 동작방식은 그대로 유지한다.
쉽게 말하면 부모타입으로 객체 생성시 부모가 허락한 메소드만 (동일한 메소드명 = 오버라이딩) 실행가능
인스터스화 시킬땐 꼭 같은 클래스의 타입을 불러오지 않아도 되고, 그렇게 불러올때 주의해야 될 것은 부모클래스에 정의가 되어 있는걸 불러야 되고 부모클래스에 정의된걸 부를때 자식클래스에 overriding된 존재를 불러온다고 생각하면 편하다
인터페이스와 다형성
다형성에서는 인터페이스도 중요한 수단이다. 특정한 인터페이스를 구현하고 있는 클래스가 있을 때 위에 예제처럼 이 클래스의 데이터 타입으로 인터페이스를 지정 할 수 있다. 클래스 D의 데이터 타입으로 인터페이스 I2,I3가 될 수 있다는 점이다. 이것은 다중 상속이 지원되는 인터페이스의 특징과 결합해서 상속과는 다른 양상의 효과를 만들어낸다.
objI2.b()에서 오류가 발생하는 이유는 objI2의 데이터 타입이 인터페이스 I이기 때문이다. 인터페이스 I는 메소드 A만을 정의하고 있고 I를 데이터 타입으로 하는 인스턴스는 마치 메소드 A만을 가지고 있는 것처럼 동작하기 때문이다.
이것은 인터페이스의 매우 중요한 특징 중의 하나를 보여준다. 인스턴스 objI2의 데이터 타입을 I2로 한다는 것은 인스턴스를 외부에서 제어할 수 있는 조작 장치를 인스턴스 I2의 맴버로 제한한다는 의미가 된다. 인스턴스 I2와 I3로 인해서 하나의 클래스가 다양한 형태를 띄게 되는 것이다.
Exception 예외
try{ 예외가 발생되는 로직 }
catch ( 예외클래스 인스턴스 ) { 예외가 발생됐을때 실행되는 로직 }
finally { 예외여부와 관계없이 실행되는 로직 }
e 는 변수다. 이 변수 앞의 Exception은 변수의 데이터 타입이 Exception이라는 의미다. Exception은 자바에서 기본적으로 제공하는 클래스로 java.lang에 소속되어 있다. e.getMessage()는 자바가 전달한 인스턴스의 메소드 중 getMessage를 호출하는 코드이다.
(catch는 else 와 같이 오류별로 중첩이 가능하다 단, 순서에 주의)
- e.getMessage();
오류에 대한 기본적인 내용을 출력해준다. 상세하지 않다.
- e.toString()
더 자세한 예외 정보를 제공한다. java.lang.ArithmeticException은 발생한 예외가 어떤 예외에 해당하는지에 대한 정보라고 지금을 생각하자.
- e.printStackTrace()
메소드 getMessage, toString과는 다르게 printStackTrace는 리턴값이 없다. 이 메소드를 호출하면 메소드가 내부적으로 예외 결과를 화면에 출력한다. printStackTrace는 가장 자세한 예외 정보를 제공한다.
finally 를 사용하는 이유 - 예를 들어 데이터베이스를 사용한다면 데이터베이스 서버에 접속해야 한다. 이때 데이터베이스 서버와 여러분이 작성한 에플리케이션은 서로 접속상태를 유지하게 되는데 데이터베이스를 제어하는 과정에서 예외가 발생해서 더 이상 후속 작업을 수행하는 것이 불가능한 경우가 있을 수 있다.
예외가 발생했다고 데이터베이스 접속을 끊지 않으면 데이터베이스와 연결 상태를 유지하게 되고 급기야 데이터베이스는 더 이상 접속을 수용할 수 없는 상태에 빠질 수 있다. 접속을 끊는 작업은 예외 발생여부와 상관없기 때문에 finally에서 처리하기에 좋은 작업이라고 할 수 있다
멀티 catch 블럭 (JDK1.7부터 가능)
위와 같이 내용이 같은 catch 블럭을 하나로 합친 것. 사용하는 예외는 상속관계가 아니어야 하고 두 예외사이의 정의된 메소드가 존재할 시 공통된 멤버만 사용가능 (이런경우 단독적으로 사용하는 것이 옳음)
왼쪽은 기본적인 try catch finally 문장을 사용한것이다. 하지만 이제 자바 7.0 버전 이상에서는 finally의 조건문이 번잡해지는 경우에 따라 try with Resource statement를 제공한다. try괄호안의 close가 필요한 클래스를 인스턴스화한 코드를 입력하고 catch에서 예외를 그대로 입력해주면 된다. 그러면 자동으로 내부적으로 close를 실행한다. 기본적인 코드 보다 오른쪽의 코드가 더 간결하고 가독성이 좋아진다.
instanceof
instacnceof는 객체 타입을 확인하는 연산자이다. 형변환이 가능한지 여부를 확인하고 boolean타입으로 반환한다.
상속 관계에서 부모객체인지 자식객체인지 확인하는데 많이 사용된다. instanceof는 객체 instanceof 클래스 를 선언하여 사용하는 것이 기본 사용법이다.
'Java' 카테고리의 다른 글
Java 기초 입문 8일차 (Object, enum, 참조) (0) | 2022.11.27 |
---|---|
Java 기초 입문 7일차 (예외처리 throws, checked, unchecked) (0) | 2022.11.24 |
Java 기초 입문 5일차 (classpath, API, 접근제어자, abstract) (0) | 2022.11.22 |
Java 기초 입문 4일차 (class와 instance의 관계, 지역변수와 전역변수, 상속, 생성자, 오버로딩과 오버라이딩) (0) | 2022.11.21 |
Java 기초 입문 3일차 (객체 지향 프로그래밍, 클래스와 인스턴스) (0) | 2022.11.18 |