인터페이스(interface) 및 추상클래스(abstract class)

kmb·2022년 2월 22일
0

자바

목록 보기
15/31
post-thumbnail

인터페이스

제한된 행위(메서드)를 강제로 수행하도록 하는것.

개발 코드와 객체가 서로 통신하는 접점 역할을 한다.
개발 코드가 인터페이스의 메서드를 호출하면 인터페이스는 객체의 메서드를 호출한다.
따라서 개발 코드는 객체의 내부구조를 알 필요가 없고 인터페이스의 메서드만을 알고 있으면 된다.

 

인터페이스 선언 (Java8 이상)

접근제어자 interface 인터페이스이름 {

    [public static final] 반환타입 상수이름 =;   // 상수 필드(Constant Field)

    [public abstract] 반환타입 메서드이름(매개변수);  // 추상 메서드(Abstract Method)
    
    // 자바8 추가
    [public] default 반환타입 매서드이름(매개변수);   // 디폴트 메서드(Default Method)
    
    // 자바8 추가
    [public] static 반환타입 메서드이름(매개변수);  // 정적 메서드(Static Method)

}

상수 필드[ public static final ] 생략 가능. 상수이름은 대문자로 작성하는것이 관례. 반드시 초기값을 대입해야 한다.

추상 메서드[ public abstract ] 생략 가능.

디폴트 메서드[ public ] 생략 가능. 기존 인터페이스를 확장해서 새로운 기능을 추가하기 위한 목적.

정적 메서드[ public ] 생략 가능. 객체 생성없이 인터페이스만으로 호출 가능.

 

인터페이스 특징

  1. 상수메서드만을 멤버로 가진다. (필드생성자를 가질수 없다)

  2. 생성자를 가질수 없으므로, new 연산자로 인스턴스를 생성할 수 없다.

  3. Java 8이후부터 디폴트(default) 메서드정적(static) 메서드 선언이 가능하다

  4. 개발 코드에서 인터페이스는 클래스의 필드, 생성자 및 메서드의 매개변수 그리고 생성자 또는 메서드의 지역 변수로 선언될 수 있다.

 

인터페이스 구현

class 클래스이름 implements 인터페이스이름 { 
	
    @Override
    반환타입 메소드이름() {
    	......
    }
}

 

ex) 인터페이스를 활용한 예시

public interface RemoteControl {
	
    // 상수 필드
    int MAX_VOLUME = 10;
    int MIN_VOLUME = 0;
    
    // 추상 메서드
    void turnOn();
    void turnOff();
    void setVolume(int volume);
    
    // 디폴트 메서드
    dafault void setMute(boolean mute) {
    	if(mute) {
        	System.out.println("무음 처리합니다");
        }else {
        	System.out.println("무음 해제합니다");
        }
    }
    
    // 정적 메서드
    static void changeBattery() {
    	System.out.println("건전지를 교환합니다");
    }
}

public class Television implements RemoteControl {
	
    // 필드
    private int volume;
    
    // 추상 메서드 구현
    public void turnOn() {
		System.out.println("TV를 켠다.");
	}
    public void turnOff() {
		System.out.println("TV를 끈다.");
	}
    public void setVolume(int volume) {
    	if(volume > RemoteControl.MAX_VOLUME) {
        	this.volume = RemoteControl.MAX_VOLUME;
        
        } else if(volume < RemoteControl.MIN_VOLUME) {
        	this.volume = RemoteControl.MIN_VOLUME;
        
        } else {
        	this.volume = volume;
        }
        
        System.out.println("현재 TV 볼룸 = " + this.volume);
    }
}

public class RemoteControlExample {
	
    public static void main(String[] args) {
    	
        RemoteControl rc;
        
        rc = new Television();
    }
}

추상클래스

하나 이상의 추상 메서드를 포함하는 클래스.
반드시 사용해야하는 메서드를 추상클래스 내부의 추상메서드로 선언 할 경우에, 추상클래스를 상속받은 모든 클래스에서 추상메서드를 반드시 재 정의해야한다.

즉 객체 지향의 특징인 다형성을 가지는 메서드의 집합을 정의 할 수 있게 해준다.

 

추상클래스 선언

abstract class 클래스이름 {

	// 필드
    
