26678
何故Javaの`interface`に宣言されているメソッドに`protected`修飾が出来ないようにされたのでしょうか。

* * *

Androidの`onClick`メソッドは`public`でしかオーバーライド出来ません。理由は`interface`は`public`じゃないと宣言できないからです。このようにした理由はなぜでしょうか？

`private`だとアクセスできないのはわかります。  
なら、`package private`や`protected`はなぜ出来ないのでしょうか。継承先ではアクセスできるはずです。
CC BY-SA 3.0
2016-06-11T23:27:48.507
26661
2016-10-23T01:01:46.697
2016-10-23T01:01:46.697
15185
15185
question
java
Javaのinterfaceは、何故protected修飾が出来ないのか
privateメソッドは、クラス内からしか呼び出すことができません。となると、クリックを検出するプログラムもクラス内に作る必要があります。  
interfaceは、その名の通り他のクラスとのインターフェースですから、privateではインターフェースにならないと思います。
CC BY-SA 3.0
2016-06-12T00:09:29.880
26662
2016-06-12T00:09:29.880
8077
26661
answer
`private`は`protected`と違い、継承したクラスからですら（リフレクションなど一部例外を除いて）アクセスできないので、継承して初めて参照できる`interface`のメンバーに`private`を持たせることがその目的と反していうるためじゃ無いでしょうか。  
onClickなどは別クラスからアクセスされるので`public`でなければなりません。オーバーライドされたく無いばあいは`final`をつけて`public
final void onClick(View v){...}`とすればサブクラスからオーバーライドできなくなります。

**追記に関して**  
`interface`に`protected`が使えない究極的な理由は、Javaを作った人がそうすることに決めたからということになるような気がします。ただそうした理由としては、interfaceという英単語が持つ意味的に、内部でやっていることを隠して外部に公開する機能のみを表記するためだけに使って欲しかったからでは無いでしょうか。  
`interface`にある`protected`なメンバーは`interface`を継承したクラスをさらに継承しないと使えませんから、外部に提供する機能とはちょっと違ったニュアンスになるような気がします。そういう用途には`abstract
class`の方を使って欲しかったのかもしれません。
CC BY-SA 3.0
2016-06-12T05:33:43.790
26666
2016-06-12T06:13:28.307
2016-06-12T06:13:28.307
3974
3974
26661
answer
インターフェースは外側から使えるメソッドを定義しておくのが目的なので`public`なメソッドがあれば十分です。  
とは言え、Java 8でデフォルトメソッドが扱えるようになったので、そのデフォルトメソッドから利用するヘルパメソッド等を隠蔽する意義はあるかも知れません。  
実際手元の[JDK9](https://jdk9.java.net/download/)（build
122）の`javac`では以下のコードがコンパイルを通りました。

```

    interface Test {
       default void meth() {
        help();
       }
       private void help() {
        System.out.println("Hello!");
       }
    }
    
```

`protected`については多重継承による衝突の解決の問題もあるのではないでしょうか。

以下、参考までにJVMの仕様変更について  
[Java SE 7版のChapter 4. The class File
Format](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.6)には次のように書かれています。

> All interface methods must have their ACC_ABSTRACT and ACC_PUBLIC  
>  flags set; they may have their ACC_VARARGS, ACC_BRIDGE and  
>  ACC_SYNTHETIC flags set and must not have any of the other flags in  
>  Table 4.5 set (JLS §9.4).

従ってJVMのレベルでインターフェースで`private`や`protected`なメソッドは扱えません。

一方[Java SE 8版のChapter 4. The class File
Format](https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6)には次のように書かれています。

> Methods of interfaces may have any of the flags in Table 4.6-A set  
>  except ACC_PROTECTED, ACC_FINAL, ACC_SYNCHRONIZED, and ACC_NATIVE (JLS  
>  §9.4). In a class file whose version number is less than 52.0, each  
>  method of an interface must have its ACC_PUBLIC and ACC_ABSTRACT flags  
>  set; in a class file whose version number is 52.0 or above, each  
>  method of an interface must have exactly one of its ACC_PUBLIC and  
>  ACC_PRIVATE flags set.

`protected`は相変わらずダメですが`private`は扱えるようになっています。
CC BY-SA 3.0
2016-06-12T09:46:33.480
26678
2016-06-12T12:59:40.777
2016-06-12T12:59:40.777
13199
13199
26661
answer