当前位置:  技术问答>java相关

protected和static关键字的疑惑!

    来源: 互联网  发布时间:2015-07-28

    本文导语:  1.在Java2 认证考试指南(机械工业出版社 原书第三版)中如是描述: protected修饰符使得类的变量、方法、构造器可以被同包中的类或者接口所访问,也可以被所在类的子类(理所当然在其他包的子类也可以)所访问。 ...

1.在Java2 认证考试指南(机械工业出版社 原书第三版)中如是描述:
protected修饰符使得类的变量、方法、构造器可以被同包中的类或者接口所访问,也可以被所在类的子类(理所当然在其他包的子类也可以)所访问。
2.而在Beginning Java 2(电力出版社)中,类成员访问属性描述那章也是上面这样说的。可是在继承那章却有如下的话:“protected限制包以外的类对其进行访问,但是不限制继承。没有访问修饰符的成员限制在同一包内可以访问,而且阻止包外面的子类继承”,这真是让人迷惑,感觉protected可以阻止包外的子类访问(分明更多的书上不是这样讲的),而可以继承。但究竟是这样的么?

我做了如下测试,得到的结果更是奇怪。希望高人能解释一下:
文件Tree.java描述基类test.Tree:

package test;

public class Tree 
{
  protected int age=2;
  protected void outPut()
  {
    System.out.println("Inherit Test!");
  }
}
用javac -d . Tree.java编译通过。class肯定在classpath中。

Pine.java描述子类Pine(使用默认包,以达到和父类不同包的效果)
public class Pine extends test.Tree 
{
  public static void main(String[] args)
  {
    test.Tree tmp = new test.Tree();
    tmp.outPut();
    System.out.println(tmp.age);
  }
}
结果编译出错:
D:workjavatestPine.java:13: outPut() has protected access in test.Tree
    tmp.outPut();
       ^
D:workjavatestPine.java:14: age has protected access in test.Tree
    System.out.println(tmp.age);
                          ^
2 errors

而如果将protected改为public或者将Pine、Tree置于同一包中时,均可正常运行通过。
而由此,我认为开始的观点2的确是正确的。也就是说:protected限制包以外的类对其进行访问!!!这真是让人吃惊。不过我很快意识到这种想法可能还是错的。因为也许(我还是不能肯定)不能靠新生成一个父类的实例来实现对父类(不同包)的protected的成员(fields)和方法的访问,而要靠super这个关键字。
将Pine.java做了如下修改后变异运行通过:
public class Pine extends test.Tree 
{
  public static void main(String[] args)
  {
    test.Tree tmp = new test.Tree();
    //tmp.outPut();  这样会出错。说什么outPut()是protected。不过至今不解为啥
    Pine pine = new Pine();
    pine.access();
    //System.out.println(tmp.age);//同样的错误。
  }
  private void access(){
    super.outPut();
    System.out.println("And also accesses 'age': "+super.age+" Successfully!");//这样就行。真有些想不通。
  }  
}

但很偶然的我将test.Tree修改为:
package test;

public class Tree 
{
  protected static int age=2; //修改为静态变量;
  protected static void outPut() //修改为静态方法;
  {
    System.out.println("Inherit Test!");
  }
}
重新编译后,结果居然老的Pine.java(也就是靠临时生成一个父类的实例来访问父类的protected成员和方法)也能编译了,也能运行了。
因此实在是不解啊。高人指点?

另外Java 2认证考试指南说static的方法是不能被子类覆盖的,但我做了测试这分明是行的啊(肯定不是类似于对父类private同名方法重建的,因为要求返回值一样)。当然和abstract一起使用还是不行的。在此也向各位求证一下到底该怎么说啊?

或者能提供的Java程序员认证经验的人均给分!

