새소식

JAVA

자바 기초 : 추상 클래스

  • -

핵심개념

  • 추상 : 실체 간의 공통되는 특성을 추출한 것.
    ex) 고양이, 강아지, 새의 공통되는 특성을 추출할 시 동물이라 공통점이 있음. 여기서 동물이 실체들의 공통되는 특성을 가지고 있는 추상적인 것.

  • 실체클래스 : 객체를 직접 실행할 수 있는 클래스

  • 추상클래스 : 실체클래스들의 공통적인 특성(필드, 메소드)를 추출하여 선언한 것. 추상클래스와 실체클래스는 부모(추상) 자식(실체)클래스로서 상속 관계를 가짐.

  • 추상클래스의 용도
    1. 공통된 필드와 메소드의 이름을 통일할 목적 : 데이터와 기능이 동일함에도 불구하고 이름이 다르면 객체마다 사용방법이 달라지므로.
    2. 실체 클래스를 작성할 때 시간 절약 : 공통적인 필드와 메소드는 추상클래스에 선언, 다른 점만 실체클래스에 선언 시 실체 클래스 작성 시간 절약 가능

  • 추상클래스의 선언 : 클래스 선언이 abstract를 붙여야한다. abstract를 붙일 시 new연산자를 이용해서 객체를 만들지 못하고, 상속을 통해 자식 클래스만 만들 수 있다.(부모로서의 역할만 수행). new연산자로 직접 객체를 생성할 수는 없지만, 자식 객체가 생성될 때 super(...)의 형태로 추상클래스의 객체를 생성할 수 있다.
    추상 클래스도 일반 클래스와 마찬가지로 필드, 생성자, 메소드를 선언할 수 있다.
    ex) public abstract class 클래스{
          //필드
          //생성자
          //메소드
          }
public abstract class Phone {
   //필드
   public String owner;
   //생성자
   public Phone(String owner) {
      this.owner = owner;
   }
   //메소드
   public void turnOn() {
      System.out.println("폰 전원을 켭니다.");
   }
   public void turnOff() {
      System.out.println("폰 전원을 끕니다.");
   }
}

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

public class SmartPhone extends Phone {
   //추상 클래스를 상속받아 실체 클래스 생성
   //생성자
   public SmartPhone(String owner) {
   super(owner);//Phone의 생성자 호출
   }
   //메소드
   public void internetSearch() {
      System.out.println("인터넷 검색을 합니다.");
   }
}

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

public class PhoneEx {
   public static void main(String[] args) {
   //Phone phone = new Phone("김자바"); (x)
   //추상클래스의 생성자를 호출해 객체를 생성할 수 없다.
   //자식클래스의 객체를 생성해 추상클래스의 메소드 사용 가능

      SmartPhone smartPhone = new SmartPhone("김자바");

      smartPhone.turnOn(); //Phone의 메소드
      smartPhone.internetSearch();
      smartPhone.turnOff(); //Phond의 메소드
   }
}
실행결과 : 
폰 전원을 켭니다.
인터넷 검색을 합니다.
폰 전원을 끕니다.

 

  • 추상 메소드와 재정의 : 메소드의 선언만 통일하고, 실행 내용은 실체 클래스마다 달라야하는 경우에 추상 클래스는 추상 메소드를 선언할 수 있다. 추상 메소드는 abstract 키워드로 선언되고 메소드 실행 내용인 중괄호가 없는 메소드이다. 추상 클래스 설계 시 반드시 실행내용을 채우도록 강제하고 싶은 메소드가 있을 경우 해당 메소드를 추상메소드로 선언하고, 하위클래스에서 재정의하여 실행내용을 채워야 컴파일 오류가 발생하지 않는다.
    ex)[public 또는 protected] abstract 리턴타입 메소드이름(매개변수,...);

    ex)동물이 소리를 낸다는 공통적인 특징 규정하기 위한 추상메소드
         public abstract class Animal {
            public abstract void sound();
         }
public abstract class Animal { //추상클래스
   public String kind;

   public void breathe() {
      System.out.println("숨을 쉽니다.");
   }
   public abstract void sound(); //추상메소드
}

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

public class Dog extends Animal{
   public Dog() {
      this.kind = "포유류";
   }
   @Override
   public void sound() {//추상메소드 재정의
      System.out.println("멍멍");
   }
}

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

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

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

public class AnimalEx {
   public static void main(String[] args) {
     //일반적인 방식으로 Dog와 Cat변수 호출
      Dog dog = new Dog();
      Cat cat = new Cat();
      dog.sound();
      cat.sound();
      System.out.println("-----");

     //변수의 자동 타입 변환
     //Animal변수로 타입 변환해서 sound()메소드 호출. 자식은 부모타입으로 자동타입변환
      Animal animal = null;
      animal = new Dog();
      animal.sound();
      animal = new Cat();
      animal.sound();
      System.out.println("-----");

      //메소드의 다형성
     /*부모타입의 매개변수에 자식 객체를 대입하여 메소드의 다형성 적용.
     자식 객체가 부모 타입으로 자동변환되어 재정의된 sound()메소드가 호출*/
     animalSound(new Dog());
     animalSound(new Cat());
     }
   public static void animalSound(Animal animal) {
   animal.sound();//재정의된 메소드 호출
   }
}
실행결과 : 
멍멍
야옹
-----
멍멍
야옹
-----
멍멍
야옹

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.