자바프로그래밍 추상클래스와 인터페이스

최주영·2023년 3월 20일
0

자바

목록 보기
11/30

✅ 추상클래스

(1) : 미완성클래스라고도 불리며 실제 생성되면 안되는 클래스 ( abstract 키워드 사용)
= 실제 인스턴스가 존재하지 않음

(2) : 일반 클래스와 동일하게 선언 가능하다 (필드, 메소드, 생성자) 모두 선언가능

(3) : 자체적으로 객체 생성 ❌ -> 반드시 상속하여 객체 생성해야함
-> 자식클래스를 통해서 추상클래스에 접근 가능함
-> Animal animal = new Animal() 추상 클래스로 선언시 생성 불가능 (X)

(4) : abstract 메소드가 포함된 클래스는 반드시 abstract 클래스
abstract 메소드가 없어도 abstract 클래스 선언 가능

  • 목적 : 상속을 강제하기 위해서 사용된 클래스
  • 예시 : abstract class Animal {...}

✅ 추상 메소드

  • 부모 클래스를 상속 받는 자식 클래스가 반드시 오버라이딩 해야하는 메서드
  • 메서드 안에 내용이 없음 (내용을 만들면 컴파일 오류 발생)
  • abstract 키워드를 붙어야 한다
  • 추상 메서드가 하나라도 있는 클래스는 추상 클래스로 선언해야 한다
  • 추상 클래스 안에 추상메소드 , 일반메소드 둘 다 넣을 수 있다
    -> 차이점은 추상메소드는 반드시 자식클래스에서 오버라이딩 해야한다는 점!
  • 예시 : public abstract void sound();

✅ 순수 추상 클래스

  • 모든 메소드가 추상 메소드인 추상 클래스
  • 상속 목적보다는 다형성 을 목적으로 사용함
    -> 부모의 모든 메서드를 오버라이딩 (구현) 해야함
    -> 부모의 기능을 물려받으려는 목적이 아님
public abstract class Animal{
	public abstract void sound();
    public abstract void move(); 
}

이러한 순수 추상 클래스를 더 편리하게 사용하기 위해서 인터페이스 가 등장


✅ 인터페이스

  • 추상 메소드와, static final 변수를 갖음

  • 껍데기 클래스라고 불림

  • interface 키워드를 사용

  • 추상클래스와 동일하게 객체 자체 생성 불가능

  • 인터페이스 내부에는 추상메소드만 선언 가능

  • 순수 추상 클래스에서 약간의 편의기능이 추가된 것이 인터페이스

  • 추상메소드에서 사용하던 public abstract 예약어는 생략이 가능
public interface Animal{ 
	void sound(); // public abstract 
    void move();
}
  • 인터페이스에 변수는 public static final 으로 선언된 상수만 가능하며 public static final 생략 가능
public interface Animal{ 
	int MY_PI = 3.14; // public static final 
}
  • 인터페이스를 구현한 클래스는 인터페이스의 자식 클래스로 설정됨

  • 인터페이스는 다중 구현(다중 상속)을 지원한다

📌 클래스에서 부모 자식 관계는 상속 관계라고 하지만, 인터페이스에서는 구현 관계라고 한다
-> 이유 : 인터페이스는 모두 추상메소드 이기때문에, 기능을 물려받는게 아닌 모두 구현해야함
extends implements

✅ 인터페이스를 사용해야하는 이유

  • 인터페이스의 메서드를 반드시 구현하라는 제약을 줌
  • 좋은 프로그램은 제약이 있는 프로그램
  • 클래스 상속과 다르게 인터페이스는 부모를 여러명 두는 다중 구현(다중 상속)이 가능

✅ 다중 상속은 안되지만 다중 구현은 되는 이유?

  • 인터페이스의 메소드는 모두 추상 메소드 이기 때문이다

다음 그림과 같이 인터페이스 A,B 안에 methodCommon() 메소드가 존재한다
Child 클래스에서 A,B 둘다 구현받았을 때 methodCommon() 메소드를 호출하면
A와 B중 어떤 것이 호출될까?
-> A,B가 아닌 Child에서 오버라이딩 한 methodCommon() 메소드가 호출된다
-> 즉 자식클래스에서 강제로 오버라이딩해야하기 때문에, 부모가 여러명이여도 가능하다!

public class Child implements InterfaceA, InterfaceB {
   @Override
   public void methodA() {
     System.out.println("Child.methodA");
    }
   @Override
   public void methodB() {
     System.out.println("Child.methodB");
   }
   @Override
   public void methodCommon() {
     System.out.println("Child.methodCommon");
   }
}
  • 상속과 구현 동시에 할 수 있음
    public class Bird extends AbstractAnimal implements Fly, Swim

상속과 구현 둘 다 나온 경우, extends 가 먼저 나와야함


✅ 추상클래스와 인터페이스 차이점

  • 추상클래스 : 상속을 받아서 기능을 확장하는데 사용 (추상메서드 + 일반메서드) 둘다 존재
  • 인터페이스 : 설계도와 같이 틀을 잡을 때 사용 (모조리 추상메소드만) 존재


✅ FunctionalInterface

  • 인터페이스에 선언되어 있는 추상클래스가 한 개일 경우
  • FunctionalInterface로 람다표현식으로 이용해서 간단하게 표현
  • 추상클래스가 2개 이상인 경우 오류가 발생

// CalculatorInterface 인터페이스
package com.inter.common;
@FunctionalInterface  // FunctionalInterface로 선언하면 추상메소드는 하나만 저장가능

public interface CalculatorInterface {
	
	void calc(int su, int su2);  // 추상메소드이므로 구현 x
	// int calc2(int a, int b);   -> 추상메소드가 2개이상이면 오류가남
}



// StringInterface 인터페이스
package com.inter.common;

@FunctionalInterface

public interface StringInterface {
	
	String strCheck(String data);
}



// 매개변수 있고, 반환형 없는 람다표현식
CalculatorInterface ci = (int a, int b) -> {
	System.out.println(a+b);
};
		
ci.calc(20, 30);
    
    
    
    
    
Flyable f = new Flyable(){  // 익명클래스를 이용해서 구현
	@Override
	public void fly() {}
};
    
    
// 매개변수 없고, 반환형 없는 람다표현식
f = ()->{System.out.println("람다로 날다");};
f.fly(); 


// 매개변수 있고, 반환형 있는 람다표현식
StringInterface si = (String a) -> {
	return a + " 람다로 출력하기";
};
		
System.out.println(si.strCheck("우와 신기하다"));


// 리턴이 있을 때 로직이 없고 바로 리턴을 구현하면
// return 예약어를 생략할 수 있음 {} 사용하지 않음
	si = (String b) -> b + "로직없이 바로 리턴";
	System.out.println(si.strCheck("많이 어려워요????"));

}



profile
우측 상단 햇님모양 클릭하셔서 무조건 야간모드로 봐주세요!!

0개의 댓글