    // 생성자

    [접근제한자] abstract 반환타입 메소드이름 (매개변수, ...);  // 추상 메서드

}

 

추상클래스 특징

  1. new 연산자로 인스턴스를 생성할 수 없다. (단 생성자는 가질 수 있다)
    따라서 상속받은 자식클래스에서 추상메서드를 구현하고 인스턴스 생성할 수 있다.

  2. abstract 키워드가 포함된 메서드 없이, abstract 키워드를 클래스에만 추가해도 추상클래스가 된다.
    단 이때도 new 연산자로 인스턴스를 생성할 수 없다.

  3. abstract 키워드가 포함된 메서드가 1개라도 있다면 클래스는 무조건 추상클래스가 되어야한다.

  4. 인터페이스와는 다르게 static이나 final이 아닌 다른 필드(field)도 지정 할 수 있다.

  5. 인터페이스와는 다르게 public, protected, private, final 메서드(method)를 가질수 있다.

 

추상클래스 구현

class 클래스이름 extends 추상클래스이름 {
	
    @Override
    반환타입 메소드이름() {
    	......
    }
}

 

ex) 추상 클래스를 활용한 예시

public abstract class Phone {  // 추상 클래스
	
    // 필드
    public String owner;
    
    // 생성자
    public Phone(String owner) {
    	this.owner = owner;
    }
    
    // 메서드
    public void turnOn() {
    	System.out.println("폰 전원을 켭니다");
    }
    
    public void turnOff() {
    	System.out.println("폰 전원을 끕니다");
    }
}

public class SmartPhone extends Phone {
	
    // 생성자
    public SmartPhone(String owner) {
    	super(owner);
    }
    
    // 메서드
    public void internetSearch() {
    	System.out.println("인터넷 검색을 합니다");
    }
}

public class PhoneExample {
	
    public static void main(String[] args) {
    	
        // Phone phone = new Phone();  // 추상클래스 인스턴스 생성 불가능
        
        SmartPhone smartPhone = new SmartPhone("홍길동");
        
        smartPhone.turnOn();         // 추상클래스의 메서드
        smartPhone.turnOff();        // 추상클래스의 메서드
        smartPhone.internetSearch(); 
    }
}

 

ex) 추상 메서드를 활용한 예시

public abstract class Animal {      // 추상 클래스
	
    public String kind;
    
    public void breathe() {         // 일반 메서드
    	
        System.out.println("숨을 쉽니다");
    }
    
    public abstract void sound();   // 추상 메서드
}


public class Dog extends Animal {
	
    public Dog() {
    	this.kind = "포유류";
    }
    
    @Override
    public void sound() {			// 추상 메서드 재정의
    	System.out.println("멍멍");
    }
}


public class AnimalExample {
	
    public static void main(String[] args) {
    	
        Dog dog = new Dog();
        
        dog.sound();           // 멍멍
        
        Animal animal = null;
        animal = new Dog();    // 자동 타입변환
        animal.sound();
        
        
        animalSound(new Dog());  // 메서드 다형성
    }
    
    public static void animalSound(Animal animal) {
   		
        animal.sound();   // 재정의 된 메서드 호출
    }
}

인터페이스 vs 추상클래스

 

  • 자바8 이전

추상클래스추상메서드, 생성자, 필드, 일반메서드를 포함할 수 있다.
인터페이스추상메서드, 상수 필드를 포함할 수 있다. 구현부가 있는 메서드를 포함 못한다.

 

  • 자바8 이후

공통점 : 인스턴스화가 불가능. 구현부가 없는 메서드 및 구현부가 있는 메서드 모두 포함할 수 있다.

추상클래스추상메서드, 생성자, 필드, 일반메소드를 포함할 수 있다. static이나 final말고 다른 필드를 가질수 있다. public, protected, private 메서드를 가질수있다.

인터페이스추상메서드, 상수 필드를 포함 할 수 있다.

 
추상클래스는 상속을 받은 다음에 기능을 사용하고 확장하는것에 목적을 둔다.

인터페이스는 미완성된 행위(메소드)의 구현을 강제하는것에 목적을 둔다.

 

  • 인터페이스와 추상클래스와 클래스 차이 ( Java8 버전이상 )
