12 추상클래스와 인터페이스
l 추상클래스 abstract
m 추상클래스
n 미완성 메서드를 포함한 클래스(완성 메서드랑 변수 포함 가능!)
n 자기 자신으로 인스턴스 생성 불가능 -> 상속을 통한 자손 메서드에 의해서만 완성될 수 있음
n class 앞에 abstract 붙임!
abstract class Parent{ }
m 추상메서드
n 선언부만 작성하고 구현부는 작성하지 않은 미완성 메서드
n 실제 상속 받는 클래스에서 구현하도록 비워두고 어떤 기능을 수행할 지만 주석처리로 알려줌
n abstract 리턴타입 메서드이름( );
abstract int showShow();
{ } <- 이거 붙이는 순간 일반 메서드로 취급
n 상속 받은 자손 클래스는 오버라이딩을 통해 조상인 추상메서드를 모두 구현해 줘야 됨구현 다 안하고 남겨두면 그 자손 클래스도 추상 클래스로 정의해야 됨
m 추상클래스 작성
n 추상클래스도 생성자가 있어야 함
n 추상클래스 내의 메서드들이 클래스 내의 추상 메서드 사용 가능
n 자손클래스에서 추상메서드를 반드시 구현하라고 강요하기 위해 작성!그냥 메서드는 상속되고 추상메서드는 반드시 오버라이딩 해야 함
l 인터페이스
m 인터페이스
n 일종의 추상클래스이지만 추상클래스보다 추상화 정도가 높음
n 오직 추상메서드와 상수만 멤버로 가질 수 있음일반 메서드, 변수 안됨!
m 인터페이스 작성
n class 대신 interface 사용
n 접근 제어자로 public, default 사용 가능
n 제약사항
u 모든 멤버 변수는 public static final이며 생략 가능 (상수만 가능하고 접근제어자 정해져 있으니까!)
u 모든 메서드는 public abstract이고, 생략 가능(추상메서드만 가능하니까! 그리고 static 메서드와 default 메서드는 예외)
m 인터페이스 상속
n 인터페이스는 인터페이스로부터만 상속받을 수 있음
n 다중 상속 가능
n 최고 조상이 없음
n 자손 인터페이스가 조상 인터페이스에 정의된 모든 멤버 상속 받음
m 인터페이스 구현
n 자기 자신 그 자체로 인스턴스 생략 불가능 -> 자신을 상속받은 클래스로 인해 구현됨
n extends 대신 implements 사용 (구현한다!는 의미)
n 구현하는 인터페이스 메서드 중 일부만 구현하면 -> 추상클래스로 선언해야 됨!
n 오버라이딩 할 때 조상 메서드보다 넓은 범위의 접근 제어자를 지정해야 함
m 인터페이스를 이용한 다중 상속
n 두 개의 클래스로부터 상속 받아야 한다면, 두 조상 클래스 중 비중 높은 쪽을 상속받고 낮은 것은 내부클래스로 하거나어느 한쪽의 필요한 부분만 뽑아 인터페이스로 만들어 구현
n 클래스는 둘 다 만들되, 한 클래스를 인터페이스로 따로 만들어 클래스의 메서드를 인터페이스 메서드로 오버라이딩!
class Scanner{ … }
class Copymachine{
…
void method1();
int method2();
… }
interface Icopymachine{
…
void method1();
int method2();
… }
class Multifunction_printer extends Scanner{} implements Icopymachine{
Copymachine cm = new Copymachine();
void method1(){
cm.method1();
}
int method2(){
cm.method2();
}
}
뭐 이런식?
m 인터페이스를 이용한 다형성
n 해당 인터페이스 타입의 참조변수로 이를 구현한 클래스의 인스턴스 참조 가능인터페이스 타입으로 형 변환도 가능
n 메서드의 메개변수 같은 것으로 인터페이스 사용해서, 이를 구현하는 클래스들을 매개변수로 보낼 수 있음
n 리턴 타입을 인터페이스로 하여, 인터페이스 구현한 클래스를 리턴 할 수 있음
n 분산환경 프로그래밍에서 좋음 -> 사용자 컴퓨터에 설치된 프로그램을 변경하지 않고 서버 측 변경만으로 사용자가 새로 개정된 프로그램 사용 가능
m 인터페이스의 장점
n 개발 시간 단축 가능인터페이스 구현한 클래스의 인스턴스 멤버 접근으로 코드 중복을 막음(꺼내 쓰는 것)
n 표준화 가능
n 서로 관계 없는 클래스들에게 관계를 맺어줄 수 있음공통점이 없는 상속 관계에서 상속 체계 유지하고 공통점 부여
n 독립적인 프로그래밍 가능인터페이스 이용해 특정 데이터베이스에 종속되지 않은 프로그램 작성 가능
m 인터페이스의 이해
n 클래스를 사용하는 쪽(User)과 클래스 제공하는 쪽(Provider)이 있음
n 메서드를 사용(호출)하는 쪽(User)에서는 사용하려는 메서드(Provider)의 선언부만 알면 됨
n 클래스가 서로를 직접 호출하지 않고 인터페이스를 매개체로 하여 접근하면 인터페이스만 맞으면 클래스가 대체되어도 문제 없음 -> 클래스 간 간접적인 관계!
m 디폴트 메서드와 static 메서드
n JDK1.8부터 사용할 수 있는 기능
n 디폴트 메서드!
u 추상메서드의 기본적 구현을 제공
u 추상메서드가 아니라서 디폴트 메서드 추가해도 해당 인터페이스 구현한 클래스는 변경 없어도 됨
u 키워드 default! & 블록 { } 있어야 함
u 접근제어자 public & 생략 가능
u 조상클래스에 새로운 메서드 추가한 것!
u 이름 충돌 해결 규칙
- 여러 인터페이스의 디폴트 메서드 간의 호출 : 인터페이스 구현한 클래스에서 디폴트 메서드 오버라이딩
- 디폴트 메서드와 조상 클래스 메서드 간의 충돌 : 조상 클래스 메서드 상속, 디폴트 메서드 무시도미
l 내부 클래스
m 클래스 내에 선언되는 클래스
m 내부 클래스
n 두 클래스가 서로 긴밀한 관계에 있어 클래스 내에 선언된 클래스
n 내부에 선언된 클래스는 외부 클래스에서만 보통 접근하는 것!
n 장점내부클래스에서 외부 클래스 멤버들을 쉽게 접근할 수 있음코드 복잡성 줄일 수 있음(캡슐화)
m 내부 클래스 종류와 특징
n 변수 선언 위치랑 같고, 선언된 위치에 따라 구분됨
인스턴스 클래스 | 외부 클래스 멤버변수 선언 위치에 선언외부 클래스 인스턴스 멤버로 다뤄짐 외부 클래스의 인스턴스 멤버들과 관련된 작업에 사용될 목적으로 선언 |
스태틱 클래스 | 외부 클래스 멤버변수 선언 위치에 선언 외부 클래스의 static 멤버처럼 다뤄짐외부 클래스의 static 멤버(특히 메서드)에서 사용될 목적으로 선언 |
지역 클래스 | 외부 클래스의 메서드나 초기화블럭 안에 선언 선언된 영역 내부에서만 사용됨 |
익명 클래스 | 클래스의 선언과 객체의 생성을 동시에 하는 이름없는 클래스(일회용) |
m 내부 클래스의 선언
n 내부 클래스 위치는 변수 선언위치와 동일
è 선언 위치에 따라 같은 선언위치의 변수와 동일한 scope와 접근성 가짐
m 내부 클래스의 제어자와 접근성
n abstract, final 제어자 사용 가능
n private, protected 접근 제어자 사용 가능
n static 클래스만 static 멤버 가질 수 있음(상시 사용 가능한가 문제니까)
n final static 변수는 상수니까 모든 내부 클래스에서 정의 가능
n 인스턴스 클래스 : 외부 클래스와 인스턴스 멤버임인스턴스 변수와 static변수 모두 사용 가능
n 스태틱 클래스 : 외부 클래스의 static 멤버이므로 외부 클래스의 인스턴스 멤버 사용 불가static 멤버만 사용 가능
n 지역 클래스 : 외부 클래스 인스턴스 멤버, static 멤버 모두 사용 가능지역 클래스가 포함된 메서드에 정의된 지역 변수도 사용 가능
è but! final이 붙은 지역 변수만 접근 가능 -> 변수는 소멸해도 인스턴스는 아닐 가능성이 있어서!
n 컴파일 했을 때 파일명 : 외부클래스명$내부클래스명.class내부 클래스명 앞에 숫자 붙여서 같은 이름 내부 클래스 구분
n this : 내부 클래스 변수와 외부 클래스 변수 명 같을 때 내부 - this, 외부 – 외부클래스명.this
l 익명 클래스
m 이름이 없는 일회용 클래스
n 클래스 선언과 객체의 생성을 동시에 하여 단 한번만 사용 가능, 하나의 객체만 생성
n 생성자 가질 수 없음(이름 없음)
n 조상 클래스의 이름이나 구현하고자 하는 인터페이스의 이름을 사용해 정의
è 하나의 클래스 상속과 동시에 인터페이스 구현하거나 둘 이상의 인터페이스 구현 불가능
è 즉 다중 상속 불가능
è 하나의 클래스를 상속받거나 하나의 인터페이스만 구현할 수 있음
n 컴파일 했을 때 파일명 : 익명클래스명$숫자.class
n 두 개의 독립된 클래스 작성한 다음 다시 익명클래스 이용해 변경하면 쉽다!
class EventClass{
public static void main(String[] args){
Button b = new Button(“start”);
b.addActionListener(new EventHandler());
}
}
class EventHandler implements ActionListener{
public void actionPerformed (ActionEvent e){
System.out.print(“ActionEvent!”);
}
}
이것을!
class EventClass{
public static void main(String[] args){
Button b = new Button(“start”);
b.addActionListener(new ActionListener(){
public void actionPerformed (ActionEvent e){
System.out.print(“ActionEvent!”);
}
);
}
}
이렇게 한번에!EventHandler 라는 클래스를 만들지 않고 바로 ActionListener 인터페이스를 이용한 익명 클래스를 선언하고 생성하여 사용함
'JAVA > 이론' 카테고리의 다른 글
[java][이론]014 컬렉션 프레임웍_개괄 (0) | 2020.08.28 |
---|---|
[java][이론] 013 예외처리 (0) | 2020.08.12 |
[java][이론] 011 다형성 (0) | 2020.08.06 |
[java][이론] 010 제어자 (0) | 2020.07.08 |
[java][이론] 009 package와 import (0) | 2020.07.06 |