黑马程序员技术交流社区

标题: protected修饰的成员问题 [打印本页]

作者: ljh11849    时间: 2013-1-14 21:34
标题: protected修饰的成员问题
在父类中定义了一个protected修饰的方法,在与父类不同包的子类中定义一个父类的对象 为什么这个对象访问不了protected修饰的方法。

2.png (6.05 KB, 下载次数: 31)

子类

子类

1.png (3.46 KB, 下载次数: 39)

父类

父类

作者: 胡勇敏    时间: 2013-1-14 22:27
protected这个控制符只允许在本包里面使用,采用导入其他包的方式不能使用。在父类包外的子类中能“看到“的只是子类自己继承来的protected 方法和属性,它是不能“看到“它的父类对象的protected方法和属性的。所以你的new Test1().show()是可以的而Test2 t2 =new Test2();t2.show()就是不行的。
作者: 张云杰    时间: 2013-1-14 23:06
建议你读下各个修饰符的作用域问题, 比如上面的修饰符, 意思是 受保护的,  只有被继承的时候 可以调用,  或者是在本类下 可以调用 ,相同的还有 private public... 还有一个是 friendly
作者: 铿锵科技    时间: 2013-1-14 23:12
把protected改成public就可以调用了
作者: ㄒんeゞSeven    时间: 2013-1-15 00:02
用 protected 修饰的方法和属性是包级私有的 ,就是说用 protected  修饰的类,只能被所在的包中的其他类来使用。
虽然T1继承T2,但你在T1中创建了T2的实例这个动作与继承没有关系,就如同在其他不是T2的子类中建立一个T2的实例一样。
由于T2的show方法是用protected 修饰的,所以若超过了包的范围是无法被访问到的。

希望对你有所帮助。

作者: 李俊伟    时间: 2013-1-15 12:02
package com.ljh;
/**
* 1.protected保护修饰符的定义:如果将成员变量或者成员放法的权限定义为protected,
* 那么成员变量或者成员方法只能在自己的类及其子类内访问。(教材中的定义)
* 2.分析:
* <1>Test1继承Test2,在类Test1的main方法中,new Test1().show();子类对象调用父类方法。
* <2>Test2 t2 = new Test1();t2.show();t2是一个外部类对象,在其他类(不包含同一
* 个包下的类)里调用自己的protected方法当然java是语法所不允许的。
* <3>我试了试,在同一个包内的其他类里的main方法中也可以new Test2().show();。
* <4>那么protected保护修饰符也可以这么定义了:如果将成员变量或者成员放法的权限定
* 义为protected,那么成员变量或者成员方法只能在自己的类或自己的类所属的package下
* 的其他类及其子类内访问.(嘿嘿!教材有缺陷)
* <5>实在是想要在Test1类的main方法中通过Test2的对象访问其保护方法,可以通过反射来
* 达到效果
*/
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.lyz.*;
public class Test1 extends Test2{
/**
  * @param args
  * @throws InvocationTargetException
  * @throws IllegalAccessException
  * @throws IllegalArgumentException
  */
public static void main(String[] args) {
  //new Test1().show();
  Test2 t2 = new Test2();
  //t2.show();
  try {
   //由于show方法的形参为空,getDeclaredMethod方法的第二个参数得new一个Class
   //对象的空数组。
   Method method = Test2.class.getDeclaredMethod("show",new Class<?>[]{});
   //指示反射的对象在使用时取消 Java 语言访问检查。
   method.setAccessible(true);
   //对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。由于invoke方法的第二个
   //参数为空,可以如下面这样写。
   method.invoke(t2);
   //这中方法调用也能试实现,但是还得抛两个异常,捕获异常的注释部分就是。
   //method.invoke(Class.forName("com.lyz.Test2").newInstance());
   
  }  catch (SecurityException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NoSuchMethodException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IllegalArgumentException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
//  catch (InstantiationException e) {
//   // TODO Auto-generated catch block
//   e.printStackTrace();
//  } catch (ClassNotFoundException e) {
//   // TODO Auto-generated catch block
//   e.printStackTrace();
//  }
  
}
}

作者: 舒远    时间: 2013-1-15 12:19
包含protected成员的类A,与A在同一包中的其他类可以访问A的protected成员,
与A不在同一包中的类只能是A的子类可以访问protected成员(继承下来的),即使创建出来的A的对象也无法调用protected成员
作者: 范德农    时间: 2013-1-15 13:21
lz,你可以直接发代码的,而不是发图片
下面逐条解释下
public class Test1 extends Test2
{
    public static void main(String[] args)
    {
        //这是子类调用它继承的父类方法,这个已经可以看做是它自己的方法了
        new Test1().show;
        
        Test2 t2 = new Test2();
        /*这个实际上是通过lgh包中的Test1类来lyz包中类的protected方法,是包间调用。而protected
          修饰的只允许包内调用,而子类使用继承的包外父类protect修饰方法属性时,实际上是在使用
       它自己的方法,还是包内调用*/
        t2.show()
    }
}
我觉得LZ主要问题是混淆了继承方法和调用方法的概念了。protcted修饰内容的访问范围是包内及子类,

区别于空修饰符则是空修饰符只允许包内范围,而不管是否继承。
作者: ljh11849    时间: 2013-1-15 15:38
谢谢大家的热心回复:lol




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2