0. 인터페이스 (Interface)


- 인터페이스란

인터페이스는 추상 클래스로, 구현된 것은 없고 밑그림만 그려져 있는 '기본 설계도'라 할 수 있다.

인터페이스는 여러가지 특징의 다형성을 구현하고 싶을때 사용한다.


사람과 자동차와 같은 객체가 있을 때 각각 사람, 자동차에 대한 클래스를 상속한다. 그런데 이 객체들은 다 움직일 수 있다. 

여기에서 각각의 객체에서 움직임에 관한 것들을 처리해줘도 되겠지만, moveable 이라는 인터페이스를 만들고 moveTo(x,y)와 같이 메소드를 지정하고 각각의 객체에 이 인터페이스만을 구현해주게 되면 외부에서는 사람.moveTo(), 자동차.moveTo() 등과 같이 다형성을 이용해서 하나의 움직일 수 있는 특징을 사용할 수 있게 된다.


예를 들어 자바에서 runnable 을 보면 runnable 인터페이스만 구현해주면 쓰레드를 만들 수 있게 되고,

안드로이드의 listener도 그 인터페이스만 구현해주면 다른 작업 없이도 그 특징을 구현할 수 있다.



- 인터페이스 작성

1
2
3
4
interface 인터페이스이름 { 
    public static final 타입 상수이름 = 값;     // 모든 멤버변수는 public static final 이어야 하며, 이를 생략할 수 있다. 
    public abstract 메서드이름(매개변수목록); // 모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다. 
}
cs


1
2
3
4
5
6
7
8
9
interface PlayingCard { 
    public static final int SPADE = 4
    final int DIAMOND = 3;     // public static final int DIAMOND=3; 
    static int HEART = 2;     // public static final int HEART=2; 
    int CLOVER = 1;         // public static final int CLOVER=1; 
 
    public abstract String getCardNumber(); 
    String getCardKind();     // public abstract String getCardKind();로 간주된다. 
cs



- 인터페이스 구현

1
2
3
class 클래스이름 implements 인터페이스이름 { 
    // 인터페이스에 정의된 추상 메서드를 구현해야 한다. 
cs

1
2
3
4
class Fighter implements Fightable { 
    public void move() { ... } 
    public void attack() { ... } 
cs



출처:

https://www.androidpub.com/160033

http://myeonguni.tistory.com/57



1. 실행 결과 화면

      



2. activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp"
    android:gravity="center">
 
   <fragment
       android:id="@+id/fragment_list"
       android:name="com.tistory.qlyh8.pracitice.FragmentList"
       android:layout_width="match_parent"
       android:layout_height="0dp"
       android:layout_weight="1" />
 
   <View
       android:layout_width="match_parent"
       android:layout_height="1.5dp"
       android:layout_marginTop="4dp"
       android:layout_marginBottom="4dp"
       android:background="@android:color/white"/>
 
   <fragment
       android:id="@+id/fragment_image"
       android:name="com.tistory.qlyh8.pracitice.FragmentImage"
       android:layout_width="match_parent"
       android:layout_height="0dp"
       android:layout_weight="1" />
 
</LinearLayout>
 
cs



3. fragment_list.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">
 
    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="이미지 1"
        android:textSize="18sp"/>
    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="이미지 2"
        android:textSize="18sp"/>
    <Button
        android:id="@+id/button3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="이미지 3"
        android:textSize="18sp"/>
 
</LinearLayout>
 
cs



4. fragment_image.xml

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <ImageView
        android:id="@+id/image_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>
 
cs



5. FragmentList.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package com.tistory.qlyh8.pracitice;
 
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
 
/*
 * 하나의 프래그먼트에서 다른 프래그먼트로 직접 접근할 수 없으므로
 * 시스템 역할을 하는 액티비티를 통해 명령이나 데이터를 전달해야 한다.
 * 즉, FragmentList 에서 액티비티의 메소드를 호출해야 한다.
 */
public class FragmentList extends Fragment {
    /*
    * 액티비티의 메소드를 호출할 때는 프래그먼트가 어떤 액티비티 위에 올라가더라도
    * 프래그먼트의 소스가 변경되지 않도록 인터페이스를 정의하여 사용한다.
    *
    * 인터페이스는 액티비티에서 구현하도록 하고,
    * FragmentList 에서 인터페이스에서 정의한 메소드를 호출하도록 한다.
    */
    public interface imageChangeCallback {
        void onImageChange(int index);
    }
 
    public Button button1, button2, button3;
    //MainActivity mainActivity;
 
    public imageChangeCallback callback;
 
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
 
        //mainActivity = (MainActivity) getActivity();
        /*
         * 프래그먼트는 액티비티 위에 올라갈 때 onAttach 메소드가 자동으로 호출되므로
         * onAttach 메소드가 호출되는 시점에 액티비티를 참조할 수 있다.
         * 이 액티비티가 인터페이스를 구현하고 있다면 액티비티 객체를 변수에 할당한다.
         */
        if (context instanceof imageChangeCallback) {
            callback = (imageChangeCallback) context;
        }
    }
 
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_list, container, false);
 
        button1 = rootView.findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //mainActivity.onImageChange(1);
                callback.onImageChange(1);
            }
        });
 
        button2 = rootView.findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //mainActivity.onImageChange(2);
                callback.onImageChange(2);
            }
        });
 
        button3 = rootView.findViewById(R.id.button3);
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //mainActivity.onImageChange(3);
                callback.onImageChange(3);
            }
        });
 
        return rootView;
    }
 
    @Override
    public void onDetach() {
        super.onDetach();
        //mainActivity = null;
        callback = null;
    }
}
 
cs



6. FragmentImage.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.tistory.qlyh8.pracitice;
 
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
 
public class FragmentImage extends Fragment {
 
    public ImageView imageView;
 
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_image, container, false);
        imageView = rootView.findViewById(R.id.image_view);
 
        return rootView;
    }
 
    public void setImage(int index){
        if(index == 1){
            imageView.setImageResource(R.drawable.img1);
        }
        else if(index == 2){
            imageView.setImageResource(R.drawable.img2);
        }
        else if(index == 3){
            imageView.setImageResource(R.drawable.img3);
        }
    }
}
 
cs



7. MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.tistory.qlyh8.pracitice;
 
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
 
public class MainActivity extends AppCompatActivity implements FragmentList.imageChangeCallback {
 
    FragmentManager fragmentManager;
    FragmentList fragmentList;
    FragmentImage fragmentImage;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        // 프래그먼트 매니저를 통해 프래그먼트를 찾는다.
        fragmentManager = getSupportFragmentManager();
        fragmentList = (FragmentList) fragmentManager.findFragmentById(R.id.fragment_list);
        fragmentImage = (FragmentImage) fragmentManager.findFragmentById(R.id.fragment_image);
    }
 
    // 인덱스를 통해 해당되는 이미지를 띄운다.
    // 액티비티에 변수를 선언하고 프래그먼트 객체를 할당해두면
    // FragmentList 객체나 FragmentImage 객체를 항상 참조할 수 있게 되며
    // 액티비티의 메소드가 호출되었을 때 FragmentImage 의 메소드를 호출함으로써 이미지를 변경할 수 있다.
    @Override
    public void onImageChange(int index) {
        fragmentImage.setImage(index);
    }
    //public void onImageChange(int index){
    //    fragmentImage.setImage(index);
    //}
}
cs





출처: https://www.edwith.org/boostcourse-android/lecture/17075/

+ Recent posts