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();
}
}