제 12장. 추상클래스와 인터페이스

한동윤·2022년 4월 21일
0

java 기초다지기

목록 보기
13/15
post-thumbnail

Tip)

ctrl + b ()
a클래스에서 b클래스를 사용하게 되었는데 b클래스를 수정하고 싶어서 b클래스를 찾으려고

ctrl + e (Recent files) : help - find action - recent files
전에 방문했던 클래스 리스트가 뜨는데 여기서 쉽게 클래스들을 옮겨 다닐 수 있다)

이렇게 단축키 또는 이용할 수 있는 tool이 되게 많은데 단축키를 외우는것이 어려우면 사용하고 싶은 tool명을 기억해두면 찾아서 쓰기 편리하다.

--> 단축키 관련해서는 강의 정리가 끝나고 총 정리할 예정.

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

추상클래스를 사용하는 이유는 미래의 개발자에게 코멘트를 남기지 않기위해서이다.

: 상세 부분이 미정의 된 클래스(아직 메소드와 내용이 추상적이기 때문에 객체를 생성할 수 없게 만들었다)

  1. 추상클래스는 뭐? 실체클래스의 공통적인 부분(변수,메서드)를 추출해서 선언한 클래스

  2. 추상클래스는 객체를 생성할 수 없다! 아직은 실체성이 없고 구체적이지 않기 때문에!

  3. 추상클래스와 실체클래스는 어떤관계? 상속관계!

구현이 안되어있는 메소드(abstract사용한 메소드)가 하나라도 있으면 클래스에도 abstract를 기입해주어야한다(추상클래스)

주의 : 추상클래스는 new에 의한 인스턴스화가 금지되어있다.

그러면 추상클래스는 왜 사용하는가?

  1. 공통된 필드와 메서드를 통일할 목적 -필드와 메서드 이름을 통일하여 유지보수성을 높이고 통일성을 유지

  2. 실체클래스 구현시, 시간절약 - 강제로 주어지는 필드와 메서드를 가지고 나만의 스타일대로 구현가능

  3. 규격에 맞는 실체클래스 구현 - 아무리 자기 스타일대로 클래스를 구현한다고 해도 그것도 결국엔 규격안에서 구현하는 것을 허락한다는 것이지, 규격도 없이 아무렇게나 구현을 해서는 안된다.

위의 사진은 Character(추상클래스)를 상속해주게 되면 상속받은 클래스에서 미구현된 메소드를 작성하여야한다 --> override 해서 메소드를 작성해주면 된다.

public abstract class Character {
    private String name;
    private int hp;

    public String getName() {
        return name;
    }

    public int getHp() {
        return hp;
    }

    public void run() {
        System.out.println(name + "은 도망쳤다");
    }

    public abstract void attack(Kinoko kinoko);
}

위의 Character 추상클래스에 run()매소드 있다. 여기서 해당 추상클래스를 상속받는 실체클래스들은 반드시 run()이라는 추상메소드를 상속받아 오버라이딩해야한다.
--> 여기서 오버라이딩을 하면, 다형성(같은 기능 but 다른 결과)이 발생된다는 사실을 알 수 있다.

===================================================================

인터페이스

인터페이스 = 쉽게 말해서 공통 동작(공통적인 기능들의 집합체)이라고 보면된다.
(추상클래스와 비슷하다)

인터페이스는 모든 메소드가 추상이여야하고 필드가 없다.

추상 클래스에서는 abstract를 사용해주었는데 인터페이스는 interface를 사용해준다.
--> 인터페이스는 메소드에 abstract를 기입안해주어도 자동으로 기입해준 효과를 가진다
(abstract가 생략되어 사용됨)

인터페이스를 상속해줄때는 extends 대신 implements를 사용하는데 이는 <메소드>기능을 확장하는것이 아닌 기능을 구현해주는것이기 때문이다.

public interface Creature {
    public abstract void cry();
}

쉽게 동물을 예로 Animal이라는 인터페이스를 만들어주자. 그러면 이 인터페이스를 implements해준 클래스에서는 cry()메소드를 override해서 이용해줄 수 있는데

public class Dog implements Creature {

    @Override
    public void cry() {
        System.out.println("크르르르르르카라앙ㅋ알캉라!!!!!!!!!!");
    }
}
public class Cat implements Creature {

    @Override
    public void cry() {
        System.out.println("미야아아아아아오오오오옹!!!!!!!!!!!!!!!");
    }
}

위의 두개의 다른 클래스에서 동일하게 사용되어도 안에 내용을 각자의 스타일대로 바꿔 쓸 수 있다는 점에서 쓰이는것을 확인할 수 있다.

인터페이스의 장점은 클래스를 이용하여 다중 상속을 할 경우 메소드 출처의 모호성 등 여러가지 문제가 발생할 수 있는데 다중 상속의 이점을 이용하기 위해 인터페이스를 사용해준다.

<추상클래스와 인터페이스를 동시에 사용>

우선 Creature이라는 인터페이스를 만들어주고 그 다음 Animal이라는 추상클래스를 만들어주고 각각의 클래스들을 만들어주고 코드를 실행해보자.

//Creature 인터페이스
public interface Creature {

    String getCry();
}
//Animal 추상클래스
public abstract class Animal implements Creature {
    private final String name; // 변수에 대한 setter가 없으면 final을 써서
    private final String cry; // 값이 변하지 않는것을 표시해주자

    public Animal(String name, String cry) {
        this.name = name;
        this.cry = cry;
    }

    public String getName() {
        return name;
    }

    @Override
    public String getCry() {
        return cry;
    }
}
//Dog 클래스
public class Dog extends Animal {

    public Dog(String name, String cry) {
        super(name, cry);
    }

}
//Cat 클래스
public class Cat extends Animal {

    public Cat(String name, String cry) {
        super(name, cry);
    }
}
public static void main(String[] args) {
        Cat cat = new Cat("구독냥이", "미야옹");
        Dog dog = new Dog("갱얼쥐", "월월");
        System.out.println(cat.getName() + "가 " + cat.getCry() + "하고 울었다");
        System.out.println(dog.getName() + "가 " + dog.getCry() + "하고 울었다");
    }

이런식으로 상속하여 사용해주면 각각의 클래스의 코드가 간결해지는것을 볼 수 있다.

위 예시에서는 Dog클래스와 Cat클래스에서 변수를 따로 주지않았는데 Dog만의 변수를 설정해주고 Cat만의 변수를 설정해주고 사용해주면 된다.

==================================================================

0개의 댓글