java 핵심 기술 - 인터페이스와 내부 클래스(1)

8511 단어 java 핵심 기술
인터페이스 기술: 주로 종류가 어떤 기능을 가지고 있는지 묘사하는 데 사용되며 각 기능의 구체적인 실현을 제시하지 않는다.한 종류는 한 개 또는 여러 개의 인터페이스를 실현할 수 있고 인터페이스가 필요한 곳에서 상응하는 인터페이스를 실현하는 대상을 수시로 사용할 수 있다.자바 프로그램 언어 디자인에서 인터페이스는 클래스가 아니라 클래스에 대한 요구 사항입니다.이런 종류는 인터페이스 설명의 통일된 형식에 따라 정의해야 한다.
대상 복제는 하나의 변수를 복사할 때 원시 변수와 복사 변수는 같은 대상을 인용한다. 만약에 하나의 대상을 만드는 새로운copy를 만들면 그의 최초 상태는original과 같지만 이후에 각자의 상태를 바꿀 수 있다면 clone 방법을 사용해야 한다.Employee copy = original.clone(); copy.raiseSalary(10);//ok original unchanged. 단, clone 방법은 Object 클래스의 보호된 방법입니다.사용자가 작성한 코드에서 그를 직접 호출할 수 없다는 것이다.Employee 클래스만 Employee 객체를 복제할 수 있습니다.이런 제한에는 어느 정도 일리가 있다.이 클래스는 구체적인 클래스 대상에 대해 아무것도 모르기 때문에 각 영역을 대응하는 복사만 할 수 있다.객체의 모든 데이터 도메인이 숫자 또는 기본 유형에 속하는 경우 복제 도메인에 문제가 없습니다.그러나 객체에 하위 객체에 대한 참조가 포함된 경우 복제된 결과 두 도메인이 동일한 하위 객체를 참조하게 되므로 원래 객체와 클론 객체가 이 정보를 공유합니다.
기본 클론 작업은 얕은 복사입니다. 대상에 포함된 내부 대상은 복제되지 않습니다.따라서 원래 객체가 얕은 클론 객체와 공유하는 하위 객체가 변경될 수 없는 경우 문제가 발생하지 않습니다.이런 경우도 있다.예를 들어 하위 대상은 String 클래스와 같은 변경할 수 없는 클래스에 속한다.하위 대상이 생명주기 내에 변화가 일어나지 않을 수도 있고, 그들의 방법을 바꾸지 않을 수도 있고, 그에 대한 인용을 만드는 방법도 없을 수도 있다.그러나 더욱 흔히 볼 수 있는 상황은 하위 대상이 변할 수 있기 때문에 클론 하위 대상의 깊은 복사를 실현하기 위해 클론 방법을 다시 정의해야 한다.예를 들어 대상의 Date 클래스, 이것이 바로 가변적인 하위 대상이다.모든 종류에 대해 다음과 같은 판단을 해야 한다. 1) 기본적인clone 방법이 수요를 충족시키는지 여부.2) 기본 clone 방법은 가변자 대상을 호출하는 clone을 통해 수정할 수 있는지 여부입니다.3) clone 을 사용하지 않아야 하는지 여부옵션 3은 기본값입니다.1, 2를 선택하면 클래스는 1) Cloneable 인터페이스 2를 실현해야 합니다.public 접근 수식자를 사용하여 clone 방법을 다시 정의합니다.
여기서 Cloneable 인터페이스의 출현은 인터페이스의 정상적인 사용과 아무런 관계가 없다. 특히 그는 clone 방법을 지정하지 않았다. 이 방법은 Object 클래스에서 계승된 것이다.인터페이스는 여기에 표시일 뿐이다.클래스 디자이너가 복제 처리를 알고 있음을 나타낸다.Cloneable 인터페이스는 자바가 제공하는 몇 개의 태그 인터페이스 중 하나로 일반적으로 인터페이스를 사용하는 목적은 클래스가 특정한 방법이나 그룹의 특정한 방법을 실현하는 것을 확보하기 위해서이다. Comparable 인터페이스가 바로 이런 예이다.
얕은 복사
 clone ( ) , Cloneable , clone publicsuper.clone().
eg:
class Employee implements Cloneable
{
    public Employee clone() throws CloneNotSupportedException
    {
        return (Employee) super.clone();
    }
}
 Object.clone , public, , 。

딥 카피
class Employee implements Cloneable
{
    public Employee clone() throws CloneNotSupportedException
    {
        // call Object.clone()
        Employee cloned = (Employee) super.clone();
        // clone mutable fields
        cloned.hireDay (Date) hireDay.clone();
        return cloned;
    }
}
 clone Cloneable ,Object clone CloneNotSupportedException , 。Employee Date Cloneable , 。 。 throws CloneNotSupportedException。

