티스토리 뷰

Java

자바 - 추상 클래스 개념 정리

Kodong's blog 2025. 10. 17. 21:21

자바에서, 추상 클래스를 언제 사용하는지는 체스 게임을 만들면서 공부를 해놓고, 이후, 제대로 추상 클래스, super키워드를 활용해본적이 없는 것 같아 오늘 혼자서 추상클래스, super 키워드로 좀 두들겨 보았다.

 

이렇게 두들기면서 공부한 자바 추상 클래스 개념의 빵꾸(?)부터 정리하고 가겠다.

( 중요하다기 보다는, 내가 몰랐던 문법 지식을 남기는 거다. 안 중요하다는 의미는 아니다 ㅋㅋ )

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

( 2026/3/8 수정 및 추가) 

🟩 추상 클래스

객체를 생성할 수 있는 클래스를 실체 클래스라고 한다면, 이 클래스들의 공통적인 필드나 메서드를 추출해서 선언한 클래스를 추상 클래스라고 한다. 

추상 클래스는 실체 클래스의 공통되는 필드와 메서드를 추출해서 만들었기 때문에,

new 연산자를사용해서 객체를 직접 생성할 수 없다

Animal animal = new Animal(); // XXX

 

또 추상 클래스는 새로운 실체 클래스를 만든기 위한 부모 클래스로만 사용된다. 

즉, 추상 클래스는 extends뒤에만 올 수 있다

아래는 추상 클래스를 선언하는 방법이다. 클래스 선언에 abstract 키워드를 붙이면 된다.

public abstract class Phone {
	String owner;
    
    public Phone(String owner) {
    	this.owner = owner;
    }
    
    public void turnOn() {
    	// turn on ...
    }

	public void turnOff() {
    	// turn off ...
    }
    
}
public class SmartPhone extends Phone {
	SmartPhone(String owner) {
    	super(owner)
    }
    
    void search() {
    	// ...
   	}

}

 

이제 추상 메소드에 대해서 이야기 해보자.

🔵 추상 메서드

자식들이 가지고 있는 공통 메서드를 뽑아내어 추상 클래스로 작성할 때,

메소드 선언부만 동일하고, 실행 내용은 자식 클래스마다 달라야하는 경우에 추상 메소드를 사용한다. 

 

일반 메서드와 추상 메서드의 차이점은 abstract 키워드가 붙고, 메소드 실행 내용인 중괄호{}가 없다. 

추상 클래스는 자식 클래스에서 반드시 오버라이딩해서 실행 내용을 채워야한다

자식 클래스는 부모 추상 클래스의 모든 추상 매서드를 재정의해야한다

아래는 추상 메서드의 사용 예시이다. 

abstract class Animal {
    String type;

    public Animal(String type) {
        this.type = type;
    }
    abstract void sound();
}

class Dog extends Animal {
    public Dog(String type) {
        super(type);
    }

    @Override
    public void sound() {
        System.out.println(type + "이 소리를 낸다!");
    }

}

class Cat extends Animal {
    public Cat(String type) {
        super(type);
    }

    @Override
    public void sound() {
        System.out.println(type + "이 소리를 낸다!");
    }
}

class Main {
    public static void main(String[] args) {
        Cat cat = new Cat("cat");
        cat.sound();

        Dog dog = new Dog("dog");
        dog.sound();
    }
}

 

( 여기까지 추가한 내용. 아래부터는 기존의 글 내용이다. 솔직히 삭제해도 될 것같긴하지만, 1년 전의 나의 맨땅의 헤딩 기록이어서 놔두겠다 ㅎㅎ)

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

 

1. @Override 를 사용해서 메서드 재정의 시, 접근 제어자, 반환 타입, 메서드명까지 하나도 빠짐없이 써줘야한다. (부모 클래스의 부모 메서드와 같게 적어줘야한다)

예시 코드를 작성해보겠다. 

package main;

public class Application {
    public static void main(String[] args) {
        
        Child child = new Child();
        child.printName();

    }
}

class Parent {
    String name = "parent3123344323";

    public void printName() {
        System.out.println(name);
    }
}

class Child extends Parent {
    String name = "child234342434";

