(JAVA) 추상 클래스,추상 메서드

InAnarchy·2022년 10월 21일
0

JAVA

목록 보기
15/18
post-thumbnail

Table of Contents

  • 추상 클래스
  • 추상 메서드
  • 추상 클래스의 작성

추상 클래스

  • 미완성 설계도(미완성 메서드를 가지고 있는 클래스)
  • 다른 클래스 작성에 도움을 주기 위한 것. (미완성 설계도를 상속받아 구현함. 코드의 변경이 쉬워짐)
  • 생성자가 있으며, 멤버변수와 메서드도 가질 수 있다.

  • new 연산자로 생성자를 호출할 수는 없지만 자식 객체가 생성될 때 super()를 호출해서 추상 클래스 객체를 생성한다.(즉 추상클래스는 생성자가 있어야 한다)

  • 추상클래스로부터 상속받는 자손 클래스는 오버라이딩을 통해 추상메서드를 구현해야한다.(만약 조상으로부터 상속받은 추상메서드 중 하나라도 구현하지 않으면 자손 클래스도 추상 메서드로 지정한다)

  • 인스턴스(객체) 생성이 불가능하다.

abstract class Player{ //추상 클래스
    abstract void play(int pos); //추상 메서드
    abstract void stop();
}

class AudioPlayer extends Player{
    void play(int pos) { //내용생략, 추상 메서드 구현
    }
    void stop() {//내용 생략, 추상메서드 구현
    }
}

abstract class AbstractPlayer extends Playe{
	void play(int pos){
    //내용 생략, 추상 메서드 구현
    //추상 메서드 중 하나를 구현하지 않았으므로 추상 클래스로 지정함
}
Player p = new Player(); //에러
AudioPlayer ap = new AudioPlayer();

그럼 예시를 보자.

abstract class Player{ //추상 클래스
    abstract void play(int pos); //추상 메서드
    abstract void stop(); //추상 메서드
    // void stop(){} //과 같음

}

class AudioPlayer extends Player{
    void play(int pos) {
        System.out.println(pos+"위치부터 play");
    }
    void stop() {
        System.out.println("중지");
    }
}
public class AbstractEx {
    public static void main(String[] args) {
//        AudioPlayer ap = new AudioPlayer();
        Player ap = new AudioPlayer(); //다형성
        ap.play(100);
        ap.stop();
    }
}
abstract class Phone {
    public String owner;

    public Phone(String onwer) {
        this.owner = onwer;
    }

    public void turnOn() {
        System.out.println("turn on");
    }

    public void turnOff() {
        System.out.println("turn off");
    }
}

class SmartPhone extends Phone{
    public SmartPhone(String owner) {
        super(owner);
    }

    public void internetSearch(){
        System.out.println("searching");
    }
}
public class PhoneEx {
    public static void main(String[] args) {
        //Phone p = new Phone() //phone으로 객체 생성 불가
        SmartPhone sp = new SmartPhone("홍길동"); //자식클래스로 객체 생성
        sp.turnOn();
        sp.internetSearch();
        sp.turnOff();
    }
}

추상 메서드

  • 구현부 {} 이 없는 미완성 메서드
  • 부모 클래스에서는 선언부만 작성하고, 상속받는 클래스에서는 구현부를 작성
  • 자식 클래스는 추상 메서드를 재정의해서 작성해야만 함.(그렇지 않으면 컴파일 오류)
  • 메서드는 선언부만 알면 호출 가능하므로 추상 메서드도 호출 가능하다.

예시

abstract class Player{
	//iv
	boolean pause;
    int currentPos;
    
    Player(){ //추상클래스도 생성자가 있어야 함
    	pause = false;
        currentPost = 0;
    }
    
    abstract void play(int pos);
    abstract void stop();
    
    //인스턴스 메서드
    void play(){ 
    	play(currentPos); //추상메서드 호출. 자손이 상속을 통해 완성할 것!
    }
abstract class Animal {
    public String kind;

    public void breath() {
        System.out.println("후,...하...");
    }

    public abstract void sound(); //추상 메서드, 어떤 소리인지는 모름
}

class Dog extends Animal {
    public Dog() {
        this.kind = "포유류";
    }

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

    public void sound() {
        System.out.println("냥냥"); //추상 메서드 재정의
    }
}

public class AnimalEx {
    public static void main(String[] args) {

        Dog dog = new Dog();
        Cat cat = new Cat();

        dog.sound();
        cat.sound();
        System.out.println("-------");

        //변수의 자동 타입 변환
        Animal animal = null;
        animal = new Dog();
        animal.sound();
        animal = new Cat();
        animal.sound();
        System.out.println("--------");

        //메서드의 다형성
        animalSound(new Dog());
        animalSound(new Cat());
    }

    public static void animalSound(Animal animal){
        animal.sound();

    }
}

추상 클래스의 작성

  • 여러 클래스에 공통적으로 사용될 수 있는 클래스를 바로 작성하기도 하고
  • 기존 클래스의 공통적인 부분을 뽑아서 추상 클래스로 만들어 상속

예시

위의 경우 stop메서드는 선언부 구현부 모두 공통이지만
Marine, Tank는 지상 유닛이고 Dropship은 공중유닛이기 때문에 이동하는 방법이 달라서 move메서드는 구현부는 다를 것이다.(선언부는 같기 때문에 추상메서드로 정의할 수 있다.)

즉 각 클래스의 공통부분을 뽑아 Unit클래스를 만들고, 이 클래스를 상속받아서 자신의 클래스에 맞게 구현하면 된다!

abstract class Unit {
    int x, y;

    abstract void move(int x, int y);

    void stop() {
    }
}

class Marine extends Unit {
    void move(int x, int y) {
        System.out.println("Marine[x=" + x + ",y=" + y + "]");
    }

    void stimPack() {
    }
}

class Tank extends Unit{
    void move(int x, int y){
        System.out.println("Tank[x=" + x + ",y=" + y + "]");
    }
    void changeMode() {
    }
}

class Dropship extends Unit {
    void move(int x, int y) {
        System.out.println("Dropship[x=" + x + ",y=" + y + "]");
    }

    void load() {
    }

    void unload() {
    }
}

public class AbstractEx{
    public static void main(String[] args) {
        Unit[] group = {new Marine(), new Tank(), new Dropship()};
        //Unit배열 타입 
        
        //Unit[] group = new Unit[3];
       // group[0] = new Marine();
        //group[1] = new Tank();
        //group[2] = new Dropship();
        //객체 변수를 묶은 객체 배열
        
        for (int i = 0; i < group.length; i++)
            group[i].move(100, 200); //group의 타입은 Unit[]. group[]은 참조변수
    }
}
profile
github blog 쓰다가 관리하기 귀찮아서 돌아왔다

0개의 댓글

Powered by GraphCDN, the GraphQL CDN