본문 바로가기
Framwork/Java기초

Chapter 10. 추상 클래스와 인터페이스

by 김엉배 2023. 8. 12.
728x90
반응형

목차

1. 추상 클래스(abstract class)
2. 자바 버전 7까지의 인터페이스
3. 자바 버전 8 이후의 인터페이스

 

1. 추상 클래스(abstract class)


- 추상 클래스는 자식을 위해 존재하는 클래스이다. 인스턴스를 만들 수 없다.

 

ex_1) Person이라는 상위 클래스를 만들고, Person 하위 클래스는 Professor, Student 클래스 생성

패키지 구조


package abstracttest;

public class Person {
	private int id;
	private String name;
	public Person(int id, String name) {
		this.id = id;
		this.name = name;
	}
	public int getId() {
		return id;
	}
	public String getName() {
		return name;
	}
}

package abstracttest;

public class Professor extends Person {
	private String department;
	public Professor(int id, String name, String department) {
		super(id, name);
		this.department = department;
	}
	public void show() {
		System.out.println("id : " + getId());
		System.out.println("name : " + getName());
		System.out.println("department : " + department);
	}
}

package abstracttest;

public class Student extends Person {
	private int year;
	public Student(int id, String name, int year) {
		super(id, name);
		this.year = year;
	}
	public void show() {
		System.out.println("id : " + getId());
		System.out.println("name : " + getName());
		System.out.println("year : " + year);
	}
}
  • 위 코드는 Person 클래스는 자신의 하위 클래스인 Professor와 Student 객체를 위해 존재하는 것을 알 수 있다.
    즉, Person 객체를 만들 일이 없어 보인다. 이 경우 Person 클래스를 추상 클래스로 만들면 된다.
    ※추상 메소드가 하나라도 있다면 그 클래스는 반드시 추상 클래스가 되어야 한다.
package abstracttest;

public abstract calss Person {
	........
}

 

ex_2) 추상 메소드

구조


package test;

public class Main {
	public static void main(String[] args) {
		Parent x = new Child1();
		Parent y = new Child2();
		x.show();
		y.show();
		x.print();
		y.print();
	}
}

package test;

public abstract class Parent { // 추상 메소드가 하나라도 있으면 반드시 추상 클래스
	public void show() {
		System.out.println("parent show()");
	}
	public abstract void print(); 
}

package test;

public class Child1 extends Parent {
	public void print() {
		System.out.println("child1 show()");
	}
}

package test;

public class Child2 extends Parent {
	public void print() {
		System.out.println("child2 show()");
	}
}

 

  • 추상 클래스 특징
    - 일반 클래스처럼 멤버변수, 생성자, 일반 메소드 모두 가질 수 있다.
    - 추상 클래스는 객체를 만들 수 없는 클래스이다.
    - 추상 클래스의 메소드는 일반 메소드일 수도 있고 추상 메소드일 수도 있다.
    - 추상 클래스 내의 메소드는 추상 메소드(abstract method)로 구현하는게 바람직하다.
    - 추상 메소드는 선언만 있고 구현 내용은 없다.
    - 추상 메소드를 갖는 클래스는 반드시 추상 클래스가 되어야 한다.
    - 추상 메소드는 반드시 자식 클래스에서 오버라이딩해야 한다. 그렇지 않으면 자식 클래스도 추상 클래스여야 함.
    - 추상 클래스는 자식 클래스를 만들어 다형성을 이용하도록 한다.
    - 추상 메소드에는 private 접근 제어자 붙이면 접근할 수 없어 private 접근 제어자를 사용 x
    - 추사 메소드를 갖지 않아도 추상 클래스로 정의할 수 있다.

 

2. 자바 버전 7까지의 인터페이스


- 인터페이스는 추상 클래스의 일종으로, 추상 클래스보다 더 추상화되어 있다.

- 자바 7 버전까지에서는 인터페이스는 상수와 추사 매소드만 가질 수 있다.

 

  • 인터페이스 기초
interface 인터페이스명 {
	public static final 자료형 상수명 = 값;
    public abstract 반환자료형 메소드명 (매개변수 리스트);
}

- 인터페이스는 interface 키워드로 정의한다. 상수는 public static final로 정의되어야 하는데,

  만약 public static final이 생략되어 있어도 인터페이스 내의 상수는 pulic static으로 간주한다.

ex)
Interface 인터페이스명 {
	public static final int data = 100; //반드시 초기화해야 한다.
    public abstract void show();        //반드시 추상 메소드여야 한다.
}

----------------------------------------------------------------
package interfacetest;

public interface Data {
	int count = 100;  // public static final이 생략되었다.
    void print();     // public abstract가 생략되었다.
}
----------------------------------------------------------------
package interfacetest;

public Code {
	public static void main(String[] args) {
    	Data x = new Data(); //에러 발생.
        System.out.println("count: " + Data.count); // 괜찮
    }
}

 

  • 인터페이스 내의 변수
    ex) 필요한 상수만을 모아서 인터페이스를 구현하고 다른 클래스에서 이용하는 예제
public interface Limit {
  int MAX = 100;
  int MIN = 0;
}

--------------------------------

import java.util.Scanner;

