2

私は次の2つのファイルを持っています:

Fruit.java:

package superClass;

public class Fruit { 
 protected static void printName() {
  System.out.println("My name is Khan");
 }

}

Apple.java:

package food;

import superClass.*;

public class Apple  {
 public static void main(String[] args) {
  int i, j;
  for(i = 0; i < 5; i++) {
   for(j = 0; j < i; j++) {
    System.out.print("*");
   }
   System.out.println();
  }
  printName(); // Call inherited member - NO ERROR, expected

  Fruit f = new Fruit();
  f.printName(); // Call instantiated member - ERROR, expected
 }

}

予想どおり、Appleクラスから保護されたメソッドprintNameにアクセスすることはできません。これらは、異なるパッケージに存在するためです。次のエラーが発生します。

printName() has protected access in superClass.Fruit

完全に正しい。しかし、次のようにクラスsuperClassから継承した場合、エラーは発生しません。

package food;

import superClass.*;

public class Apple extends Fruit {
 public static void main(String[] args) {
  int i, j;
  for(i = 0; i < 5; i++) {
   for(j = 0; j < i; j++) {
   System.out.print("*");
   }
   System.out.println();
 }
  printName(); // Call inherited member - NO ERROR, expected

  Fruit f = new Fruit();
  f.printName(); // Call instantiated member - NO ERROR, WHAT????
 }
}

参照により、別のパッケージの別のクラスの保護されたメンバーにアクセスできるのはなぜですか?これは違法なアクセスだと思われますね。

私は混乱しています!誰か助けてください。

コードはJava1.6.0_18を使用してコンパイルされました。

4

8 に答える 8

4

観察された動作は、printName が静的であるためです。protected 修飾子はサブクラスでそのメソッドの可視性を提供しますが、メソッドが非 static の場合、そのメソッドの呼び出しはサブクラスのインスタンスを介してのみ可能です (「クラスから継承する場合、あなたが提起していた懸念」次のようなスーパークラスはエラーになりません!")。JLS セクション 6.6.2.1は、これを簡潔に定義しています。

于 2010-09-01T17:17:36.473 に答える
3

保護された修飾子は、継承されたクラスへのアクセスを許可します。特定のパッケージでのみクラスへのアクセスを制限する必要がある場合は、「パッケージ」修飾子が必要です。これは単なる空の修飾子です。つまり、次のようなメソッドを記述します。

static void printName()

パッケージが表示されます。

于 2010-03-03T09:18:22.783 に答える
3

protectedこれがアクセスの定義です。protectedメンバーは、別のパッケージに含まれているかどうかに関係なく、サブクラスからアクセスできます。

これは、 Javaのアクセス修飾子への参照です。

注:Javaでは、規則は小文字のパッケージ名を持つことです。つまりsuperClass、この規則に準拠していません。特に、ファイル名とディレクトリ名で大文字と小文字が区別される* nixプラットフォームで開発している場合は、これに悩まされる可能性があります。

于 2010-03-03T09:18:44.637 に答える
3

スーパークラスの保護されたメンバーは、スーパークラスが別のパッケージにある場合でも、サブクラスからアクセスできますが、保護されたメンバーが使用されているクラスの参照によって使用できます。これは、この時点でそのクラスが保護されたメンバーの所有者であるためです。保護されたメンバーを仮定します

com.pack1 class A { protected int i;}
com.pack2 class D { System.out.println(i); System.out.println(a1.i); }

iは完全ですが、a1.i完全ではありません。エラーを出してください。クラスDでは、クラスAの参照ではなく、dの参照によって保護されたメンバーを使用できます

于 2011-11-23T06:40:49.417 に答える
1

スーパークラスが別のパッケージにある場合でも、スーパークラスのprotectedメンバーはサブクラスからアクセスできます。このページの 2 番目の部分と、それに付随する表/図を参照してください。

http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

于 2010-03-03T09:22:52.790 に答える
0

protected をデフォルト (別名 package) 修飾子と混同していませんか? 後者は、同じパッケージのメンバーへのアクセスを制限します。

Protected は、問題のクラスから継承するパッケージおよびクラスのメンバーへのアクセスを制限します。

詳細については、 http://java.sun.com/docs/books/jls/second_edition/html/names.doc.html#62587を参照してください。

于 2010-03-03T09:22:32.573 に答える
0

ええ、エラーが発生しなかったのは良いことです...それは Java 言語仕様の違反またはバグである可能性があります...とにかく、そのとおりです。それが保護されたアクセス修飾子の定義です。Protected は、外部または他のクラスからのクラス メンバーのアクセシビリティの中間レベルのようなものです。それは私的と公的の間だと思います。保護されたクラス メンバーは、(クラスのサブクラスから) および (同じパッケージに属している限り、他のクラスから) アクセスできます。ちょっとした考え!

于 2010-03-03T09:28:41.753 に答える