    @Override
    public void printName() {
        System.out.println(name);
    }

}

이 코드에서는 Parent라는 클래스에 있는 printName 이라는 메서드를 Child 클래스에서 오버라이딩 한 코드이다.

즉, 내가 말하고자 하는 점은,

오버라이딩을 하더라도, 접근 제어자(public), 출력 형식(void) 를 적어줘야한다는 의미이다.

 

2. 필드에는 abstract를 적으면 안된다.

간단하게 설명을 해보겠다.

abstract 키워드의 의미가 무엇인지 부터 떠올려 보자. "나중에 자식 클래스에서 구현하세요!!" 라는 의미이다. 

즉, 구현부(  {} 내부 코드 )가 없다는 의미이다.

 

하지만, 필드에 "나중에 구현하세요!"라는 말이 성립이 되나? 

애초에 필드에는 구현부라는 것이 없다.

필드는 단순히 값을 저장하는 클래스 변수(static 변수 또는 공유 변수) 또는 인스턴스 변수이다.

이미 값이 저장되어 있는데, 구현하라는 의미? 말이 안된다. 

 

3. 자식 클래스는 부모 클래스의 멤버를 모두 가지게 됨! ( private 멤버 제외!! )

간단하게 설명해보자면,

 

 

이렇게 만들어진 클래스에서, private멤버(state3)를 제외한 나머지 멤버들(state1, state2)을 상속한 자식 클래스에서 사용할 수 있다는 말이다.

 

 

여기까지 내용으로 간단한 예제를 만들어 보았다. 

package main;

abstract public class Animal {

    public Boolean isAlive = true;
    abstract public void run();
    abstract public void eat();
    abstract public void sound();

}


class Dog extends Animal {

    String name;

    public Dog(String name) {
        this.name = name;
    }

    @Override
    public void sound() {
        System.out.println(this.name + " is barking!");
    }

    @Override
    public void run() {
        System.out.println(this.name + " is running!");
    }

    @Override
    public void eat() {
        System.out.println(this.name + " is eating!");
    }

    public void sayAlive() {
        System.out.println(this.isAlive);
    }

}

 

package main;

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

        Dog dog = new Dog("asdf");
        dog.sayAlive();
        dog.sound();
        dog.eat();
        dog.run();

    }
}

 

(그냥 코드만 보고 이해하면 충분하다고 생각한다)

( 굳이 설명을 하자면, 추상 클래스에 있는 추상 메서드( run(), eat(), sound()를 자식 클래스에서 구현한 코드이다 )

 

또 뭔가 extends 키워드는 abstract 클래스에만 써야하는지도 궁금증이 들었다. 

이에 대해서도 간단하게 정리해보았다. 

extends 키워드는 말그대로 부모 클래스를 상속한다는 의미이고( 해당 부모 클래스가 일반 클래스인지, abstract 클래스인지와는 상관 없이), abstract 키워드는 해당 클래스를 추상 클래스로 만들어, oop의 계층성을 이용하기 위해 사용한다. 쉽게 말하자면, 부모 클래스에 자식 클래스들이 구현해야하는 "틀"을 만든다는 점에서 의미가 있다.

쉽게 말해서 abstract클래스 뿐만 아닌, 일반 클래스에도 사용할 수 있다. 

 

 

( 참고한 글 ↓ )

@Override 어노테이션의 의미와 사용 이유는 무엇일까?

 

@Override 어노테이션의 의미와 사용 이유는 무엇일까?

어노테이션은 JDK5 부터 등장하였으며, 클래스나 메서드, 변수에 @을 사용하는 것을 말합니다.어노테이션은 사전적 의미로 주석을 뜻합니다. 주석과는 역할이 다르지만, 주석처럼 달아 특수한 의

velog.io

자바 extends, implements 차이

 

자바 extends, implements 차이

상속이란 (Inheritance) 상속을 말하기 전에 먼저 OOP가 무엇인지 알면 좋을거 같다.OOP(Object-Oriented Programming, 객체 지향 프로그래밍) 이란? OOP의 특징으로 1. 상속과 인터페이스 (계층성) 2. 다형성, 사

velog.io

 

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

여기까지.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG more
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함