JavaRush /Java Blog /Random-KO /구체적인 예가 포함된 Java의 추상 클래스

구체적인 예가 포함된 Java의 추상 클래스

Random-KO 그룹에 게시되었습니다
안녕하세요! 이전 강의에서 우리는 인터페이스에 대해 알아보고 인터페이스 가 필요한 것이 무엇인지 파악했습니다. 오늘의 주제는 이전 주제와 공통점이 있습니다. Java의 추상 클래스 에 대해 이야기해 보겠습니다 .구체적인 예가 포함된 Java의 추상 클래스 - 1

클래스를 "추상"이라고 부르는 이유

아마도 "추상화"가 무엇인지 기억하실 겁니다. 우리는 이미 다루었습니다 :) 갑자기 잊어버리셨다면 괜찮습니다. 기억해두세요: 이것이 OOP의 원칙입니다 . 클래스를 디자인하고 객체를 생성할 때 강조해야 할 점은 다음과 같습니다. 엔터티의 주요 속성만 삭제하고 보조 속성은 삭제합니다. SchoolTeacher예를 들어, 학교 교사라는 학급을 설계하는 경우 " " 특성이 필요하지 않을 것입니다. 실제로 교사에게는 이러한 특성이 중요하지 않습니다. 그러나 프로그램에서 BasketballPlayer농구 선수라는 클래스를 만들면 키가 주요 특징 중 하나가 될 것입니다. 따라서 추상 클래스는 미래 클래스 그룹에 대해 가장 추상적이고 매우 근사한 "공백"입니다. 이 준비는 완성된 형태로 사용할 수 없습니다. 너무 "원시"입니다. 그러나 이는 미래의 클래스(추상 클래스의 상속자)가 갖게 될 특정한 일반적인 상태와 동작을 설명합니다.

Java 추상 클래스 예

자동차에 대한 간단한 예를 살펴보겠습니다.
public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public abstract void gas();

   public abstract void brake();

   public String getModel() {
       return model;
   }

   public void setModel(String model) {
       this.model = model;
   }

   public String getColor() {
       return color;
   }

   public void setColor(String color) {
       this.color = color;
   }

   public int getMaxSpeed() {
       return maxSpeed;
   }

   public void setMaxSpeed(int maxSpeed) {
       this.maxSpeed = maxSpeed;
   }
}
이것이 가장 간단한 추상 클래스의 모습입니다. 보시다시피 특별한 것은 없습니다. :) 무엇을 위해 필요한가요? 우선, 그는 우리에게 필요한 실체를 가능한 한 추상적으로 설명합니다. 바로 자동차입니다. 추상이라는 단어가 여기에 나온 데에는 이유가 있습니다. 세상에 '그냥 기계'는 없습니다. 트럭, 경주용 자동차, 세단, 쿠페, SUV가 있습니다. 우리의 추상 클래스는 나중에 자동차 클래스를 생성할 단순한 "청사진"입니다.
public class Sedan extends Car {

   @Override
   public void gas() {
       System.out.println("The sedan accelerates!");
   }

   @Override
   public void brake() {
       System.out.println("The sedan slows down!");
   }

}
이것은 상속에 관한 강의에서 이야기했던 것과 매우 유사합니다. Car거기에만 추상이 아닌 클래스와 해당 메서드가 있었습니다 . 그러나 이 솔루션에는 여러 가지 단점이 있으며 이는 추상 클래스에서 수정됩니다. 무엇보다도 추상 클래스의 인스턴스를 만들 수 없습니다.
public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Error! The Car class is abstract!
   }
}
이 "트릭"은 Java 제작자가 특별히 구현한 것입니다. 다시 한 번 기억하세요. 추상 클래스는 미래의 "일반" 클래스에 대한 청사진일 뿐입니다 . 도면 사본은 필요하지 않죠? 따라서 추상 클래스의 인스턴스를 만들 필요가 없습니다 :) 그리고 클래스가 Car추상이 아닌 경우 해당 객체를 쉽게 만들 수 있습니다.
public class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       // some logic
   }

   public  void brake() {
       // some logic
   }
}


public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Everything is OK, the machine has been created
   }
}
이제 우리 프로그램에는 트럭도, 경주용 자동차도, 세단도 아닌 일반적인 자동차가 아닌 일종의 이상한 자동차가 있습니다. 자연에는 존재하지 않는 동일한 "단순한 기계"입니다. 동물에게도 같은 예를들 수 있습니다. 프로그램에 개체가 Animal" 단지 동물 "로 나타나는지 상상해 보십시오. 그것이 어떤 유형인지, 어떤 가족에 속해 있는지, 어떤 특징을 가지고 있는지는 명확하지 않습니다. 그를 프로그램에서 보는 것은 이상할 것이다. 자연에는 '단지 동물'이 없습니다. 개, 고양이, 여우, 두더지 등만 해당됩니다. 추상 클래스는 우리를 " 단순한 객체 "로부터 해방시켜줍니다. 이는 우리에게 기본적인 상태와 동작을 제공합니다. 예를 들어, 모든 자동차에는 모델 , 색상 , 최대 속도가 있어야 하며 주유제동 도 가능해야 합니다 . 그게 다야. 이것은 일반적인 추상 체계이며 필요한 클래스를 직접 디자인합니다. 참고: 추상 클래스의 두 메서드도 abstract 로 지정되며 전혀 구현되지 않습니다. 이유는 동일합니다. 추상 클래스는 "단순한 기계"에 대한 "기본 동작"을 생성하지 않습니다. 그들은 단지 모든 자동차를 만들 수 있어야 한다고 말합니다. 그러나 여전히 기본 동작이 필요한 경우 추상 클래스에서 메서드를 구현할 수 있습니다. Java는 다음을 금지하지 않습니다.
public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       System.out.println("Let's go!");
   }

   public abstract void brake();

   //getters and setters
}


