"자바 프로그래밍 로직"5 장 클래스 확장

5 장 클래스 확장

5 장은 주로 인터페이스, 추상 클래스, 내부 클래스 및 열거를 소개합니다.

인터페이스의 특성

대부분의 경우 우리가 관심을 갖는 것은 개체의 유형이 아니라 개체의 능력입니다. 개체의 유형에 관계없이 특정 능력을 제공하려면 개체가 필요합니다. 인터페이스 는 개체가 제공 할 수있는 기능을 설명하는 데 사용됩니다.

인터페이스는 기능 집합을 선언하지만이 기능을 자체적으로 구현하지는 않으며 단지 관례 일뿐입니다. 인터페이스는 두 당사자의 객체 상호 작용을 포함합니다. 한 당사자는이 인터페이스를 구현해야하고 다른 당사자는이 인터페이스를 사용하지만 두 당사자는 서로 직접적으로 의존하지 않고 인터페이스를 통해 간접적으로 만 상호 작용합니다.

인터페이스의 정의는 interface키워드를 사용 합니다. 다음과 같이

public interface MyComparable {
    
    
    int compareTo(Object other);
}

Java 8 이전에는 메소드를 인터페이스에서 구현할 수 없으며 인터페이스 메소드는 수정자를 추가 할 필요가 없으며 기본값은 공용 추상입니다.

클래스는 인터페이스를 구현하여 클래스의 객체에 인터페이스가 나타내는 기능이 있음을 나타낼 수 있습니다. 인터페이스 implements구현하려면 키워드를 사용하십시오 .

public class Point implements MyComparable{
    
    
    ...
   @Override
    public int compareTo(Object other) {
    
    
        ...
    }
}

인터페이스를 구현하려면 클래스의 인터페이스에 의해 정의 된 메서드를 재정의해야합니다. 제네릭을 사용할 때 instanceof불필요한 오류를 피하기 위해 객체 유형을 확인하는 데 사용해야 합니다.

클래스는 여러 인터페이스를 구현하여 클래스의 개체에 여러 기능이 있음을 나타낼 수 있습니다.

public class Test implements interface1, interface2{
    
    
    
}

인터페이스는 new인터페이스 객체를 생성하는 데 사용할 수 없습니다 . 인터페이스를 사용하는 유일한 방법은 클래스를 통해 인터페이스를 구현 한 다음이 클래스의 객체를 생성하고 객체의 인터페이스 메소드를 호출하는 것입니다. 인터페이스를 구현하는 객체는 부모 클래스와 자식 클래스 간의 관계와 유사하게 인터페이스 유형의 변수에 할당 될 수 있습니다.

이것이 인터페이스의 힘이있는 곳입니다. 객체의 유형, 즉 인터페이스 지향 프로그래밍의 아이디어없이 객체의 기능을 균일하게 고려할 수 있습니다.

더 중요한 것은 인터페이스가 결합을 줄이고 유연성을 향상 시킨다는 것입니다. 인터페이스를 사용하는 코드는 인터페이스의 특정 유형이 아니라 인터페이스 자체에 의존하며, 프로그램은 분리 된 사용자에게 영향을주지 않고 상황에 따라 인터페이스 구현을 대체 할 수 있습니다.

인터페이스에서 변수를 정의 할 수 있지만 변수 유형은 다음과 같습니다.public static final

public interface Interface1{
    
    
    public static final int a = 0;
}

인터페이스는 상속 될 수 있으며 클래스 상속과 달리 인터페이스 상속은 다중 상속을 지원합니다.

public interface IBase1{
    
    
    void method1();
}

public interface IBase2{
    
    
    void method2();
}

public interface IChild extends IBase1, IBase2{
    
    
    
}

클래스 상속과 구현 인터페이스는 공존 할 수 있습니다.

public class Child extends Base implements IChild{
    
    
    
}

인터페이스는 instanceof키워드를 사용 하여 객체가 특정 인터페이스를 구현하는지 여부를 결정할 수도 있습니다 .

Point p = new Point();
if( p instanceof MyComparable) {
    
    
    
}

인터페이스와 컴포지션을 사용하여 상속을 효과적으로 대체 할 수 있습니다.

추상 클래스

추상 클래스는 추상 클래스입니다. 추상화는 구체적으로 상대적입니다. 일반적으로 구체적 클래스는 직접적으로 대응하는 객체를 가지고 있지만 추상 클래스에는없는 것으로 그래픽 클래스 Shape와 같은 추상적 인 개념을 표현합니다. 추상 개념의 메서드는 일반적으로 추상 메서드로 정의됩니다. 예를 들어 추상 클래스의 draw메서드는 추상 메서드입니다. 추상 클래스는 메서드를 구현하는 방법을 모르기 때문에 하위 클래스 (Circle과 같은 구체적인 클래스) 만 메서드를 구현하는 방법을 알고 있습니다. 추상 클래스와 추상 메서드는 모두 abstract키워드를 사용하여 선언 됩니다 .

