[java] 자바의 추상 클래스
Java에서 “추상 클래스”란 무엇입니까?
답변
추상 클래스는 인스턴스화 할 수없는 클래스입니다. 추상 클래스는 인스턴스화 할 수 있는 상속 서브 클래스를 작성하여 사용됩니다 . 추상 클래스는 상속 서브 클래스에 대해 몇 가지 작업을 수행합니다.
- 상속 서브 클래스에서 사용할 수있는 메소드를 정의하십시오.
- 상속 서브 클래스가 구현해야하는 추상 메소드를 정의하십시오.
- 서브 클래스를 다른 모든 서브 클래스와 교환 할 수있는 공통 인터페이스를 제공하십시오.
예를 들면 다음과 같습니다.
abstract public class AbstractClass
{
abstract public void abstractMethod();
public void implementedMethod() { System.out.print("implementedMethod()"); }
final public void finalMethod() { System.out.print("finalMethod()"); }
}
“abstractMethod ()”에는 메소드 본문이 없습니다. 이로 인해 다음을 수행 할 수 없습니다.
public class ImplementingClass extends AbstractClass
{
// ERROR!
}
구현하는 메소드가 없습니다 abstractMethod()
! 따라서 JVM이 다음과 같은 것을 얻을 때 수행해야 할 작업을 알 수있는 방법이 없습니다 new ImplementingClass().abstractMethod()
.
올바른 내용은 다음과 같습니다 ImplementingClass
.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
}
implementedMethod()
또는 을 정의 할 필요는 없습니다 finalMethod()
. 이미에 의해 정의되었습니다 AbstractClass
.
또 다른 올바른 것이 ImplementingClass
있습니다.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
}
이 경우을 재정의했습니다 implementedMethod()
.
그러나 final
키워드로 인해 다음이 불가능합니다.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
public void finalMethod() { System.out.print("ERROR!"); }
}
finalMethod()
in AbstractClass
구현이 최종 구현으로 표시되어 있기 때문에이 작업을 수행 할 수 없습니다 finalMethod()
. 다른 구현은 절대 허용되지 않습니다.
이제 추상 클래스를 두 번 구현할 수도 있습니다 .
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
}
// In a separate file.
public class SecondImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("second abstractMethod()"); }
}
이제 어딘가에 다른 방법을 쓸 수 있습니다.
public tryItOut()
{
ImplementingClass a = new ImplementingClass();
AbstractClass b = new ImplementingClass();
a.abstractMethod(); // prints "abstractMethod()"
a.implementedMethod(); // prints "Overridden!" <-- same
a.finalMethod(); // prints "finalMethod()"
b.abstractMethod(); // prints "abstractMethod()"
b.implementedMethod(); // prints "Overridden!" <-- same
b.finalMethod(); // prints "finalMethod()"
SecondImplementingClass c = new SecondImplementingClass();
AbstractClass d = new SecondImplementingClass();
c.abstractMethod(); // prints "second abstractMethod()"
c.implementedMethod(); // prints "implementedMethod()"
c.finalMethod(); // prints "finalMethod()"
d.abstractMethod(); // prints "second abstractMethod()"
d.implementedMethod(); // prints "implementedMethod()"
d.finalMethod(); // prints "finalMethod()"
}
우리가 선언에도 불구하고 있음을 공지 유형에서 표시 . 우리가 인스턴스화 된 객체가 실제로이었다 때문입니다 누구는 물론 오버라이드 (override)이다. (이것을 다형성이라고합니다.)b
AbstractClass
"Overriden!"
ImplementingClass
implementedMethod()
특정 하위 클래스에 특정한 멤버에 액세스하려면 먼저 해당 하위 클래스로 캐스트해야합니다.
// Say ImplementingClass also contains uniqueMethod()
// To access it, we use a cast to tell the runtime which type the object is
AbstractClass b = new ImplementingClass();
((ImplementingClass)b).uniqueMethod();
마지막으로 다음을 수행 할 수 없습니다.
public class ImplementingClass extends AbstractClass, SomeOtherAbstractClass
{
... // implementation
}
한 번에 하나의 수업 만 연장 할 수 있습니다. 여러 클래스를 확장해야하는 경우 인터페이스 여야합니다. 당신은 이것을 할 수 있습니다 :
public class ImplementingClass extends AbstractClass implements InterfaceA, InterfaceB
{
... // implementation
}
인터페이스 예는 다음과 같습니다.
interface InterfaceA
{
void interfaceMethod();
}
이것은 기본적으로 다음과 같습니다.
abstract public class InterfaceA
{
abstract public void interfaceMethod();
}
유일한 차이점은 두 번째 방법은 컴파일러가 실제로 인터페이스라는 것을 알리지 않는다는 것입니다. 사람들이 인터페이스 만 구현하고 다른 인터페이스는 구현하지 않으려는 경우에 유용 할 수 있습니다. 그러나 일반적인 초급 규칙으로 추상 클래스에 추상 메소드 만있는 경우 인터페이스로 만들어야합니다.
다음은 불법입니다 :
interface InterfaceB
{
void interfaceMethod() { System.out.print("ERROR!"); }
}
인터페이스에서 메소드를 구현할 수 없습니다. 이것은 두 개의 다른 인터페이스를 구현하면 해당 인터페이스의 다른 메소드가 충돌 할 수 없음을 의미합니다. 인터페이스의 모든 메소드는 추상이므로 메소드를 구현해야하며 메소드가 상속 트리에서 유일한 구현이므로 컴파일러는 메소드를 사용해야한다는 것을 알고 있습니다.
답변
Java 클래스는 다음과 같은 조건에서 요약됩니다.
1. 방법 중 하나 이상이 추상으로 표시됩니다.
public abstract void myMethod()
이 경우 컴파일러는 전체 클래스를 추상으로 표시하도록합니다.
2. 수업은 초록으로 표시됩니다.
abstract class MyClass
이미 말했듯이 : 추상 메소드가있는 경우 컴파일러는 전체 클래스를 추상으로 표시하도록 강제합니다. 그러나 추상 메서드가 없더라도 클래스를 추상으로 표시 할 수 있습니다.
일반적인 사용 :
추상 클래스의 일반적인 사용은 인터페이스와 유사한 클래스의 개요를 제공하는 것입니다. 그러나 인터페이스와 달리 이미 기능을 제공 할 수 있습니다. 즉, 클래스의 일부 부분이 구현되고 일부 부분은 메소드 선언으로 간략하게 설명됩니다. (“요약”)
추상 클래스는 인스턴스화 할 수 없지만 추상 클래스를 기반으로 구체적인 클래스를 생성 한 다음 인스턴스화 할 수 있습니다. 그렇게하려면 추상 클래스에서 상속하고 추상 메서드를 재정의해야합니다 (예 : 구현).
답변
abstract 키워드를 사용하여 선언 된 클래스 는로 알려져 있습니다 abstract class
. 추상화는 데이터 구현 세부 사항을 숨기고 사용자에게 기능 만 표시하는 프로세스입니다. 추상화를 사용하면 객체가 수행하는 방식 대신 객체가 수행하는 작업에 집중할 수 있습니다.
추상 클래스의 주요 사항
-
추상 클래스는 추상 메서드를 포함하거나 포함하지 않을 수 있습니다. 추상 클래스가 아닐 수 있습니다.
추상 메소드는 다음과 같이 구현없이 (중괄호없이 세미콜론으로) 선언 된 메소드입니다.
예 :
abstract void moveTo(double deltaX, double deltaY);
-
클래스에 추상 메소드가 하나 이상 있으면 해당 클래스는 추상적이어야합니다.
-
추상 클래스가 인스턴스화되지 않을 수 있습니다 (Abstract 클래스의 객체를 생성 할 수 없음)
-
추상 클래스를 사용하려면 다른 클래스에서 상속해야합니다. 모든 추상 메소드에 구현을 제공하십시오.
-
추상 클래스를 상속하면 모든 추상 메소드에 구현을 제공해야합니다.
추상 클래스abstract
선언 선언하는 동안 클래스 앞에 키워드를
지정 하면 추상이됩니다. 아래 코드를 살펴보십시오.
abstract class AbstractDemo{ }
추상 메서드abstract
선언 선언하는 동안 메서드 앞에 키워드를
지정 하면 추상이됩니다. 아래 코드를 살펴보십시오.
abstract void moveTo();//no body
수업을 추상화해야하는 이유
객체 지향 도면 응용 프로그램에서 원, 사각형, 선, 베 지어 곡선 및 기타 여러 그래픽 객체를 그릴 수 있습니다. 이러한 객체에는 모두 특정 상태 (예 : 위치, 방향, 선 색상, 채우기 색상)와 동작 (예 :-: 이동 위치, 회전, 크기 조정, 그리기)이 공통적으로 있습니다. 이러한 상태와 동작 중 일부는 모든 그래픽 객체에서 동일합니다 (예 : 채우기 색상, 위치 및 이동 위치). 다른 것들은 다른 구현이 필요합니다 (예 : 크기 조정 또는 그리기). 모든 그래픽 객체는 스스로 그림을 그리거나 크기를 조정할 수 있어야하며, 작동 방식이 다릅니다.
이것은 추상 슈퍼 클래스에게 완벽한 상황입니다. 유사성을 활용 GraphicObject
하고 다음 그림과 같이 동일한 추상 부모 개체 (예 : :)에서 상속하도록 모든 그래픽 개체를 선언 할 수 있습니다 .
먼저, GraphicObject
현재 위치 및 moveTo 메소드와 같은 모든 서브 클래스가 완전히 공유하는 멤버 변수 및 메소드를 제공하기 위해 추상 클래스를 선언합니다 . GraphicObject
또한 모든 서브 클래스에 의해 구현되어야하지만 다른 방식으로 구현되어야하는 draw 또는 resize와 같은 추상 메소드를 선언했습니다. GraphicObject
클래스는 다음과 같이 볼 수 있습니다 :
abstract class GraphicObject {
void moveTo(int x, int y) {
// Inside this method we have to change the position of the graphic
// object according to x,y
// This is the same in every GraphicObject. Then we can implement here.
}
abstract void draw(); // But every GraphicObject drawing case is
// unique, not common. Then we have to create that
// case inside each class. Then create these
// methods as abstract
abstract void resize();
}
서브 클래스에서의 추상 메소드 사용 and와 GraphicObject
같은
각각의 추상이 아닌 서브 클래스 는 and 메소드에 대한 구현을 제공해야합니다 .Circle
Rectangle
draw
resize
class Circle extends GraphicObject {
void draw() {
//Add to some implementation here
}
void resize() {
//Add to some implementation here
}
}
class Rectangle extends GraphicObject {
void draw() {
//Add to some implementation here
}
void resize() {
//Add to some implementation here
}
}
main
메소드 내부에서 다음과 같은 모든 메소드를 호출 할 수 있습니다.
public static void main(String args[]){
GraphicObject c = new Circle();
c.draw();
c.resize();
c.moveTo(4,5);
}
Java에서 추상화를 달성하는 방법
자바에서 추상화를 얻는 두 가지 방법이 있습니다
- 추상 클래스 (0 ~ 100 %)
- 인터페이스 (100 %)
생성자, 데이터 멤버, 메소드 등이있는 추상 클래스
abstract class GraphicObject {
GraphicObject (){
System.out.println("GraphicObject is created");
}
void moveTo(int y, int x) {
System.out.println("Change position according to "+ x+ " and " + y);
}
abstract void draw();
}
class Circle extends GraphicObject {
void draw() {
System.out.println("Draw the Circle");
}
}
class TestAbstract {
public static void main(String args[]){
GraphicObject grObj = new Circle ();
grObj.draw();
grObj.moveTo(4,6);
}
}
산출:
GraphicObject is created
Draw the Circle
Change position according to 6 and 4
두 가지 규칙을 기억하십시오.
-
클래스에 추상 메소드와 구체적인 메소드가 거의없는 경우 클래스로 선언하십시오
abstract
. -
클래스에 추상 메소드 만있는 경우이를로 선언하십시오
interface
.
참고 문헌 :
답변
인스턴스화 할 수없는 클래스이며 클래스를 구현하면 개요가있는 추상적 인 메소드를 구현해야합니다.
답변
간단히 말해서, 추상 클래스는 약간 더 많은 기능을 가진 인터페이스처럼 생각할 수 있습니다.
추상 클래스를위한 인터페이스도 인스턴스화 할 수 없습니다.
인터페이스에서 메소드 헤더를 정의하면 모든 구현자가 강제 로 모든 헤더 를 구현 해야 합니다. 추상 클래스에서 메소드 헤더를 정의 할 수도 있지만 여기서는 인터페이스의 차이점에 따라 메소드의 본문 (일반적으로 기본 구현)을 정의 할 수도 있습니다. 또한 다른 클래스가 추상 클래스를 확장 (구현하지 않고 따라서 자식 클래스 당 하나의 추상 클래스 만 가질 수 있음 ) 할 때 추상 메소드 를 지정하지 않는 한 추상 클래스의 모든 메소드를 강제로 구현하지는 않습니다 ( 이 경우 인터페이스와 같이 작동하며 메소드 본문을 정의 할 수 없습니다).
public abstract class MyAbstractClass{
public abstract void DoSomething();
}
그렇지 않은 경우 추상 클래스의 일반 메서드의 경우 “상속자”는 기본 동작을 사용하거나 평소처럼 재정의 할 수 있습니다.
예:
public abstract class MyAbstractClass{
public int CalculateCost(int amount){
//do some default calculations
//this can be overriden by subclasses if needed
}
//this MUST be implemented by subclasses
public abstract void DoSomething();
}
답변
오라클 문서에서
추상 방법 및 클래스 :
추상 클래스는 추상으로 선언 된 클래스이며 추상 메소드를 포함하거나 포함하지 않을 수 있습니다.
추상 클래스는 인스턴스화 할 수 없지만 서브 클래스 화는 가능합니다
추상 메소드는 다음과 같이 구현없이 (중괄호없이 세미콜론으로) 선언 된 메소드입니다 .
abstract void moveTo(double deltaX, double deltaY);
클래스에 추상 메소드가 포함 된 경우 클래스 자체는 다음과 같이 추상으로 선언되어야합니다.
public abstract class GraphicObject {
// declare fields
// declare nonabstract methods
abstract void draw();
}
추상 클래스가 서브 클래 싱 될 때, 서브 클래스는 일반적으로 부모 클래스의 모든 추상 메소드에 대한 구현을 제공합니다. 그러나 그렇지 않은 경우 서브 클래스도 abstract로 선언해야합니다. .
이후 abstract classes
및interfaces
관련, SE 질문 아래를 보라 :
답변
여기에 답을 얻으십시오.
BTW-최근 질문 한 내용입니다. 명성을 쌓기위한 새로운 질문에 대해 생각해보십시오.
편집하다:
이 포스터와 참조 된 질문의 이름은 같거나 최소한 비슷한 이름이지만 user-id는 항상 다릅니다. 따라서 기술적 인 문제가 있습니다. keyur가 다시 로그인하는 데 문제가 있고 그의 질문에 대한 답을 찾는 데 어려움이 있거나 SO 커뮤니티를 즐겁게하는 일종의 게임입니다.)