java

导航

关于Java内部类的可见性

来源 :中华考试网 2020-12-03

  在Java中,当生成一个内部类的对象时,此对象与制造它的外部类通过外部类的.this保持着联系,因此该内部类对象可以访问其外部类对象的所有成员,包括private成员。

  而该内部类对象对于其他类的对象的访问,遵照常规的访问权限语法,这一点也没有什么特别支持。这里需要探讨的是,外部类以及其他类的对象可以如何访问到某个内部类对象,即内部类的可见性问题。

  下面是一个示例程序Out.java,其中包含了4个不同访问权限的内部类(private,default,protected,public),在每个内部类中,分别包含4个不同访问权限的成员与方法。在外部类Out中提供了得到内部类实例的方法。

  Out.java

  package com.zj.main;

  public class Out {

  public PrivateIn getPrivateIn(){

  return new PrivateIn();

  }

  public DefaultIn getDefaultIn(){

  return new DefaultIn();

  }

  public ProtectedIn getProtectedIn(){

  return new ProtectedIn();

  }

  public PublicIn getPublicIn(){

  return new PublicIn();

  }

  private class PrivateIn implements InMethod{

  private int private_arg;

  int default_arg;

  protected int protected_arg;

  public int public_arg;

  private void private_method(){};

  void default_method(){};

  填写下面表单即可预约申请免费试听java课程!害怕学不会?助教陪读,随时解惑!担心就业?一地学习,可全国推荐就业!

  protected void protected_method(){};

  public void public_method(){};

  }

  class DefaultIn implements InMethod{

  private int private_arg;

  int default_arg;

  protected int protected_arg;

  public int public_arg;

  private void private_method(){};

  void default_method(){};

  protected void protected_method(){};

  public void public_method(){};

  }

  protected class ProtectedIn implements InMethod{

  private int private_arg;

  int default_arg;

  protected int protected_arg;

  public int public_arg;

  private void private_method(){};

  void default_method(){};

  protected void protected_method(){};

  public void public_method(){};

  }

  public class PublicIn implements InMethod{

  private int private_arg;

  int default_arg;

  protected int protected_arg;

  public int public_arg;

  private void private_method(){};

  void default_method(){};

  protected void protected_method(){};

  public void public_method(){};

  }

  public static void main(String[] args){

  //create an outer object

  Out out=new Out();

  //create a private inner object by 'new'

  Out.PrivateIn privateIn=out.new PrivateIn();

  privateIn.private_arg=0;

  privateIn.private_method();

  // create a private inner object by 'out's method'

  Out.PrivateIn privateIn2 = out.getPrivateIn();

  privateIn2.private_arg = 0;

  privateIn2.private_method();

  }

  }

  所有的4个内部类都实现了一个接口InMethod,该接口的作用在下文中会有讨论。下面先讨论内部类所在的外部类对其内部类对象的访问权限问题。

  1.外部类的访问

  我们通过两种两种方式试图创建内部类的实例。

  方式一 OuterClassName.InnerClassName inner=new Ouer().new Inner();

  通过外部类对象.new 的方式,可以得到private inner class 的实例,并且可以访问它的private成员和private方法。自然default、protected和public的都可以访问。

  方式二 通过外部类方法get InnerInstance()

  此种方法也可以访问所有内部类的所有成员和方法。

  所以,一个内部类的对象对生成它的外部类对象是完全可见的,包括private内部类、private成员与private方法。

  2.同包其他类的访问

  下面,在同一个包内创建一个SamePackage.java类,试图访问Out类的所有内部类。

  SamePackage.java

  package com.zj.main;

  public class SamePackage {

  public static void main(String[] args) {

  // create an outer object

  Out out = new Out();

  //create a private inner object by 'new'

  //Out.PrivateIn privateIn=out.new PrivateIn();

  //->error: Out.PrivateIn is not visible.

  // create a default inner object by 'new'

  Out.DefaultIn defaultIn = out.new DefaultIn();

  //defaultIn.private_arg=0;->error:not visible

  defaultIn.default_arg = 0;

  //defaultIn.private_method();->error:not visible

  defaultIn.default_method();

  // create a private inner object by 'out's method'

  //Out.PrivateIn privateIn2 = out.getPrivateIn();

  //->error:Out.PrivateIn is not visible through out.getPrivateIn() is visible.

  // create a private inner object by 'out's method',

  // but use Interface reference to handle it

  InMethod privateIn=out.getPrivateIn();

  privateIn.public_method();

  }

  }

  方式一 OuterClassName.InnerClassName inner=new Ouer().new Inner();

  使用方式一试图得到private 内部类失败,根本得不到内部类的句柄。

  //create a private inner object by 'new'

  //Out.PrivateIn privateIn=out.new PrivateIn();

  //->error: Out.PrivateIn is not visible.

  但是可以正常的访问default访问权限的内部类的对象。当然是访问不到它的private成员和private方法的。自然protected和public的都可以访问。

  方式二 通过外部类方法get InnerInstance()

  虽然可以调用外部类对象的getInnerInstance()方法,但由于得不到private内部类的句柄,所以此种方法无法创建private内部类的实例。

  // create a private inner object by 'out's method'

  //Out.PrivateIn privateIn2 = out.getPrivateIn();

  //->error:Out.PrivateIn is not visible through out.getPrivateIn() is visible.

  但由于所有的内部类都实现了接口InMethod。

  <> InMethod.java

  public interface InMethod {

  void public_method();

  }

  所以还是可以通过接口的引用访问到private内部类的public方法。自然default、protected和public的都可以访问这个public方法。

  // create a private inner object by 'out's method',

  // but use Interface reference to handle it

  InMethod privateIn=out.getPrivateIn();

  privateIn.public_method();

  3.不同包其他类的访问

  在另一个包中建立一个类DifferPackage.java。

  DifferPackage.java

  package com.zj.other;

  import com.zj.main.InMethod;

  import com.zj.main.Out;

  public class DifferPackage {

  public static void main(String[] args){

  //create an outer object

  Out out=new Out();

  //create a public inner object by 'new'

  Out.PublicIn publicIn=out.new PublicIn();

  publicIn.public_arg=0;

  publicIn.public_method();

  // create a public inner object by 'out's method'

  Out.PublicIn publicIn2 = out.getPublicIn();

  publicIn2.public_arg=0;

  publicIn2.public_method();

  //use Interface reference

  InMethod method;

  method=out.getPrivateIn();

  method.public_method();

  method=out.getDefaultIn();

  method.public_method();

  method=out.getProtectedIn();

  method.public_method();

  method=out.getPublicIn();

  method.public_method();

  }

  }

  通过new方式和getInnerInstance()方法只能访问public内部类的public成员和public方法;如果使用接口的引用,则可以访问所有4个内部类的public方法。

  4.不同包继承类的访问

  在另一个包中建立一个类DifferPackageExtend.java,它继承自外部类Out。

  DifferPackageExtend.java

  package com.zj.other;

  import com.zj.main.Out;

  public class DifferPackageAndExtend extends Out{

  public static void main(String[] args){

  //create an DifferPackageAndExtend's object,which extends Out

  Out extend=new DifferPackageAndExtend();

  //create a protected inner object by 'new'

  //Out.ProtectedIn protectedIn=extend.new ProtectedIn();

  //->error:The constructor Out.ProtectedIn() is not visible

  // create a protected inner object by 'out's method'

  Out.ProtectedIn protectedIn=extend.getProtectedIn();

  protectedIn.public_arg=0;

  protectedIn.public_method();

  }

  }

  通过new方式,虽然可以得到内部类的句柄Out.ProtectedIn,但该内部类的构造子却不可见。

  通过getInnerInstance()方法得到protected内部类的对象,但只能访问到public成员和public方法。由此可知,protected内部类并不关心是否有其他类继承自它的外部类。所有protected访问权限不在此种情况下适用。

  如果你现在想学习Java,赢取高薪工作机会,非常简单,填写下面信息,学好Java技术高薪工作机会唾手可得。

分享到

您可能感兴趣的文章