Java : Basic2

Jamangstangs·2022년 1월 20일
0

Roadmap

목록 보기
2/8
post-thumbnail

Interface

  • 인터페이스 : 객체의 사용 방법을 정의한 타입

    • 개발코드가 인터페이스 메소드 호출 -> 인터페이스는 객체의 메소드 호출 -> 객체
    • 객체는 인터페이스에 리턴값 리턴 -> 인터페이스는 개발코드로 리턴값 리턴
    public interface InterfaceName {
      // 상수 필드
      public static final int CONSTANT = 10;
      // 추상 메소드
      public abstract void funtion();
    }
    • 상수 필드, 추상 메소드만들 구성 멤버로 가진다.
    • 생성자는 없다.
    • 인터페이스는 타입만 정의해서, 구현 객체가 여기에 들어간다고 생각하자.
  • 상수 필드

    • 상수는 public static final이 붙는다.
    • 인터페이스에서 이것을 생략하더라도 자동으로 static final이 붙으면서 상수화된다.
  • 추상 메소드

    • 추상 메소드는 public abstract이 붙는다.
    • 인터페이스에서 이것을 생략하더라도 자동으로 abstract가 붙으면서 추상 메소드가 된다.
    • 내부를 구현할 필요가 없다.
  • 구현 클래스

    • 개발코드 -> 인터페이스의 메소드 호출 -> 인터페이스는 객체의 메소드 호출

    • 이때, 객체는 실체 메소드를 가져야하는데, 인터페이스에 선언된 추상 메소드와 동일한 실체 메소드를 가지고 있어야한다.

    • 따라서, 구현 클래스 -> 구현 객체를 구현해야한다.

      public class ImplementsClassName implements InterfaceName {
       // 인터페이스에서 선언된 추상메소드의 실체 메소드
       public void function(){
         return;
       }
      }
  • 인터페이스 사용 방법

    public class Example{
      public static void main(String[] args){
        // 인터페이스 타입에 구현 객체를 대입한다. 
        InterfaceName in;
        in = new InplementsClassName();
      }
    }
  • 다중 인터페이스

    • 추상 클래스는 다중 상속이 불가능 하지만,
    • 인터페이스는 다중 상속이 가능하다.
    public class ImplementsClassName implements Interface1, Interface2{
    	// interface1의 추상 메소드의 실체 메소드 구현
      // interface2의 추상 메소드의 실체 메소드 구현
    }
  • 인터페이스로 구현객체 사용 방법

    • 인터페이스에 구현객체를 대입하여 사용하는 방식이다.
    public class Example{
      /* Field */
      // 인터페이스가 필드에 선언될 경우, 구현 객체를 대입한다. 
      Interface1 in = new ImplementsClassName();
      /*--------------------*/
      
      /* Constructor */
      
      Exmple(){
      }
      
      // 인터페이스가 생성자의 매개변수로 사용됨
      Example(Interface1 in) {
        this.in = in;
        in.function();
      }
      // Example ex = new Example(new ImplementsClassName());
      // 매개변수에 구현 객체를 넣어서 사용 가능하다.
      
      /*--------------------*/
      
      /* Method */
      // 인터페이스 타입이 메소드의 로컬 변수 타입으로 사용될 때, 변수에 구현 객체를 넣는다. 
      void exampleMethod1(){
        Interface1 in = new ImplementsClassName();
        in.function();
      }
      
      
      // 인터페이스 타입이 메소드의 매개변수로 사용될 때, 매개변수에 구현 객체를 넣는다. 
      void exampleMethod2(Interface1 in) {
        in.function();
      }
      /*--------------------*/
    }
    
    public class Application{
      public static void main(String[] args){
        // 필드에 선언된 인터페이스에 접근
        Example ex1 = new Example();
        ex.in.function();
        
        // 생성자에 구현객체 넣기.
        Example ex2 = new Example(new ImplementsClassName()):
        
        // 메소드 불러오기 (메소드 안에 구현 객체의 함수 호출하는 기능)
        Example ex3 = new Example();
        ex3.exampleMethod1();
        
        // 메소드 불러오기 (메소드의 매개변수로 구현 객체 넣어서 메소드 내의 구현 메소드 불러오기)
        Example ex4 = new Example();
        ex4.exampleMethod2(new ImplementsClassName());
      }
    }
    • 구현 객체가 인터페이스 타입에 대입 -> 인터페이스에서 선언된 추상 메소드를 사용자가 사용할 수 있다.

Interface Polymorphism

  • Promotion : 구현 객체가 인터페이스 타입으로 변환되는 것은 자동 타입 변환이다.

    • Interface interfaceName = new ImplementsClassName();
    • public ImplementsClassName implements interfaceName{ }
    • Interface의 자식 클래스가 Implements Class임을 알 수 있으니 당연하다.
  • 이때, 구현 클래스의 자식클래스 역시 인터페이스 타입으로 Promotion 가능하다.

  • Interface vs Abstract Class

    • 인터페이스는 타입개념. 여기에 선언된 상수 필드, 추상 메소드를 사용 가능하며 실체 객체를 불러와서 사용 가능하다.
      • 오직 추상 메소드만 선언 가능하다.
      • 추상 메소드 구현을 강제하는 느낌이 강하다.
    • 추상 클래스는 자식 클래스들에게 공통된 필드나 메소드를 분배해준다. -> new 연산자로 직접 생성이 불가능 하지만, 자식 객체가 생성될때 super()을 사용해야 하므로 필요하다. 추상 클래스에서 선언된 메소드 이외에서 자식 클래스에서 선언한 메소드를 실행 가능하다.
      • 공통된 메소드는 추상 클래스에서 구현 가능하고, 추상 메소드도 선언 가능하다.
  • Parameter Polymorphism

    • Interface 타입으로 매개변수 선언 -> 구현 객체를 argument로 주면 된다.
    • 이때, 구현 객체는 여러개 가능하므로 다형성이 가능하다.
  • Casting

    • 자동 타입 변환 -> 인터페이스에 정의된 메소드만 사용 가능하다.
    • 강제 타입 변환 -> 인터페이스에 정의 안된 메소드도 사용 가능하다.
    interface Human {
      void walk();
    }
    
    class JM implements Human{
      void walk(){
        System.out.println("달린다.");
      }
    	void study(){
        System.out.println("공부한다. ");
      }
    }
    
    public class Example {
    	public static void main(String[] args){
        Humane human = new JM();
    
        human.walk();
        human.study(); 	// 오류가 난다. Human 형에는 study 정의 안됨
        
        JM jm = (JM)human;
        
        jm.walk();
        jm.study();
      }
    }
  • 객체 타입 확인

    • instanceof 사용하기
    if(Human instanceof JM) {
      JM jm = (JM) human;
    }
  • 인터페이스 상속

    • 다중 상속이 가능하다.
    public interface childInterface extends parentInterface1, parentInterface2 {}

Nested Class & Nested Interface

  • 클래스 내부에 선언한

    • Class
    • Interface
    class ClassName{
    	class NestedClassName{
      }
      
      interface NestedInterfaceName{
      }
    }

Nested Class

  • 멤버 클래스 : 클래스의 멤버로 선언되는 중첩 클래스
    • OuterClassName $ MemberClassName.class 바이트 코드 파일로 컴파일 된다.
    • Instance Member Class : static 없이 선언된 멤버 클래스
    • Static Member Class : static 선언된 멤버 클래스 -> Outer Class 객체 생성 안하고 사용 가능하다.
  • 로컬 클래스 : Constructor | Method 내부에서 선언되는 중첩 클래스
    • OuterClassName $1 LocalClassName.class 바이트 코드 파일로 컴파일 된다.
    • 메소드 내부에서만 사용하므로 Access Modifier, static을 붙일 수 없다.
class OuterClass {
	// Instance Member Class
  class InstanceMemberClass {
    InstanceMemberClass (){}
    int field;
    // static int field;
    void method();
    // static method();
  }
  
  // Static Member Class
  class StaticMemberClass {
		StaticMemberClass(){}
    int field1;
    static int field2;
    void method1();
    static method2();
  }
  
  // Local Member Class 
  void method(){
   	class LocalClass{
      LocalClass(){}
      int field;
      // static int field;
      void method();
      // static method();
    }
    // 메소드 내세어 객체를 생성하고 사용해야 한다. 
    LocalClass lc = new LocalClass();
    lc.field = 1;
    lc.method();
  }
}