|
1, test.Tree tmp = new test.Tree(),然后用tmp引用来访问test.Tree的方法这已经不是对基类的访问了,可称为对test.Tree类对象的方法调用(虽然你extends test.Tree),和其他类用test.Tree tmp = new test.Tree()没有区别,用super.xxx才是对基类的访问方式。
2, 至于你将变量和方法改为static后,能用test.Tree tmp = new test.Tree(),的tmp引用访问,这种情况实际上就绕开了“可称为对test.Tree类对象的方法调用“,tmp.age能通过与你实例化test.Tree无关,不用new xxx一样行,只要有这句:test.Tree tmp,而age是一个静态字段,不实例化同样存在。
方法outPut()同理。

|
一.  修饰符
                  类变量(对象共享) 类名,对象名点取
                  类方法 1)static方法中不能直接使用非静态成员, 因
                       为非静态成员与实例相关,通过对象点取间接使用
                             2)static方法中不能用this(与实例相关)   
                             3)非static方法中可以使用static成员      
                  static块:和数据成员时并列的位置,用于类初始化
                       类装入时执行一次(第一次创建对象,第一次使用
                        static成员,不同的静态块,按在类中的顺序执行)
                     注:只能修饰成员,不能修饰方法变量.
                static方法覆盖时,没有起到覆盖的作用

|
protected修饰符修饰的变量、方法,限制包以外的类对其进行访问。
就是说,在一个类中不能调用其他类的protected变量和方法,要想调用,
必须是public。
    关于继承,子类会继承其父类的protected、public变量和方法
所以用super.xx就没问题,因为该方法是他继承父类的成员方法

|
你提供的例子:
public class Pine extends test.Tree 
{
  public static void main(String[] args)
  {
    test.Tree tmp = new test.Tree();
    tmp.outPut();
    System.out.println(tmp.age);
  }
}
中,你是在Pine中调用Tree的outPut方法,protected限制派生类以外的调用,是指派生类(Pine)可以调用父类(Tree)的protected方法,而不是在派生类中可以用父类(Tree)调用父类本身(Tree)的方法,二你的程序是后者,所以不行。可以改为:
    test.Pine tmp = new test.Pine();//派生类
    tmp.outPut();//调用父类的保护方法
希望队你有所帮助

|
楼上的解释的很清楚,至于你说的在变量前加上static关键字,第一个程序就可以编译运行了,那是绝对不可能的.一个变量能否被访问只与访问修饰符public,protected,private和友好的(就是什么也不加)有关,与是否是static是无关的.好好看看Thing in java对你会有帮助的!

    
 
 

您可能感兴趣的文章:

 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • java命名空间javax.lang.model.element枚举modifier的类成员方法: protected定义及介绍
  • protected 与 package 的存取权限怎么在我看来是一样的? iis7站长之家
  • java命名空间java.lang.reflect类modifier的类成员方法: protected定义及介绍
  • 请教关于protected的访问控制
  • java 类修饰符(private,public和protected)所代表的权限
  • protected的方法和变量不是不能在类外访问马?
  • 不太理解protected的意思,请大虾帮忙解释一下。
  • 请那位给简单讲一下存取修饰符中中default的存取权限(相对于protected)
  • 关于protected modifier的一个疑问
  • protected修饰符为什么不能修饰class?为什么用friendly修饰成员变量时产生错误?
  • 一道protected小问题???!!!在线等!!!!!!
  • 请教大家,有关protected隐藏的一个小问题!
  • 继承一个protected函数,怎样在子类中让它完成父类的功能
  • 请教real mode 和protected mode ,谁能仔细讲讲?
  • 关于private和protected
  • 为什么我无法使用一个类的protected方法。
  • 类A为什么从外包继承一个protected成员后,类A的子类为什么不能访问这个成员
  • 一个类的方法声明为protected,那么在另一个包中的该类的子类能否访问该方法?
  • protected 与 package 的存取权限怎么在我看来是一样的?
  • 什么是inner class?类不过不加修饰符,它的访问权限是protected or default?
  • 跨包之间访问protected类型的问题


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3