public abstract class Shape{
    
    
    public abstract void draw();
}

추상 메서드를 정의하는 클래스는 추상 클래스로 선언해야하지만 추상 클래스에는 추상 메서드가있을 수 없습니다. 추상 클래스는 new개체를 만드는 데 사용할 수 없으며 하위 클래스를 사용하여 개체를 만들어야합니다. 클래스가 추상 클래스를 상속 한 후에는 추상 클래스로 선언되지 않는 한 추상 클래스에 정의 된 모든 추상 메서드를 구현해야합니다.

public class Circle extends Shape{
    
    
    @Override
    public void draw(){
    
    
        
    }
}

추상 클래스는 객체를 생성 할 수 없지만 추상 클래스의 변수를 선언하고 추상 클래스의 구체적인 하위 클래스의 객체를 참조 할 수 있습니다.

Shape shape = new Shape();
shape.draw();

사용자가 올바르게 사용하고 쓸모없는 것을 줄 이도록 안내하는 추상 클래스 도입. 빈 메서드 본문 대신 추상 메서드를 사용하면 서브 클래스에서 메서드를 구현해야하며 무시할 수 없으며 무시하면 컴파일 오류가 발생합니다.

추상 클래스와 인터페이스는 근본적으로 다르며 인스턴스 변수는 인터페이스에서 정의 할 수 없지만 추상 클래스는 정의 할 수 있습니다. 클래스는 여러 인터페이스를 구현할 수 있지만 하나의 클래스 만 상속 할 수 있습니다.

추상 클래스와 인터페이스는 대체가 아니라 함께 사용되며 종종 함께 사용되며 인터페이스 선언 기능, 추상 클래스는 기본 구현을 제공하고 메서드의 전체 또는 일부를 구현합니다. 인터페이스에는 종종 해당하는 추상 클래스가 있습니다. 예를 들어 Collection, 인터페이스에 해당하는 AbstractCollection추상 클래스입니다.

특정 능력이 필요한 특정 클래스의 경우 두 가지 선택이 있습니다. 하나는 인터페이스를 구현하고 모든 메서드를 직접 구현하는 것이고 다른 하나는 추상 클래스를 상속하고 필요에 따라 메서드를 다시 작성하는 것입니다. 상속의 장점은 코드를 재사용하는 것입니다. 필요한 부분 만 다시 작성하면됩니다. 작성해야하는 코드는 비교적 작고 구현하기 쉽습니다. 그러나이 콘크리트에 이미 부모 클래스가있는 경우 인터페이스 구현 만 선택할 수 있습니다.

내부 클래스의 본질

일반적으로 각 클래스는 독립적 인 Java 소스 파일에 해당합니다. 그러나 클래스 는 내부 클래스 라고 하는 다른 클래스 안에 배치 될 수도 있습니다 . 상대적으로 말해서 클래스를 포함하는 클래스를 외부 클래스 라고 합니다 .

내부 클래스는 Java 컴파일러의 개념 일뿐입니다. Java 가상 머신의 경우 내부 클래스를 알지 못합니다. 결국 각 내부 클래스는 독립적 인 바이트 코드 파일을 생성하기 위해 독립적 인 클래스로 컴파일됩니다.

내부 클래스는 외부 클래스의 개인 변수에 쉽게 액세스 할 수 있습니다.

Java에는 위치 및 정의 방법에 따라 네 가지 주요 유형의 내부 클래스가 있습니다.

  • 정적 내부 클래스
  • 회원 내부 클래스
  • 메서드 내부 클래스
  • 익명 내부 클래스

메서드 내부 클래스는 메서드 내에서 정의되고 사용되며 익명 내부 클래스는 범위가 더 작으며이 두 유형 중 어느 것도 외부에서 사용할 수 없습니다. 멤버 내부 클래스와 정적 내부 클래스는 외부에서 사용할 수 있지만 모두 다음과 같이 선언 할 수 있습니다.private

정적 내부 클래스는 모두 static키워드를 사용하여 정적 변수 및 정적 메서드와 동일한 방식으로 정의됩니다 .

public class Outer{
    
    
    public static class StaticInner{
    
    
        public void innerMethod() {
    
    
            ...
        }
    }
}

정적 내부 클래스는 외부 클래스의 정적 변수 및 메서드에 직접 액세스 할 수 있지만 인스턴스 변수에는 액세스 할 수 없습니다.

public정적 내부 클래스는 외부에서 사용할 수 있지만 外部类.静态内部类방식으로 사용해야합니다.

Outer.StaticInner si = new Outer.StaticInner();
si.innerMethod();