public class code167 {
  public static void main(String[] args) {
    Scanner scin = new Scanner(System.in);
    System.out.print("Enter number between 0 and 100: ");
    int num = scin.nextInt();

    if(num < Limit.MIN || num > Limit.MAX)
      System.out.println("Out of ranger");
  }
}
----------------------------------
결과
Enter number between 0 and 100: 110
Out of ranger

 

  • 인터페이스 상속하기
    - 인터페이스 내의 메소드는 추상 메소드이기 때문에 반드시 자식 클래스가 상속받아서 오버라이딩해야 한다.
    - 클래스가 인터페이스를 상속받을 때에는 implements 키워드를 사용한다.
    - 인터페이스가 인터페이스를 상속받을 때도 있는데 이때는 extends 키워드를 사용한다.

ex) 클래스가 인터페이스를 상속하기 - implements 키워드 사용

package interfacetest;

public interface Data {
  int count = 100;
  void print();
}

----------------------------------------------------------

package interfacetest;

public class ChildDate implements Data {
  // 인터페이스의 메소드들은 public 제어를 한다.(오버라이딩 할때 부모보다 엄격한 제어를 가질 수 없다. 반드시 public)
  public void print() {
    System.out.println("I am child print");
  }
}

----------------------------------------------------------

package interfacetest;

public class code168 {
  public static void main(String[] args) {
    Data x = new ChildDate();
    x.print();
    System.out.println("count: " + Data.count);
  }
}
----------------------------------------------------------
결과
I am child print
count : 100

 

ex) 인터페이스가 인터페이스를 상속 - extends 키워드 사용

- Things 인터페이스를 Book 인터페이스가 상속받고, 그 아래에서 ChildrenBook 클래스가 최종적으로 상속받고 있다.

interface Things {
  void printlnfo();
}
--------------------------------------------------------------
interface Book extends Things { //인터페이스가 인터페이스를 상속받을 때
  void showTitle();
}
--------------------------------------------------------------
class ChildrenBook implements Book { //클래스가 인터페이스를 상속받을 떄
  private String title;
  private String author;

  ChildrenBook() {}
  ChildrenBook(String title, String author) {
    // 반드시 오버라이딩 해야한다.
    this.title = title;
    this.author = author;
  }

  public void printlnfo() {
    // 반드시 오버라이딩 해야한다.
    System.out.println("title: " +title);
    System.out.println("author: " +author);
  }
}
--------------------------------------------------------------
public class code169 {
  public static void main(String[] args) {
    Children Book b = new ChildrenBook("Little Mermaid", "Andersen");
    b.printlnfo();
    b.showTitle();
  }
}
--------------------------------------------------------------
결과
I am child print
count: 100

 

  • 단일 상속 vs 다중 상속
    - 단일 상속은 부모가 하나뿐인 것을 말하고, 다중 상속은 부모가 여럿인 것을 말한다.
    - 클래스는 부모 클래스를 하나만 가질 수 있지만, 인터페이스는 다중 상속을 가능하게 한다.

 

 

3. 자바 버전 8 이후의 인터페이스


- 원래 인터페이스에는 public static final 변수와 추상 메소드만 넣을 수 있었지만 두 종류 메소드가 추가
   1) 디폴트 메소드(default method)
   2) 정적 메소드(static method)
- 자바 버전 9에서는 프라이빗 메소드(private method)가 추가된다.

 

  • 디폴트 메소드
    - 디폴트 메소드는 내용 즉, 구현이 있는 메소드이다.
interface WithDefault {
  int COUNT = 100;
  void test();
  default void show() { //반드시 앞에 default 키워드를 붙여야 한다.
    System.out.println("I am show");
  }
}
-----------------------------------------------------------------
class Test implements WithDefault {
  public void test() { //test() 메소드는 추상 메소드이므로 오버라이딩한다.
    System.out.println("I am test");
  }
}
-----------------------------------------------------------------
public class code172 {
  public static void main(String[] args) {
    Test t = new Test();
    t.test();
    t.show();
  }
}
-----------------------------------------------------------------
결과
I am test
I am show

 

  • 정적 메소드
    - 정적 메소드(static) 클래스의 정적 메소드와 같다.
interface WithStatic {
  int get();
  static int getData() {
    return 10;
  }
}
---------------------------------------------------
public class code174 {
  public static void main(String[] args) {
    // static 메소드는 클래스명, 메소드로 호출할 수 있다.
    System.out.println("WithStatic.getData(): " + WithStatic.getData());
  }
}
---------------------------------------------------
결과
WithStatic.getData() : 10

 

  • 프라이빗(private) 메소드
    - 같은 인터페이스 내에 있는 디폴트 메소드나 다른 프라이빗 메소드에 의해서만 호출 가능.
    - 프라이빗 메소드 의미대로 메소드가 선언된 곳에서만 사용할 수 있다.
interface WithPrivate {
  default int getData() {
    print();
    return get() + 100;
  }

  private void print() { //private 메소드는 인터페이스 안에서만 접근 가능.
    System.out.println(get());
  }
  private int get() {
    return 100;
  }
}
---------------------------------------------------------
class Test4 implements WithPrivate {
  void test() {
    int x = getData();
    System.out.println("x: " + x);
  }
}
---------------------------------------------------------
public class code175 {
  public static void main(String[] args) {
    Test4 = new Test4();
    t.test();
  }
}
---------------------------------------------------------
결과
100
x : 200

 

728x90
반응형

'Framwork > Java기초' 카테고리의 다른 글

Chapter 12. 예외 처리  (20) 2023.08.15
Chapter 11. 패키지와 클래스들  (16) 2023.08.15
Chapter 9. 패키지와 접근 제어  (7) 2023.08.06
Chapter 8. 상속  (5) 2023.08.06
Chapter 7. 클래스와 객체(2)  (0) 2022.11.04