> Java > java지도 시간 > 본문

Java 액세스 권한 제어 - 보호된 키워드에 대해 자세히 알아보도록 안내합니다(그림).

黄舟
풀어 주다: 2017-03-14 12:01:27
원래의
2327명이 탐색했습니다.


요약 :

클래스 내에서 해당 멤버(멤버 변수 포함 여부 및 멤버 메서드 )는 멤버의 수정자에 따라 다른 클래스에서 액세스할 수 있으며, 다른 클래스에서 클래스에 액세스할 수 있는지 여부는 클래스의 수정자에 따라 다릅니다. Java에는 네 가지 유형의 클래스 멤버 액세스 권한 수정자가 있습니다. 프라이빗, 없음(기본적으로 패키지 액세스 권한), 보호 및 퍼블릭. 이 중 패키지 액세스 권한과 퍼블릭만 클래스(내부 클래스 제외)를 수정할 수 있습니다. 특히 자바를 소개하는 책 중에는 protected를 일반적인 방식으로 소개하는 경우가 많아 오해를 불러일으키는 경우가 많습니다. 따라서 이 글에서는 보호 키워드의 의미와 사용법을 밝히는 데 중점을 두고 몇 가지 다른 수식어를 소개합니다.


저작권:

이 기사의 원저자: Rico the Nerd
저자 블로그 주소: http://www.php.cn/


1. 패키지

패키지 사용 시 주의할 점은 한 프로젝트에 동일한 패키지 이름이 두 개 있을 수 없다는 것입니다. 즉, 패키지 이름은 프로젝트의 다른 패키지 이름과 반복될 수 없습니다. 여기에는 사용자 정의 패키지 이름뿐만 아니라 프로젝트에서 참조하는 클래스 라이브러리 의 패키지 이름도 포함됩니다. 다음 예를 살펴보세요.

package java.lang;public class MyObject {
    public static void main(String[] args) throws CloneNotSupportedException {
        Object o = new Object();
        System.out.println(o.hashCode());
    }
}
로그인 후 복사

우리 프로그램에 제공하는 패키지 이름은 java.lang입니다. 실제로 우리는 java.lang이 JDK에서 사용하는 패키지 이름이라는 것을 알고 있습니다.

프로그램은 정상적으로 컴파일될 수 있지만 프로그램을 실행하면 패키지 충돌 경고와 "java.lang.SecurityException: Prohibited package name: java.lang" 예외 가 표시됩니다. 아래와 같이 던져질 것입니다.

    

Java 액세스 권한 제어 - 보호된 키워드에 대해 자세히 알아보도록 안내합니다(그림).

   

Java 액세스 권한 제어 - 보호된 키워드에 대해 자세히 알아보도록 안내합니다(그림).

또한 다음 사항에 유의해야 합니다.

프로그램에서 Package 문을 사용하는 경우 다음을 제외해야 합니다. 파일에서 외부 프로그램 코드의 첫 번째 문장을 주석으로 처리하세요. 그렇지 않으면 컴파일되지 않습니다.


2. Java 접근 권한 개요

클래스 내에서 다른 클래스가 해당 멤버(멤버 변수 및 멤버 메소드 포함)에 액세스할 수 있는지 여부는 Modifier에 따라 다릅니다. 이 회원. Java에는

private, none(기본적으로 패키지 액세스), protected 및 public의 네 가지 유형의 클래스 멤버 액세스 한정자가 있습니다. 의 권한 제어는 다음 표와 같습니다.

 멤버, 둘은 구분되어야 합니다.)

Java 액세스 권한 제어 - 보호된 키워드에 대해 자세히 알아보도록 안내합니다(그림).,

은 두 가지 접근 권한만 가집니다. 한정자: public 및 "none"(즉, 패키지 액세스 권한), private 및 protected는 아님(특별한 경우로 내부 클래스만 private이거나 protected일 수 있습니다. 내부 클래스에 대한 자세한 내용은 내 블로그를 참조하세요. "Java 내부 클래스 개요"). 따라서 내부 클래스가 아닌 경우에는 package access 또는 public만 부여할 수 있습니다. 다른 사람이 클래스에 액세스하는 것을 원하지 않으면 모든 생성자를 비공개로 지정하여 누구도 클래스의 객체를 생성하지 못하도록 할 수 있습니다. 현재 이 클래스의 객체는 정적 멤버 내에서만 생성될 수 있습니다. 이 상황은 단일 케이스 패턴과 약간 비슷합니다. 예를 들어