public class Sedan extends Car {

   @Override
   public void brake() {
       System.out.println("The sedan slows down!");
   }

}

public class Main {

   public static void main(String[] args) {

       Sedan sedan = new Sedan();
       sedan.gas();
   }
}
콘솔 출력: "가속해 보세요!" 보시다시피 추상 클래스에 한 가지 메서드를 구현했지만 두 번째 메서드는 구현하지 않았습니다. 결과적으로 우리 클래스의 동작은 Sedan두 부분으로 나누어졌습니다. 즉, 클래스에 대한 메서드를 호출하면 gas()상위 추상 클래스에서 "풀업"되고 Car클래스 brake()에서 메서드를 재정의합니다 Sedan. 매우 편리하고 유연한 것으로 나타났습니다. 그런데 이제 우리 수업은 그렇게 추상적이지 않나요 ? 실제로 그의 방법 중 절반이 구현되었습니다. 사실 - 이것은 매우 중요한 특징입니다. 클래스의 메소드 중 적어도 하나가 추상이면 클래스는 추상입니다 . 적어도 두 가지 방법 중 하나, 천 가지 방법 중 적어도 하나는 중요하지 않습니다. 모든 메소드를 구현하고 추상 메소드를 남기지 않을 수도 있습니다. 추상 메소드가 없는 추상 클래스가 있을 것입니다. 원칙적으로 이것은 가능하며 컴파일러는 오류를 생성하지 않지만 이렇게 하지 않는 것이 좋습니다. abstract라는 단어는 의미를 잃게 되며 동료 프로그래머는 이를 보고 매우 놀라게 될 것입니다 . abstract라는 단어가 표시되어 있으면 각 하위 클래스는 abstract를 구현하거나 선언해야 합니다. 그렇지 않으면 컴파일러에서 오류가 발생합니다 . 물론 각 클래스는 하나의 추상 클래스에서만 상속받을 수 있으므로 상속 측면에서는 추상 클래스와 일반 클래스 사이에 차이가 없습니다. 추상 클래스에서 상속을 받든 일반 클래스에서 상속을 받든 상관없이 부모 클래스는 하나만 있을 수 있습니다.

Java에 다중 클래스 상속이 없는 이유는 무엇입니까?

우리는 이미 Java에는 다중 상속이 없다고 말했지만 실제로 그 이유를 파악하지는 못했습니다. 지금 시도해 보겠습니다. 요점은 Java에 다중 상속이 있는 경우 하위 클래스가 어떤 동작을 선택할지 결정할 수 없다는 것입니다. Toster두 개의 클래스 가 있다고 가정해 보겠습니다 NuclearBomb.
public class Toster {


 public void on() {

       System.out.println("The toaster is on, the toast is getting ready!");
   }

   public void off() {

       System.out.println("The toaster is off!");
   }
}


public class NuclearBomb {

   public void on() {

       System.out.println("Взрыв!");
   }
}
보시다시피 둘 다 메소드가 있습니다 on(). 토스터의 경우 토스트 요리를 시작하고, 핵폭탄의 경우 폭발을 일으킨다. 오 :/ 이제 그 사이에 무언가를 만들기로 결정했다고 상상해 보세요(갑자기 왜인지는 모르겠습니다!). 그리고 여기 당신의 수업이 있습니다 - MysteriousDevice! 물론 이 코드는 작동하지 않으며 단순히 "어떻게 될 수 있는지"에 대한 예를 제시합니다.
public class MysteriousDevice extends Toster, NuclearBomb {

   public static void main(String[] args) {

       MysteriousDevice mysteriousDevice = new MysteriousDevice();
       mysteriousDevice.on(); // And what should happen here? Will we get a toast, or a nuclear apocalypse?
   }
}
우리가 무엇을 얻었는지 봅시다. 신비한 장치는 토스터와 핵폭탄에서 나옵니다. 둘 다 메소드를 가지고 있으므로 on()결과적으로 on()객체를 MysteriousDevice호출할 경우 어떤 메소드가 객체에서 실행되어야 하는지 명확하지 않습니다. 객체는 이것을 이해할 수 없습니다. 글쎄, 케이크 위의 체리처럼: 핵폭탄에는 방법이 없습니다 off(). 따라서 우리가 잘못 추측하면 장치를 끌 방법이 없습니다. 구체적인 예가 포함된 Java의 추상 클래스 - 2 객체가 어떤 동작을 선택해야 하는지 불분명할 때 Java 개발자가 다중 상속을 포기한 것은 바로 이러한 혼란 때문입니다. 그러나 Java 클래스는 많은 인터페이스를 구현한다는 것을 기억할 것입니다. 그건 그렇고, 당신은 이미 공부에서 적어도 하나의 추상 수업을 접했습니다! 그래도 눈치 채지 못했을 수도 있습니다 :)
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>
이것은 당신의 오랜 친구 수업입니다 Calendar. 그것은 추상적이며 여러 상속인이 있습니다. 그 중 하나는 입니다 GregorianCalendar. 날짜에 대한 강의에서 이미 사용하셨습니다 :) 모든 것이 명확한 것 같습니다. 남은 점은 단 하나입니다. 추상 클래스와 인터페이스의 근본적인 차이점은 무엇입니까 ? 왜 그들은 둘 다 Java에 추가하고 하나만으로 제한하지 않았습니까? 이것으로 충분할 수 있습니다. 이에 대해서는 다음 강의에서 다루겠습니다! 또 봐요:)
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION