일단 해보는 코딩/Java

[Java] 인터페이스(Interface), 내부클래스의 종류, 접근제한자

eun_zoey2 2022. 7. 29. 15:50
728x90
인터페이스(Interface)란?

 

    인터페이스는 앞에서 배운 ' 추상 클래스 ' 와 매우 유사하지만, 서비스 요청에 따른 중계자 역할을 하는 것과 같다. 

    고객이 호출할 수 있는 서비스의 목록이라고 할 수 있다.(내용을 감춰서 고객은 외부적으로만 접근할 수 있는 구조)

    서버에서 DB, FTP, Web과 같은 여러 서비스를 실행하고 있는데 클라이언트가 DB와 FTP, Web 중

    Web 서비스를 요청하면 웹 서비스가 제공되어야 하고, DB 서비스를 요청하면 데이터 베이스 서비스가 실행되어야 한다.

    서버는 외부에 자신이 서비스하고 있는 모든 항목을 보여야 하고, 서비스 항목에 있는 모든 서비스가 실제로 실행될 수 있어야 한다. 

    인터페이스는 클라이언트가 서비스를 요청할 수 있는 서비스 목록으로 볼 수 있다.

    서버는 내부적으로 각 서비스 항목에 있는 서비스   실행을 코딩해야 한다.  

 

 

- 인터페이스  선언 -

   인터페이스는 상속관계가 아닌 클래스에 설정하는데 클래스와 비슷한 구조이지만 상수와 추상 메써드만 멤버가 될 수 있다.

[접근제한] interface 인터페이스_명 {
	상수 ; // <= final 대문자_변수_명 ;
	추상 메써드 ; //<= abstract 메써드_명 ;
	...
	}

 

- 인터페이스 자식 선언 -

   class 클래스이름 implements 인터페이스이름 {... }

 

 

예제모음

더보기

예제 1)

 

 

package Java10;

interface A_Inter {	//부모 인터페이스 클래스 선언
final int CONST =	100;	// 상수_변수
abstract int getA();	// 추상 메써드 (code block인 {...} 없음)
}

class B_Inter implements A_Inter {	// 자식 인터페이스 클래스 선언, cf) extends
	public int getA() {	// Method Overriding
		return CONST;
	}
}

public class InterFace {
	public static void main(String[] args) {
		B_Inter bi = new B_Inter();
// 부모가 아닌 자식 클래스에서 객체 생성!! => 부모 변수와 자식 메써드 모두 사용 가능	
		System.out.println("getA() : " + bi.getA());
	}
}

 

예제 2)

 

package Java10;
interface Int1 {
	final int A = 100;
	abstract int getA();
	abstract void setData();
}
interface Int2 {
	final String B = "Pual";
	abstract String getB(String a);	// (a 값) 인자를 받는 추상메써드 
}
class IntTest implements Int1, Int2{
	public int getA() {
		return A;
	}
	public String getB(String a) {
		return B+a;
	}
	public void setData() {
		// 위에 값을 이미 선언되어져 있으므로 무조건 구현 {...} 해줌! 하는일이 없어도 써줘야함.
	}
}
public class Test02 {
	public static void main(String[] args) {
		IntTest it = new IntTest();
		System.out.println("getA() : " + it.getA());
		System.out.println("getB() : " + it.getB(", Good Guy"));
	}

}

 

 

열거형 (enum)

    열거형은 주로 상수를 가지고 생성되는 객체들을 한 곳에 모아둔 하나의 묶음이다. 

    변수를 사용자가 지정한 이름으로 0부터 순차적으로 증가시켜준다.

 

String name ( ) 열거 객체의 문자열을 리턴
int  ordinal ( ) 열거 객체의 순번 (0부터 시작) 을 리턴
int compareTo ( ) 열거 객체를 비교해서 순번 차이를 리턴
열거 타입 valueOf (String name) 주어진 문자열의 열거 객체를 리턴
열거 배열 values ( ) 모든 열거 객체들을  배열로 리턴

 

예제 모음

더보기

예제 1)

 

package Java10;

import java.util.Scanner;

public class Test03 {
	public enum Item{	//열거형 선언
		Start, Pause, Exit;	//;으로 끝내지 않아도 됨
	}
	public static void main(String[] args) {
		while (true) {
			System.out.println("0 : Game Start");
			System.out.println("1 : Game Pause");
			System.out.println("2 : Game Exit");
			Scanner scan = new Scanner(System.in);
			int n = scan.nextInt();
			Item st = Item.Start;	// enum에서 객체 생성
			Item pa = Item.Pause;
			Item ex= Item.Exit;
			scan.close();
			if (n== st.ordinal()) {	//ordinal() 사용
			System.out.println("Game starting....");
			} else if (n == pa.ordinal()) {
			System.out.println("Game interrupted....");
			} else 
				System.out.println("Game Over");
				return;
		}
	}
}

예제 2)

 

package Java10;
import java.lang.*;
	enum Mobile{                                  // enum class declaration
		Samsung(400), Nokia(250), Motorloa(325);  // member constant
		int price;
		Mobile(int p){                   // member Method definition1
			price = p;
		}
		int showPrice() {               // member Method definition2
			return price;
		}
	}
public class Test04 {
	public static void main(String[] args) {
		System.out.println("Cellular Phone List: ");
		for(Mobile m : Mobile.values()) {  // for 문에서 상수 변수들을 돌릴 때 사용
			System.out.println(m+ " costs "+m.showPrice()+ " dollars, sir/mam");
		}
		Mobile rate;
		rate = Mobile.valueOf("Samsung");
		System.out.println("Selected : "+rate);
	}

}

 

 

내부 클래스 

내부 클래스란 특정 클래스 안에 또 다른 클래스가 정의되는 것을 의미한다.
내부 클래스는 독립적이지만 클래스 전체를 하나의 멤버처럼 사용할 수 있는 특징이 있다.

 

내부 클래스의 종류 

    1) Member inner-class

        - 멤버 내부 클래스는 기존에 외부에서 생성해오던 클래스와 같은 형식이지만 특정 클래스의 내부에서 정의된다는 차이점이 있다.

더보기
package Java10;
class MemberOuter {
	int a = 10;
	private int b = 100;
	static int c = 200;
	class Inner{
		public void printData() {
			System.out.println("int a : " + a);
			System.out.println("private int b : " + b);
			System.out.println("static int c : " + c);
		}
	}
}
public class Member_Inner {

	public static void main(String[] args) {
		// 내부 클래스의 객체화는 먼저 외부 클래스를 객체화 한 뒤, 이 객체를 통해서 만듦
		// TODO Auto-generated method stub
		MemberOuter outer = new MemberOuter(); // 외부 클래스의 객체 생성
		MemberOuter.Inner inner = outer.new Inner(); // 이를 이용해서 내부 클래스의 객체 생성
		inner.printData(); //내부 Inner클래스의 멤버 메써드 이용 
	}

}

    2) Local inner-class

        - 로컬 내부 클래스는 특정 메서드 안에서 정의되는 클래스를 말한다. 특정 메서드 안에서 선언되는 지역변수와 같은 것이다.

더보기
package Java10;
class Outer {
	int a = 100;
	public void local_mem(int n) {	// Outer의 멤버_메써드 정의
		int b = 200;	// 지역_변수
		final int c = n;	// 상수
		class Inner {
			public void getData() {
				System.out.println("int a : " + a);
				System.out.println("int b : " + b);
				System.out.println("fianl int c : " + c);
			}
		}
		Inner i = new Inner();	// 내부 로컬 클래스의 객체 생성
		i.getData();
	}
}
public class Member_local {
	public static void main(String[] args) {
		Outer outer = new Outer();	// Outer 객체 생성
		outer.local_mem(500);
	}

}

    3) Static inner-class

        -내부 클래스가 static 변수를 가지고 있다면, 해당 내부 클래스를 static으로 선언해야 한다.

더보기

static 정적(static) 은 고정된  의미를 가지고 있다.

 

Static이라는 키워드를 사용하여 Static 변수와 Static 메서드를 만들 수 있는데 다른 말로 정적_변수와 정적_메서드라고도 하며, 이 둘을 합쳐 정적_멤버라고 한다(클래스_멤버)

정적_멤버와 정적_메서드는 객체에 소속된 멤버가 아니라 클래스에 고정된 멤버이기 때문에 클래스를 로딩해서 메서드 메모리 영역에 적재할 때 클래스별로 관리된다. 따라서 클래스의 로딩이 끝나는 즉시 바로 사용이 가능하다.

=> 정적 메써드는 객체를 생성하지 않고 사용할 수 있는 이유는 클래스가 메모리에 로딩될 때 자동으로 정적 메서드가 활성화된다.(자동으로 객체가 생성된다라는 느낌으로....)

 

멤버_변수나 멤버_메써드를 선언할 때 나중에 객체를 인스턴스로 생성(new 사용)해서 공용으로 사용할 것인지,  해당 클래스에서만 사용할 것인지를 판단해서 지정하는데 해당 클래스에서만 사용한다면 staic을 붙인 변수와 메서드로 해주면 된다. 

class Number {
  static int num1 = 0; // class_member_varialbe
  int num2 = 0;	       // instance_member_variable
}
public class Static_ex {
  public static void main(String[] args) {
    Number number1 = new Number();
    Number number2 = new Number(); 
    number1.num1++ ;
    number1.num2++ ; 
    System.out.println(number2.num1);
    System.out.println(number2.num2);
    }
}
class Name {
  static void print1() {  // class_member_method
    System.out.println("My name is Paul");
  }
  void print2() {         // instance_member_method
    System.out.println("My name is Mary");
  }
}
public class Static_ex [
  public static void main(String[] args) {
    Name.print1();     // Without making instance, calling method
    Name na = new Name(); 
    na.print2(); 
    }
}
package Java10;
class Outers {
	int a = 10;
	private int b = 100;
	static int c = 200;
	static class Inner {
		static int d = 1000;
		public void getData() {
			System.out.println("static int c : " + c);
		}
	}
}
public class Member_static {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		 Outers.Inner inner = new Outers.Inner();
		 //Outer outer = new Outer();  Outer 클래스는 static이 없으므로 new 객체 생성
		 // Inner inn = outer.new Inner();
		 inner.getData();
		 //static class 는 객체 생성없이 바로 사용할 수 있다. 
	}

}

    4) Anonymous inner-class

        - 이름이 없는 클래스. 한 번만 사용하고 버려지는 객체를 사용할 때 유용하게 쓰이는 내부 클래스이다. 

          나중에 배울 이벤트 Listener  등에서 사용되는 방식이다. 직접 만들어 쓰지는 않고 대부분 정의된 것을 호출해서 사용한다.

더보기
package Java10;
interface TestInt { // 인터페이스 클래스 안에는 상수와 추상메써드가 들어옴 
	int data = 10000;	
	// final int DATA = 10000; 선언하는것이 원칙 interface를 쓰면 자동으로 상수처리 
	abstract public void printData();	//abstract 가 붙고 {...} 없음 => 추상메서드
}
class AnonyInner {
	public void test() {
		new TestInt() {	//위에서 추상 메서드를 재정의
			@Override
			public void printData() {
				System.out.println("익명 클래스 printData()");
			}
		}.printData();	// 위에서 재정의한 printData() 메써드를 호출 
	}
}

public class Anonymous {

	public static void main(String[] args) {
		
		AnonyInner in = new AnonyInner();
		in.test();	//in.printData()식으로 하지 않음! 
		
	}
}

 

이벤트 사용

왜 종료로 안뜨지?
package Java11;

import java.awt.Button;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

	// JFame(그래픽 처리를 위한 자바 스윙)에서 사용된 익명 클래스 Events Listener 구현
public class Test01 {

	public static void main(String[] args) {
		Frame t = new Frame();
		Button btn = new Button("종료");
		t.setSize(300,200);	// JFrame에 들어 있는 함수를 불러서 사용 
		t.add(btn);
		t.setVisible(true);
		btn.addActionListener((ActionListener) new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				System.exit(0);
			}
		});
	}
}

 

 

 

접근 제한자 (적용범위를 보면 public > default > protected > private)
  1.  public : can be accessed from all (모든 접근을 허용, 프로젝트 내의 모든 객체들이 사용할 수 있도록 허용)
  2.  private : only be accessed within present object  ( 현재 클래스 내에서만 사용을 허가)
                  - in class : (public, default)
                  - in constructor, member method, member variable: public, protected, default, private
       
  3.  protected : only be accessed within the same packages inherited object ( 상속관계의 객체들에만 사용을 허가)
  4.  default : only be accessed within the same packages ( 같은 패키지(폴더)내의 객체에만 사용을 허가 )