인터페이스abstract 클래스클래스
선언시 사용하는 예약어interfaceabstract classclass
구현이 안된 메소드 포함 가능 여부가능 (필수적)가능불가
구현된 메소드 포함 가능 여부가능가능가능 (필수적)
static 메소드 선언 가능 여부가능가능가능
final 메소드 선언 가능 여부불가가능가능
상속(extends) 가능 여부불가가능가능
구현(implements) 가능 여부가능불가불가

 

  • 인터페이스와 추상클래스와 클래스 차이 ( Java8 버전미만 )
인터페이스abstract 클래스클래스
선언시 사용하는 예약어interfaceabstract classclass
구현이 안된 메소드 포함 가능 여부가능 (필수적)가능불가
구현된 메소드 포함 가능 여부불가가능가능 (필수적)
static 메소드 선언 가능 여부불가가능가능
final 메소드 선언 가능 여부불가가능가능
상속(extends) 가능 여부불가가능가능
구현(implements) 가능 여부가능불가불가

 


ex) 인터페이스 및 추상클래스를 활용한 예시

interface MoveAble {
	// public abstract 가 생략
	void();
	void 아래();
	void 왼쪽();
	void 오른쪽();
}

interface MoveAble2 {
	// public abstract 가 생략
	void();
	void 아래();
	void 왼쪽();
	void 오른쪽();
	void 숨기();
}

// 일반클래스의 경우 인터페이스인 MoveAble을 implements하고 구현
// 추상클래스의 경우 인터페이스인 MoveAble을 implements하고 구현은 서브클래스로 위임
// 하지만 추상클래스와 서브클래스의 구현할 내용이 같다면 추상클래스에서 구현을 해도된다.
abstract class 사나운동물 implements MoveAble {

	abstract void 공격();	// 미완성 메서드

	@Override
	public void() {
		System.out.println("위로 이동");
	}
	@Override
	public void 아래() {
		System.out.println("아래로 이동");
	}
	@Override
	public void 왼쪽() {
		System.out.println("왼쪽으로 이동");
	}    
	@Override
	public void 오른쪽() {
		System.out.println("오른쪽으로 이동");
	}
}

abstract class 온순한동물 implements MoveAble2{

	abstract void 채집();	// 미완성 메서드

	@Override
	public void() {
		System.out.println("위로 이동");
	}
	@Override
	public void 아래() {
		System.out.println("아래로 이동");
	}
	@Override
	public void 왼쪽() {
		System.out.println("왼쪽으로 이동");
	}
	@Override
	public void 오른쪽() {
		System.out.println("오른쪽으로 이동");
	}
	@Override
	public void 숨기() {
		System.out.println("땅바닥으로 이동");
	}
}

class 원숭이 extends 온순한동물 {

	@Override	// 어노테이션 : JVM이 실행시에 분석해서 확인
	void 채집() {
		System.out.println("바나나 채집");
	}

}
classextends 온순한동물 {

	@Override
	void 채집() {
		System.out.println("풀 채집");
	}
}
class 호랑이 extends 사나운동물 {

	@Override
	void 공격() {
		System.out.println("할퀴기 공격");
	}
}
class 사자 extends 사나운동물 {

	@Override
	void 공격() {
		System.out.println("물기 공격");
	}
}

public class OOPEx09 {

	// 다형성(오버로딩)
	static void 조이스틱(온순한동물 u) {
		u.채집();
		u.숨기();
		u.();
		u.아래();
		u.오른쪽();
		u.왼쪽();
		System.out.println("========================");
	}
    
	// 다형성(오버로딩)
	static void 조이스틱(사나운동물 s) {
		s.공격();
		s.();
		s.아래();
		s.오른쪽();
		s.왼쪽();
		System.out.println("========================");
	}

	public static void main(String[] args) {
		소 u1 = new();
		조이스틱(u1);
		원숭이 u2 = new 원숭이();
		조이스틱(u2);
		호랑이 u3 = new 호랑이();
		조이스틱(u3);
		사자 u4 = new 사자();
		조이스틱(u4);
	}
}


출처

  • 이지업 컨텐츠 내의 데어프로그래밍 자바강의
  • 자바의 신 (책)
  • 이것이 자바다 (책)
profile
꾸준하게

0개의 댓글