추상 클래스 (abstract class) 구현하기
추상 클래스란
구현 코드 없이 메서드의 선언만 있는 추상 메서드를 포함한 클래스
메서드 선언 : 반환 타입, 메서드 이름, 매개변수로 구성
메서드 정의 : 메서드 구현과 동일한 의미 구현부를 가짐
추상 클래스의 모든 클래스가 추상 메서드의 필요는 없다.
대신 하위클래스들이 구현하도록 위임한다.
abstract 예약어를 사용
추상 클래스는 new 할 수 없음 객체생성 불가
나중의 인터페이스는 선언만 존재
상속 받은 클래스는 추상 메서드를 구현하던가 아니면
자신도 추상 클래스가 되어 추상 메서드의 선언만을 내포하게 된다.
그냥 하위클래스에서 오버라이드하면 되지 왜 이 짓을 하는가.
하위클래스의 오버라이드 강제화..?!
업캐스팅으로 인스턴스를 만들 수 는 있다.
abstClass this = new nonAbstClass
상위 추상 클래스 다 오버라이드해도 하위 클래스를 추상화할 수 있는데
이는 이 하위 클래스 또한 다른 이들에게 상속하기 위함이다.
이 클래스들은 인스턴스로써 살아갈 생각이 없다는 것이다.
템플릿 메서드 패턴
템플릿 메서드
추상 메서드나 구현된 메서드를 활용하여 코드의 흐름(시나리오)를 정의하는 메서드
final로 선언하여 하위 클래스에서 재정의 할 수 없게 함 흐름이 바뀌면 안되기에
클래스에 final이 들어가면 상속을 할 수 없다.
프레임워크에서 많이 사용되는 설계 패턴
추상 클래스로 선언된 상위 클래스에서 템플릿 메서드를 활용하여 전체적인 흐름을 정의하고 하위 클래스에서 다르게
구현되어야 하는 부분은 추상 메서드로 선언하여 하위 클래스에서 구현하도록 한다.
프레임워크
일반적인 라이브러리와는 다르다. JDK는 라이브러리이다. android는 프레임워크
라이브러리를 사용하면 프로그램의 전반적인 흐름의 제어는 프로그래머가 가지지만
프레임워크는 흐름이 다 정해져있다. 프레임워크의 구멍을 매꿀뿐이다
상위클래스에 구현부를 빈 { } 로 둬서 강제성 없이 필요에 따라 오버라이드 하도록 할 수 있다. 이러한 메서드를 훅메서드라한다.
얘를 final 메서드 안에다 넣으면 구현한 쪽에서는 추가된 기능이 나오고 안 한쪽은 일어나지 않는다.
인터페이스
인터페이스는
모든 메서드가 추상 메서드로 선언됨 public abstract
모든 변수는 상수로 선언됨 public static final
메서드 구현이 없다 그래서 멤버변수 가질 수가 없다 그래서 모든 변수는 상수가 된다
precompile시 키워드가 붙게된다.
인터페이스는 상속이 아닌 구현한다고 표현한다
전부 구현 안하면 구현한 클래스는 추상 클래스가 된다.
다중상속을 하게되면 모호성이 발생할 수 있는데 인터페이스는 구현이 없기에 모호성이 발생하지 않는다
인터페이스를 구현한 클래스는 ? 인터페이스의 타입상속이라 한다...? 이 클래스가 이 인터페이스 타입이다...
그리고 인터페이스 참조변수로 하위클래스 받으면 인터페이스 범위로만 접근 가능
인터페이스가 하는 일
클래스나 프로그램이 제공하는 기능을 명시적으로 선언
일종의 클라이언트 코드와의 약속이며 클래스나 프로그램이 제공하는 명세
클라이언트 프로그램은 인터페이스에 선언된 메서드 명세만 보고이를 구현한 클래스를 사용할 수 있다.
어떤 객체가 하나의 인터페이스 타입이라는 것은 그 인터페이스가 제공하는 모든 메서드를 구현했다는 의미임
인터페이스를 구현한 다양한 객체를 사용함 - 다형성
사용자 정보를 crud한다고 하자. 다른 회사에 프로그램을 납품하려하는데 회사 마다 DB가 다르다
이를 DB별로 코드를 만들면 관리를 2중으로 해야하니 정말 좋지 않다. 버그패치를 하기에도 힘들다. 기능 업그레이드도.
버전관리도 힘들엇! 그러니 인터페이스로 정의하자
DB에 회원정보를 넣는 dao(Data access object)를 여러 DB 제품이 지원될 수 있게 구현
환경파일 db.properties 에서 database의 종류에 대한 정보를 읽고 그 정보에 맞게 dao 인스턴스를 생성해서 실행되게 함
인터페이스의 여러가지 요소
상수
모든 변수는 상수로 변환된다.
추상 메서드
모든 선언된 메서드는 추상 메서드
디폴트 메서드 (Java 8이후)
구현을 가지는 메서드, 인터페이스를 구현하는 클래스들에서 공통으로 사용할 수 있는 기본 메서드
default 키워드 사용
인터페이스를 구현하는 경우에도 같은 코드를 중복해서 작성해야하는 경우가 있었다.
그냥 공통적으로 쓸 수 있게 구현 가능
재정의 가능
정적 메서드 (Java 8 이후)
인스턴스 생성과 상관 없이 인터페이스 타입을 사용할 수 있는 메서드
private 메서드 (Java 9이후)
인터페이스를 구현한 클래스에서 사용하거나 재정의 할 수 없음
이넡페이스 내부에서만 사용하기 위해 구현하는 메서드
default 메서드나 static 메서드에서 사용함
인터페이스 내부 스태틱 메서드에는 private static 메서드가 사용된다
다중 구현함에도 모호함이 발생하지 않는 건 내부 정의 없어서..
default같은 애들이 생겼음에도 문제가 되지 않는건
구현한 클래스에도 공통된 메서드가 들어가서? 이건 가상메서드 때문에 해결되는거 아닌가
c++에서도 모호함을 가상메서드로 해결하지 않았나..
가상 메서드에 숨겨진 비밀이 있을 것 같다.. 냄새가 난다..
다이아몬드 상속 경우 모호함 발생
다중상속 허용하면 여러 기능을 상속받을 수있으니 장점이 있다.
대신 . 모호성이 존재한다 . Java는 기존에 안정성을 보장하려했다
여러 인터페이스 구현 시
자바의 인터페이스는 구현 코드가 없으므로 하나의 클래스가 여러 인터페이스는 구현할 수 있음
디폴트 메서드가 중복 되는 경우는 구현하는 클래스에서 재정의 하여야 한다
여러 인터페이스를 구현한 클래스는 인터페이스 타입으로 형 변환되는 경우 해당 인터페이스에선언된 메서드만 사용 가능
그냥 모호함을 수용하였다고 봐야겠다.
클래스 생성할 때
일반적인 클래스한테서 상속을 받고 기능적인 부분은 인터페이스로 받는다
선반 클래스와 큐 인터페이스를 상속 받아서 만드는 책선반
(선반 클래스 내부를 ArrayList로 만들었지만 기능을 인터페이스로 따로 패뒀다. (걍 선발 클래스에 기능도 구현하면 안 되나))
댓글