추상 메서드 :
prototype만 있고 실행 코드를 작성하지 않은 미완성의 메서드이다.
추상메서드 정의:
메서드 이름 앞에 abstract라고 선언하면 됨.
예시는 다음과 같다.
public abstract void setName(String newName);
public abstract String getName();
추상 클래스
abstract 키워드로 선언된 클래스로써 다음 2가지로 구분됨
!! 추상 클래스는 실행 코드가 없는 미완성 상태의 추상 메서드가 존재 가능하므로 객체를 생성할 수 없다.
추상 클래스는 추상 메서드를 통해 서브 클래스가 구현할 메서드를 명확하게 알려주는 인터페이스의 역할로 서브 클래스는 추상 메서드를 목적에 맞게 구현하는 다형성을 실현할 수 있다.
이를 통해 설계와 구현을 분리하고, 계층적 상속 관계를 쉽게 만들 수 있다.
예제)
📃 추상 클래스
abstract class PairMap {
protected String keyArray[];// key들을 저장하는 배열
protected String valueArray[];// value들을 저장하는 배열
abstract String get(String key);// key값을 가진 value 리턴, 없으면 null
abstract void put(String key, String value);// key와 value의 쌍으로 저장, 기존에 key가 있으면 값을 value로 수정
abstract String delete(String key);// key값을 가진 아이템 삭제, 삭제된 value값 리턴
abstract int length();// 현재 저장된 아이템의 개수 리턴
}
📃 추상 클래스를 상속받는 클래스
class Dictionary extends PairMap {
private int count = 0;
public Dictionary(int num) {
keyArray = new String[num];
valueArray = new String[num];
count = 0;
}
@Override
String get(String key) {
for (int i = 0; i < keyArray.length; i++) {
if (key.equals(keyArray[i])) {
return valueArray[i];
}
}
return null;
}
@Override
void put(String key, String value) {
for (int i = 0; i < keyArray.length; i++) {
if (key.equals(keyArray[i])) {
valueArray[i] = value;
return;
}
}
keyArray[count] = key;
valueArray[count] = value;
count++;
}
@Override
String delete(String key) {
for (int i = 0; i < keyArray.length; i++) {
if (key.equals(keyArray[i])) {
String returnDeleteValue = valueArray[i];
keyArray[i] = null;
valueArray[i] = null;
count--;
return returnDeleteValue;
}
}
return null;
}
@Override
int length() {
return count + 1;
}
}
📃 이를 활용하는 main() 메서드
public class DictionaryApp {
public static void main(String[] args) {
Dictionary dic = new Dictionary(10);
dic.put("황기태", "자바");
dic.put("이재문", "파이썬");
dic.put("이재문", "c++");
System.out.println("이재문의 값은 " + dic.get("이재문"));
System.out.println("황기태의 값은 " + dic.get("황기태"));
String deleteValue = dic.delete("황기태");
System.out.println("황기태의 값은 " + dic.get("황기태"));
System.out.println("삭제된 값은 " + deleteValue);
System.out.println("저장된 아이템의 개수는 " + dic.length());
}
}
출력 결과 =>
이재문의 값은 c++
황기태의 값은 자바
황기태의 값은 null
삭제된 값은 자바
저장된 아이템의 개수는 2
추상 클래스보다 한 단계 더 추상화된 클래스
keyword : interface
예시는 다음과 같다
interface PhoneInterface(){
public static final int TIMEOUT = 10000;// 상수필드 public static final 생략가능
public abstract void sendCall();
void receiveCall();// 추상 메서드, public abstract 생략 가능(인터페이스 내의 메서드는 모두 추상메서드로 간주)
public default void printLogo(){// default 메서드
System.out.println("** Phone **");
}
}
!! 멤버변수는 만들수 없다.
!! 객체 생성 불가(인터페이스에 추상 메서드를 가질 수 있으므로)
클래스 - extends - 클래스
인터페이스 - extends - 인터페이스
인터페이스 - implements - 클래스
예제)
📃 인터페이스
public interface Shape {
final double PI = 3.14;// 상수
void draw();// 도형을 그리는 추상 메서드
double getArea();// 도형의 면적을 리턴하는 추상 메서드
default public void redraw(){// 디폴트 메서드
System.out.print("---다시 그립니다.");
draw();
}
}
📃 원 그리기
public class Circle implements Shape {
private int radius;
public Circle(int radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println(" 반지름이 " + radius + "인 원입니다.");
}
@Override
public double getArea() {
return PI * radius * radius;
}
}
📃 타원 그리기
package aboutInterface;
public class Oval implements Shape{
private int width;
private int height;
public Oval(int width, int height) {
this.width = width;
this.height = height;
}
@Override
public void draw() {
System.out.println(" " + width + "*" +height + "에 내접하는 타원입니다.");
}
@Override
public double getArea() {
return PI * width * height;
}
}
📃 사각형 그리기
package aboutInterface;
public class Rect implements Shape{
private int width;
private int height;
public Rect(int width, int height) {
this.width = width;
this.height = height;
}
@Override
public void draw() {
System.out.println(" " + width + "*" + height + "크기의 사각형 입니다.");
}
@Override
public double getArea() {
return width * height;
}
}
📃 이를 활용하는 main() 메서드
public class DrawShape {
public static void main(String[] args) {
Shape[] list = new Shape[3];
list[0] = new Circle(10);
list[1] = new Oval(20,30);
list[2] = new Rect(10,40);
for (Shape shape : list) {
shape.redraw();
}
for (Shape shape : list) {
System.out.println("면적은 " + shape.getArea());
}
}
}
출력 결과 =>
---다시 그립니다. 반지름이 10인 원입니다.
---다시 그립니다. 2030에 내접하는 타원입니다.
---다시 그립니다. 1040크기의 사각형 입니다.
면적은 314.0
면적은 1884.0000000000002
면적은 400.0
- 상속을 위한 슈퍼 클래스로만 사용됨
- 클래스의 다형성을 실현하기 위한 목적
비교 | 목적 | 구성 |
---|---|---|
추상 클래스 | 서브 클래스에서 필요로 하는 대부분의 기능을 추상 클래스에서 구현하여 두고 서브 클래스가 상속받아 활용할 수 있도록 하되 구현 할 수 밖에 없는 기능만을 추상 메소드로 선언하여 서브클래스에서 정의하도록 구현할 목적 | |
인터페이스 | 개발자에게 인터페이스를 상속받는 클래스의 목적에 따라 인터페이스의 모든 추상 메서드를 만들도록 하는 목적 |
📌즉, 추상 클래스는 상속을 받아 기능을 활용(확장 및 확대) 하는 것 이라면 인터페이스는 특정 메서드가 반드시 존재하도록 강제하여 구현 객체끼리 같은 동작을 하도록 하는 것이다.