멤버 내부 클래스와 정적 내부 클래스의 정의는 비슷하지만 static수정자가 없습니다 .

public class Outer{
    
    
    private int a = 100;
    
    public class Inner{
    
    
        public void innerMethod() {
    
    
            System.out.prinln("outer a = " + a);
            Outer.this.action();
        }
    }
    
    private void action() {
    
    
     	System.out.println("action");   
     }
    public void test() {
    
    
        Inner inner = new Inner();
        inner.innnerMethod();
    }
}

멤버 내부 클래스는 외부 클래스의 인스턴스 변수 및 메서드에 직접 액세스 할 수도 있으며 메서드를 사용하여 외부 클래스 外部类.this.xxx의 인스턴스 변수 및 메서드를 참조 할 수도 있습니다 . 그러나 후자는 일반적으로 멤버의 내부 클래스의 메서드와 변수가 외부 클래스와 동일한 이름을 가질 때 사용됩니다.

열거의 본질

열거 형 enum은 특수한 데이터 형으로 값이 제한되어 열거 할 수 있으므로 열거 형이라고합니다.

열거 형 클래스의 정의 예는 다음과 같습니다.

public enum Size {
    
    
    SMALL, MEDIUM, LARGE
}

열거 형 enum키워드를 사용하여 정의되며 열거 형 유형의 각 값은 쉼표로 구분 ,됩니다. 열거 형은 별도의 파일로 정의하거나 다른 클래스 내에 정의 할 수 있습니다.

열거 형 변수의 정의는 다음과 같습니다.

Size size = Size.MEDIUM;

열거 형 변수 toString()sum name()메서드는 열거 형 변수 size.toString()리터럴 값을 반환하고 반환 은 MEDIUM입니다.

열거 형 변수를 사용 ==하고 equals()비교할 수 있습니다 . 열거 형 값이 순서대로되어 있기 때문에 크기를 비교할 수 있습니다. 열거 형 값의 순서는 0부터 시작하여 열거 형을 정의 할 때 결정됩니다. 열거 형 값은 메서드에 의해 ordinal()반환 됩니다 .

열거 유형은 모두 Java API Comparable인터페이스를 구현하며 compareTo, 이는 실제로 비교 ordinal크기 메소드를 통해 다른 열거 값과 비교할 있습니다 .

열거 형은 switch판정 조건 case에서 사용할 수 있지만 라벨의 앞에 열거 형을 붙일 수는 없습니다.

switch(size) {
    
    
    case SMALL:
        ...
       break;
        
    case MEDIUM:
       ...
       break;
        
    case LARGE:
       ...
       break;
}

열거 형에는 valueOf(String)문자열에 해당하는 열거 형 값을 반환 할 수 있는 정적 메서드가 있습니다.

System.out.println(Size.valueOf("SMALL"));

열거 유형 values에는 선언과 동일한 순서로 모든 열거 유형 변수를 포함하는 배열을 반환하는 정적 메서드 도 있습니다 .

for(Size size : Size.values()) {
    
    
	System.out.println(size);
}

실제로 클래스에서 정적 정수 변수를 정의하면 열거 기능을 수행 할 수도 있지만 열거 유형에는 다음과 같은 이점이 있습니다.

  • 열거 형을 정의하는 구문은 더 간결합니다.
  • 열거 된 유형이 더 안전합니다. 열거 형 변수, 그 값은 null이거나 열거 형 값 중 하나이며 다른 값이 될 수 없습니다. 정수 변수를 사용하는 경우 값을 제한 할 수 없습니다.
  • 열거 형에는 사용하기 쉬운 기본 제공 메서드가 많이 있습니다.

열거 형은 실제로 Java 컴파일러 final에 의해 Java API의 java.lang.Enum 클래스를 상속 하는 해당 클래스 로 컴파일됩니다 .

일반적으로 열거 형 변수는 해당 클래스 변수로 변환되며 switch 문에서는 열거 형 값이 해당 서수 값으로 변환됩니다. 열거 형은 실제로 클래스이지만 컴파일러가 자동으로 많은 작업을 수행하기 때문에 열거 형을 사용하는 것이 더 간결하고 안전하며 편리합니다.

열거 형은 인스턴스 변수와 메서드를 가질 수도 있습니다. 열거 형 값의 정의 ;클래스 정의의 시작과 끝에 배치해야합니다 .

public enum Size {
    
    
    SMALL("S", "小号"), 
    MEDIUM("M","中号"), 
    LARGE("L","大号");
    
    private String attribute;
    private String title;

    private Size(String attribute, String title) {
    
    
        this.attribute = attribute;
        this.title = title;
    }

    public String getAttribute() {
    
    
        return this.attribute;
    }

    public String getTitle() {
    
    
        return this.title;
    }
}

추천

출처blog.csdn.net/NelsonCheung/article/details/110358505