마지막으로 사용자 정의 클래스에서 clone 방법을 실현하는지 여부는 고객의 수요에 달려 있다.복제의 응용은 사람들이 상상하는 것처럼 보편적이지 않다. 표준 라이브러리에서 5%도 안 되는 클래스만 클론을 실현했다.
인터페이스와 콜백(callback)은 흔히 볼 수 있는 프로그램 설계 모델로 이런 모델에서 특정한 사건이 발생할 때 취해야 할 동작을 지적할 수 있다.예를 들어 마우스를 누르거나 메뉴 항목을 선택할 때 어떤 행동을 취해야 하는지를 가리킬 수 있다.
내부 클래스 내부 클래스는 다른 클래스에 정의된 클래스입니다.내부 클래스를 사용하는 이유: 1) 내부 클래스 방법은 이 클래스가 정의한 역할 영역의 데이터를 방문할 수 있으며 개인 데이터를 포함한다.2) 내부 클래스는 같은 가방의 다른 클래스를 숨길 수 있다.3) 리셋 함수를 정의하고 대량의 코드를 작성하지 않으려면 익명 내부 클래스를 사용하는 것이 편리하다.
에이전트는 에이전트를 이용하여 실행할 때 주어진 인터페이스를 실현하는 새로운 종류를 만들 수 있습니다.이런 기능은 컴파일할 때 그 인터페이스를 실현해야 한다는 것을 확정할 수 없을 때만 사용할 수 있다.인터페이스를 나타내는 Class 대상 (인터페이스만 포함할 수도 있음) 을 가정하면, 그의 정확한 유형은 컴파일할 때 알 수 없습니다.이러한 인터페이스를 실현하는 클래스를 구축하려면 newInstance 방법을 사용하거나 반사해서 이 클래스의 구조기를 찾아야 한다.그러나 인터페이스를 실례화할 수 없습니다. 프로그램이 실행 중일 때 새로운 종류를 정의해야 합니다.이 문제를 해결하기 위해 일부 프로그램은 코드를 생성할 것이다.이 코드들을 파일에 놓기;컴파일러 호출하기;결과 클래스 파일을 다시 불러옵니다.이렇게 하면 속도가 매우 느리고 컴파일러를 프로그램과 함께 놓아야 한다.대리 메커니즘은 더욱 좋은 해결 방안이다.프록시 클래스는 실행할 때 새로운 클래스를 만들 수 있습니다.이런 에이전트는 지정한 인터페이스를 실현할 수 있다.그는 다음과 같은 방법을 가지고 있다. 1) 인터페이스를 만드는 데 필요한 모든 방법.2) Object 클래스의 모든 방법(예: toString, equals 등)그러나 실행할 때 이 방법의 새 코드를 정의할 수 없습니다.호출 프로세서 (invocation handler) 를 제공하는 호출 프로세서는 Invocation Handler 인터페이스를 실현하는 클래스 대상입니다. 이 인터페이스에는 단 하나의 방법이 있습니다. Object invoke (Object proxy, Method method, Object [] args)호출 프로세서는 호출을 처리하는 방식을 제시해야 한다.프록시 객체를 만들려면 Proxy 클래스의 newProxyInstance 메서드를 사용해야 합니다.이 방법은 세 가지 매개 변수가 있다. 하나는 클래스 캐리어이다.Java 보안 모델의 일부로 사용됩니다.시스템 클래스와 인터넷에서 다운로드한 클래스는 서로 다른 클래스 마운트를 사용할 수 있다.2) 각 요소는 구현해야 하는 인터페이스인 Class 객체 배열3) 호출 프로세서 1개
package com.cht.ProxyTest;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.*;

public class ProxyTest {

    public static void main(String[] args) {
        Object [] elements = new Object [1000];
        //fill elements with proxies for the integers 1...1000
        for (int i = 0; i < elements.length; i++) {
            Integer value = i + 1;
            InvocationHandler handler = new TraceHandler(value);
            Object proxy = 
                    Proxy.newProxyInstance(
                            null,
                            new Class[]{ Comparable.class },
                            handler);
            elements[i] = proxy ;
        }

        //Construct a random integer 
        Integer key = new Random().nextInt(elements.length)+1;

        //serch for the key 
        int result = Arrays.binarySearch(elements, key);

        // print match if found
        if(result >= 0)System.out.println(elements[result]);
    }

}


class TraceHandler implements InvocationHandler{

    private Object target;
    public TraceHandler(Object t){
        target = t ;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        //print implict argument
        System.out.println(target);
        //print method name
        System.out.println("."+method.getName()+"(");

        //print explict arguments
        if (args != null){
            for (int i = 0; i < args.length; i++) {
                System.out.println(args[i]);
                if(i 1)System.out.println(".");
            }
        }
        System.out.println(")");

        return null;
    }


}

좋은 웹페이지 즐겨찾기