위에서 언급한 네 가지 수식어 중 protected를 제외하면 모두 이해하기 쉽고 숙지할 수 있습니다. 여기서 간단히 설명하겠습니다.

public :

    공개로 수정된 클래스 멤버는 모든 클래스에서 직접 접근할 수 있습니다.
  • private:被public修饰的类成员只能在定义它的类中被访问,其他类都访问不到。特别地,我们一般建议将成员变量设为private的,并为外界提供 getter/setter 去对成员变量进行访问,这种做法充分体现了Java面向对象的四大特性(封装,多态,继承,抽象)中的封装思想;

  • 包访问权限:包访问权限就是Java中的默认的权限,具有包访问权限的类成员只能被同一包中的类访问。

      由于 protected 关键字的真正内涵不太容易理解,我们将在下一节专门介绍 protected 关键字。


三. protected 关键字的真正内涵

  很多的有关介绍Java语言的书籍 (包括《Java编程思想》),都对protected介绍的比较的简单,基本都是一句话,就是:被protected修饰的成员对于本包和其子类可见。这种说法有点太过含糊,常常会对大家造成误解。对于protected的成员,要分子类和超类是否在同一个包中两种情况看待,现以 protected方法的调用为例进行说明,protected的成员变量类似。

  实质上,protected方法的调用是否合法(编译是否通过)关键是要看被调用的protected方法从根源上看所在的类对应的包与调用代码所在的类对应的包是否相同,若相同,则合法;否则,不合法。当然,无论如何,子类是可以访问继承而来的属于它自己的受保护方法的。

  我们可以看下面例子进行了解。


1). 第一种情形:子类与基类不在同一个包中

//示例一package p1;public class Father1 {
    protected void f() {}   
    // 父类Father1中的protected方法}package p1;
    public class Son1 extends Father {}package p11;
    public class Son11 extends Father{}package p1;
    public class Test1 {
    public static void main(String[] args) {
        Son1 son1 = new Son1();
        son1.f(); // Compile OK,protected方法f()来自于Father1类,与 Test1类 在同一包p1中
        son1.clone(); // Compile Error,protected方法clone()来自于Object类,与 Test1类不在同一包中

        Son11 son = new Son11();
        son11.f(); // Compile OK,虽然Son11类在包p11中,但protected方法f()来自于Father1类,与 Test1类在同一包p1中
        son11.clone(); // Compile Error,protected方法clone()来自于Object类,与 Test1类不在同一包中
    }
}
로그인 후 복사

  在上面的示例中,类Father1、Son1 和 Test1 在同一个包p1下,类Son11在包p11下。但是我们知道,无论Son1类还是Son11类,它们的protected方法f()在根源上都来自于p1包中的类Father1,而由于Test1也在p1包中,因此f()方法对Test1类可见,编译通过。但由于Son1类和Son11类中的clone()方法在根源上均来自于java.lang包下的类Object,与 Test1类不在同一包中,因此clone()方法对Test1类不可见,编译不通过。


//示例二package p2;
class MyObject2 {protected Object clone() throws CloneNotSupportedException {       
return super.clone();
    }
}package p22;public class Test2 extends MyObject2 {
    public static void main(String args[]) {
       MyObject2 obj = new MyObject2();
       obj.clone(); // Compile Error,protected方法clone()来自于MyObject2类,与 Test2类 不在同一包p1中

       Test2 tobj = new Test2();
       tobj.clone();// Complie OK,虽然 protected方法clone()来自于MyObject2类,与 Test2类 不在同一包p1中,但Test2类作为MyObject2类的子类,是可以访问继承而来的属于它自己的受保护方法的。
    }
}
로그인 후 복사

  在上面的示例中,类MyObject2 和 类Test2 分别在包 p2 和 p22 下。因此,在类Test2中通过MyObject2的引用调用MyObject2的protected方法clone()时,由于类MyObject2 和 类Test2 不在同一包中而编译不通过。但是我们知道,虽然 类Test2 的protected方法clone()在根源上也来源于 类MyObject2,但是Test2类作为MyObject2类的子类,是可以访问继承而来的属于它自己的受保护方法的。


//示例三package p3;
class MyObject3 extends Test3 {
}package p33;public class Test3 {
  public static void main(String args[]) {
    MyObject3 obj = new MyObject3();
    obj.clone(); // Compile OK,protected方法clone()来自于Test3类,而现在正是在Test3类中访问该方法
  }
}
로그인 후 복사

  在上面的示例中,类MyObject3 和 类Test3 分别在包 p3 和 p33 下。但是由于 MyObject3类的protected方法clone()在根源上来自于类Test3中,而现在正是在Test3类中访问该方法,因此编译通过,原理与示例一类似。


