본문 바로가기
Study/JAVA

[JAVA] 9주차_추상 클래스와 인터페이스, 인터페이스의 상속, 인터페이스 구현과 타입 변환

by 8희 2022. 5. 1.

1차시 추상 클래스와 인터페이스

 


추상 메서드:

- 메서드 본체를 완성하지 못한 메서드. 무엇을 할지는 선언할 수 있지만, 어떻게 할지는 정의할 수 없다.

- 완성하지 못한 = 추상화 했다 

- 굳이 구현부를 만들지 않고 상속받은 곳에서 구현하도록 한다.

 

추상 클래스

- 보통 하나 이상의 추상 메서드를 포함하지만 없을 수도 있다.

- 주로 상속 계층에서 자식 멤버의 이름을 통일하기 위하여 사용

- 추상 클래스는 객체 생성 불가능!

 

/* 추상 클래스와 메서드 선언 방법 */

abstract class 클래스이름 { //추상 클래스 선언
//필드
//생성자
//메서드
}

absract 반환타입 메서드이름() ; //추상 메서드 선언
//추상 메서드에는 {}, 즉 메서드 구현부가 없다.

 

/* 추상 메서드를 포함하는 추상 클래스 */

abstract class Shape {
	double pi = 3.14; //필드

	abstract void draw(); //추상메서드
	//추상메서드는 {} 없음!
	
	public double findArea() { //구현메서드
		return 0.0;
	}
}
/* 추상 클래스의 자식 클래스 */

class Circle extends Shape { //추상 클래스 상속 받음
	int radius; //필드

	public Circle(int radius) { //생성자
		this.radius = radius;
	}

//부모 클래스에서 추상 메서드로 선언했으므로 자식 클래스에서 반드시 구현해야 한다.
	public void draw() { //추상(구현) 메서드
		System.out.println("원을 그리다.");
	}

	public double findArea() { //오버라이딩
		return pi * radius * radius;
	}
}

 

인터페이스:

- 인터페이스만 준수하면 통합에 신경쓰지 않고 다양한 형태로 새로운 클래스 개발 가능

- 클래스의 다중 상속을 지원하지 않지만, 인터페이스로 다중 상속 효과를 간접적으로 얻을 수 있다.

- 인터페이스 구조 확장으로 인터페이스 안에 디폴트 메서드도 들어갈 수 있다. 

 

디폴트 메서드와 정적 메서드 (default 메서드와 static 메서드):

- 디폴트 메서드는 오버라이딩 가능, 정적 메서드는 오버라이딩 불가능

- 디폴트 메서드는 인스턴스 메서드이므로 객체 생성 후 호출, 정적 메서드는 인터페이스로 직접 호출

 

인터페이스의 구조

interface 인터페이스 이름 {
//상수 필드 //상수만 가능하기 때문에 public static final 키워드 생략 가능
//abstract 메서드 //public abstract 키워드 생략 가능
//default 메서드
//static 메서드
//private 메서드
}

2차시 인터페이스의 상속

 


인터페이스 상속

//인터페이스 선언은 부모만 가능!
//인터페이스 상속 시 extends 키워드 사용

interface 자식인터페이스 extends 부모인터페이스 {
}

//인터페이스 구현 시 implements 키워드 사용

class 자식클래스 implements 부모인터페이스 {
}

//인터페이스는 다중 상속 허용!
//상속할 인터페이스가 여러 개라면 쉼표(,)로 연결

interface 자식인터페이스 extends 부모인터페이스1, 부모인터페이스2 {
}
class 자식클래스 implements 부모인터페이스1, 부모인터페이스2 {
}

//클래스는 다중 상속 불가능
//class 자식클래스 extends 부모클래스1, 부모클래스2 {
// } //따라서 이건 불가능... 부모 클래스는 오직 하나!

class 자식클래스 extends 부모클래스 implements 부모인터페이스{
}

 

인터페이스와 상수

- 인터페이스는 상수화할 수 있다!

interface Coin {
	int PENNY = 1, NICKEL = 5, DIME = 10, QUARTER = 25;
    	//int만 표시되어 있지만, public static final int임
    	//인터페이스의 모든 필드는 public static final이기 때문에!
    	//즉 상수는 자동으로 public static final int 키워드가 붙음
}