class Application{
  public static void main(String[] args){
    //  인스턴스 멤버 클래스 선언 방법
    OuterClass oc = new OuterClass();
    OuterClass.InstanceMemberClass imc = oc.new InstanceMemberClass();
    
    // 정적 멤버 클래스 선언 방법
		OuterClass.InstanceMemberClass imc = new OuterClass.InstanceMemberClass();
    
    // Outer Class에 선언된 로컬 클래스 생성하기
    oc.method();
  }
}

Nested Interface

  • Instance Member Interface : static 없이 선언된 멤버 인터페이스
  • Static Member / : static 선언된 멤버 인터페이스 -> Outer Class 객체 생성 안하고 사용 가능하다.
class OuterClass{
  interface InterfaceName {
		void method();
  }
}

Exception Class

  • 예외의 2가지 종류, 이들을 java.lang.Exception 클래스를 상속 받는다.
    1. Exception : 예외처리 코드로 따로 처리하는 것, 컴파일 과정에서 걸린다.
      • java.lang.ClassNotFoundException
      • ...
      • RuntimeException 이외의 모든 클래스이다.
    2. Runtime Exception : 런타임 중 발생하는 에러. 컴파일러에서 못잡아낸다.
      • java.lang.RuntimeException

RuntimeException

  • NullPointerException : null값을 가지는 참조변수로 객체 접근 연산자를 사용하였기 때문에 예외가 발생한다.

  • ArrayIndexOutOfBoundsException : 배열세어 인덱스 범위를 초과할 경우, 5길이의 배열에서 arr[5]에 접근할때 에러가 발생하는 것과 같다.

  • NumerFormatException : 문자열로 되어 있는 데이터를 숫자로 변경하는 과정

    • Integer.parseInt(String str)
    • Double.parseDouble(String str)

    여기서 숫자로 변환될 수 없는 문자가 포함되어 있으면 에러를 발생시킨다.

  • ClassCastException : 타입 캐스팅은 하위 클래스 -> 상위 클래스 or 구현 클래스 -> 인터페이스

    • 이때, 상위 클래스 or 인터페이스에 대입된 하위 클래스 or 구현 클래스가 다시 본래 객체의 타입형으로 돌아갈때, 다른 클래스 타입으로 변환하고자 할때 발생하는 에러이다.

Exception Handling

  • try-catch-finally

    try{
      // 실행하다가 예외가 발생하면 catch로 넘어간다. 
    } catch(ExpcetionClass e) {
      // 예외 처리를 여기서 해준다.
      // try중 예외가 발생안하면 여기는 생략한다.
    } finally {
      // 항상 실행하는 구문이다. 
      // 앞에서 return이 있어서 항상 실행된다. 
    }
    • catch의 갯수는 늘릴 수 있다. -> 예외는 발생하면 그 시점에서 바로 catch로 가기 때문에 catch가 여러개 작동될 수는 없다.
    • 상위 예외 클래스는 하위 예외 클래스보다 아래 있어야 한다.
      • 왜? -> 하위 예외 클래스가 위에서 내려올때, 상위 예외 클래스가 보이면 거기서 에외 처리를 하기 때문이다. 하위 예외 클래스가 상위 예외 클래스를 상속했음을 알고 있자.
  • throws

    void methodName() throws ExceptionClass1, ExceptionClass2 {
      // 일반적인 메소드 내용, 여기서 예외가 발생하면
    }
    
    void methodName() throws Exception {
    	// Exception으로 설정하면, 모든 예외를 던질 수 있다. 
    }
    • 해당 메소드는, 반드시 try 블록 내에서 실행 되어야 한다.
    • 어쨌든 예외 객체를 던지는 것이므로 try에서 탐지하고catch에서 처리해야한다.

Anonymous Class

  • 이름이 없는 클래스 -> 기억하지 않아도 되는 클래스
  • 즉, 일회성으로 쓰여지고 버려질 클래스이다. 사용 방법은 아래와 같다.
public class Parent{
  public int a = 1;
  public int getA() return a;
  public int setA(int a) this.a = a;
}

public static void main(String args[]){
	// 일반적인 인스턴스 생성 방법
  Parent parent = new Parent();
  // 익명 클래스를 사용하여 인스턴스 생성
  Parent test = new Parent(){
    public int b = 10;
    @Override
    public int getB() return b;
    @Override
    public int setB() this.b = b
  };
}
profile
자망스탕스

0개의 댓글