//示例四package p4;
class MyObject4 extends Test4 {  
protected Object clone() throws CloneNotSupportedException {    
return super.clone();
  }
}package p44;public class Test4 {
  public static void main(String args[]) {
    MyObject4 obj = new MyObject4();
    obj.clone(); // Compile Error,protected方法clone()来自于MyObject4类,而Test4类与MyObject4类不在同一个包中
  }
}
로그인 후 복사

  该示例与示例三很类似,唯一不同的是 类MyObject4 重写了从 类Test4 中继承过来的protected方法clone()。这样,MyObject4 的 protected方法clone()在根源上来自于类本身而非Test4类。而类MyObject4 和 类Test4 又不在同一包下,因此编译不通过。


2). 第二种情形:子类与基类在同一个包中

//示例五package p5;

class MyObject5 {    protected Object clone() throws CloneNotSupportedException {       return super.clone();
    }
}public class Test5 {
    public static void main(String[] args) throws CloneNotSupportedException {
       MyObject5 obj = new MyObject5();
       obj.clone(); // Compile OK,protected方法clone()来自于MyObject5类,而Test5类与MyObject5类又在同一个包中
    }
}
로그인 후 복사

  该示例与示例四很类似,唯一不同的是 类MyObject5 与 类Test5在同一个包p5中。正因为二者在同一包中,因此编译通过。


//示例六package p6;

class MyObject6 extends Test6{}public class Test6 {
  public static void main(String[] args) {
    MyObject6 obj = new MyObject6();
    obj.clone();        // Compile OK
  }
}
로그인 후 복사

  在本示例中,由于类MyObject中的protected方法clone()从根源上来自于Test6类,而现在正是在 Test6 中调用protected方法clone(),因此编译通过。


//示例七package p7;

class MyObject7 extends Test7 {    public static void main(String[] args) {
        Test7 test = new Test7();
        test.clone(); // Compile Error.
  }
}public class Test {}
로그인 후 복사

  在本示例中,虽然类MyObject7与Test7类在同一个包p7中,但是由于 类Test7 的protected方法clone()从根源上来自于 java.lang.Object类,而其又与MyObject7不在同一个包中,因此编译不通过。


四. 其他的修饰符

static:修饰变量和内部类(不能修饰常规类),其中所修饰变量称为类变量或静态变量。静态变量是和类存在一起的,每个实例共享这个静态变量,在类加载时初始化。

final: final로 선언된 변수는 선언 시 초기값을 주어야 하며(물론 빈 final 경우는 제외), 수정된 변수는 수정할 수 없습니다. 가치. 클래스를 수정할 때 클래스는 하위 클래스를 파생할 수 없습니다. 메서드를 수정할 때 해당 메서드는 하위 클래스로 재정의될 수 없습니다. 독자들이 final에 대해 더 깊이 이해하고 싶다면 내 블로그 게시물 "Java 상속, 다형성 및 클래스 재사용"을 참조하세요.

추상: 클래스와 메서드를 수정합니다. 클래스를 수정할 때 클래스는 객체를 생성할 수 없습니다. 메서드를 수정할 때는 추상 메서드입니다. 클래스에 추상 메서드가 있는 한 클래스는 추상으로 정의되어야 하지만 추상 클래스가 반드시 추상 메서드를 가질 필요는 없습니다.


5. 요약

다른 클래스에서 해당 멤버(멤버 변수 및 멤버 메서드 포함)에 액세스할 수 있는지 여부는 클래스의 수정자에 따라 다릅니다. 다른 클래스에서 액세스할 수 있는 것은 클래스의 수정자에 따라 다릅니다. Java에는 네 가지 유형의 클래스 멤버 액세스 권한 수정자가 있습니다. 프라이빗, 없음(기본적으로 패키지 액세스 권한), 보호 및 퍼블릭. 이 중 패키지 액세스 권한과 퍼블릭만 클래스(내부 클래스 제외)를 수정할 수 있습니다. 특히, 이 글에서는 보호 키워드의 의미와 사용법을 밝히는 데 중점을 두고 몇 가지 다른 수식어를 소개합니다.


6. 설명

이 장을 요약하는 과정에서 우리는 많은 지식 포인트를 다루었으며 그 중 일부는 다른 블로그 게시물에서 구체적으로 언급했기 때문에 자세한 내용은 업데이트되지 않았습니다. 해당 링크는 다음과 같습니다.

위 내용은 Java 액세스 권한 제어 - 보호된 키워드에 대해 자세히 알아보도록 안내합니다(그림).의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