public class Coin1Demo {
	public static void main(String[] args) {
		System.out.println("Dime은 " + Coin.DIME + "센트입니다.");
        	//static이니까 인터페이스 이름으로 바로 접근 가능!
	}
}
public class Coin2Demo implements Coin { //Coint 인터페이스 구현
	public static void main(String[] args) {

		System.out.println("Dime은 " + DIME + "센트입니다.");
		//Coin 인터페이스의 구현 클래스이므로 직접 상수 사용 가능
	}
}

 

Comparable 인터페이스

- 객체를 비교하기 위한 규격으로 사용되는 인터페이스

- 기준이 되는 객체와 크기 비교

- 다른 객체보다 크면 양수, 동일하면 0, 작으면 음수 반환

public interface Comparable {
	int compareTo(Object other);
}
/* Comparable 인터페이스 응용 */

class Circle implements Comparable { //Comparable 인터페이스 (기본적으로 제공)
	double radius;

	public Circle(double radius) {
		this.radius = radius;
	}

	//compareTo(Circle)
	public int compareTo(Object o) { //Object는 자바 모든 클래스 중 최상위 클래스
		//Circle이 Object라는 최상위 클래스로 바뀌는 거니까 업 캐스팅 발생!
		Circle c = (Circle) o; //다운 캐스팅
		if (this.radius > c.radius) 
			return 1;
		else if (this.radius == c.radius)
			return 0;
		else
			return -1;
	}
}

public class CircleDemo {
	public static void main(String[] args) {
		Circle c1 = new Circle(5.0);
		Circle c2 = new Circle(6.0);

		if (c1.compareTo(c2) > 0) //c1을 기준으로 c2랑 비교
			System.out.println("첫 번째 원이 두 번째 원보다 크다.");
		else if (c1.compareTo(c2) == 0)
			System.out.println("두 원의 크기가 같다.");
		else
			System.out.println("첫 번째 원이 두 번째 원보다 작다.");
	}
}

3차시 인터페이스 구현과 타입 변환

 


인터페이스의 상속과 구현 클래스

public interface Controllable {
	default void repair() { //디폴트 메서드
		System.out.println("장비를 수리한다."); //수리 기능은 오버라이딩 하기 위해서 디폴트 메서드
        	//디폴트 메서드는 오버라이딩 선택 가능
	}

	static void reset() { //정적 메서드
		System.out.println("장비를 초기화한다."); //정적 메서드는 오버라이딩 불가능
	}

	void turnOn(); //추상 메서드 //추상 메서드는 구현부가 없어서 반드시 오버라이딩 필요!
	void turnOff(); //추상 메서드
}
public class TV implements Controllable {

	//자식은 부모보다 접근 범위가 좁으면 안 되기 때문에 반드시 public
    	//부모인 인터페이스의 메서드는 전부 public
	@Override
	public void turnOn() { //추상 메서드 구현 필수
		System.out.println("TV를 켠다.");
	}

	@Override
	public void turnOff() { //추상 메서드 구현 필수
		System.out.println("TV를 끈다.");
	}

	@Override
	public void repair() { //디폴트 메서드는 선택해서 오버라이딩 가능
		//Controllable.super.repair();
		System.out.println("TV 장비를 수리한다.");
	}
	
}
public class Computer implements Controllable {
	public void turnOn() {
		System.out.println("컴퓨터를 켠다.");
	}

	public void turnOff() {
		System.out.println("컴퓨터를 끈다.");
	}

	@Override
	public void repair() {
		//Controllable.super.repair();
		System.out.println("컴퓨터 장비를 수리한다.");
	}
}
public class ControllableDemo {
	public static void main(String[] args) {
		TV tv = new TV();
		Computer com = new Computer();

		tv.turnOn();
		tv.turnOff();
		tv.repair();
		com.turnOn();
		com.turnOff();
		com.repair();
		Controllable.reset(); //정적 메서드는 인터페이스로 직접 호출
		// tv.reset(); //정적 메서드는 객체를 통해서 호출 X
		// com.reset();
	}
}