class Base
{
   public void men1()
  {
   System.out.println("base men1 called_______");
  }
  public void men2()
  {
   System.out.println("base men2 called_______");
  }}
 class Sub extends Base
{
    private void men1()//报错
  {
   System.out.println("Sub men1 called_______");
  }
  public  void men2()
  {
   System.out.println("Sub men2 called_______");
  }
  public  void men3()
  {
   System.out.println("Sub men3 called_______");
  }
}
 public class test
 {
 public static void main(String arg[])
 {
 Base base=new Sub();
 base.men2();
 
 }
 }1、为什么注释的部分会报错,为什么复写父类的方法的时候不能降低访问控制?
2、为什么Base base=new Sub(); base不能调用men2() 只能调用继承自父类的方法?
希望大家不要轻易的丢下一句多态。多分析下原因。、谢谢了 

解决方案 »

  1.   

    1。父类的public是向外提供的接口,也是一种向客户程序的约定,因为子类可以替代父类,所以必须遵从这种约定。protected可以认为是向子类提供的约定,同理。2。当你使用base调用方法的时候,编译器只知道它的类型是Base,所以只能使用Base定义的方法。
    至于调用时能正确调用base所指向的实际对象的方法,那就是多态了,是运行的时候发生的行为。
      

  2.   


     class Base
    {
       public void men1()
      {
       System.out.println("base men1 called_______");
      }
      public void men2()
      {
       System.out.println("base men2 called_______");
      }}
     class Sub extends Base
    {
        public void men1()//将private改为public就ok啦;因为重写父类方法时,该方法的权限不能盖过父类即不能比父类的权限大。
      {
       System.out.println("Sub men1 called_______");
      }
      public  void men2()
      {
       System.out.println("Sub men2 called_______");
      }
      public  void men3()
      {
       System.out.println("Sub men3 called_______");
      }
    }
     public class test
     {
         public static void main(String arg[])
         {
             Base base=new Sub();
             base.men2();
             
         }
     }
      

  3.   

    1.为什么不能降低访问权限,你应该去问java开发人员,一个父类会派出好多子孙类如果子类比父类权限还低的话,那到它的N代孙子类不就不能访问了,private类是没有任何意义的
    2.Base base=new Sub();编译时创建了一个Base类的声明base,而new Sub()是在运行时才创建的
    你在eclipse打出base.的时候,工程都没运行,eclipse去哪找子类的方法,当然是只能找到父类的方法了提示了
      

  4.   


    Java上除了static 和final方法(包括private方法)之外,所有的好像都是后期绑定的,也就是多态了。它可以在运行时确定对象的时际类型,从而调用恰当的方法。
    这里,Base base=new Sub(); base.men2();调用的确实是base中的方法。对于第一个问题,我也不太明白。但是我试过,可以提升降低访问控制的。我有个假设,不知道有没有道理。现假设可以降低访问控制,把父类中的public 
    在子类中降低为private,那么这样在进行动态绑定时,好像就会有问题。拿你这个来说吧。基类中是public men1(),子类中为private men1(),
    那么,Base base=new Sub();  base.men1() 会怎么样呢?在编译时,编译器并不知道它的准确类型,只知道base是一个Base的引用, base.men1() 会通过编译的,因为men1() 在Base中是public。再看到了运行时,确定了它的实际对像是子类Sub,那么根据多态,它会调用Sub中的men1()方法。这时问题就来了,men1()方法在Sub中是private,不能被访问!我这个想法可能也是错的,希望有高手来解决。
      

  5.   


    说明一下:
    我运行了一下的,Base base=new Sub(); base.men2(); 确实调用的是子类中Sub中的方法。
      

  6.   

    可以从继承的关系想问题;
    也可说是:SUN的规定,就像private修饰的变量只允许在本类访问一样,深究到最后,就是两个字:规定
      

  7.   

    第一个问题:
    假设另一个类中有这样一个方法public fun(Base b)
    {
        b.men1();
    }当你把Sub对象当作Base传进去时你想想会发生什么?--该程序会突然可怕的死掉。
    因为它实际调用的是Sub的men1(),而Sub类中的men1()是private的。
    可想而知,一个人被他淘气的儿子背叛的时候,他该有多么沮丧。
      

  8.   


    在继承的时候有原则的,变压器会检查这些原则,
    其中有一个就是,子类的API只能大于等于父类的API,而不能小于它的(这可以理解吧)这样的话,子类可以放大父类的方法的权限,而不能缩小。所以你的父类public,子类继承为private是通不过的
      

  9.   

    1、关于第一点,我个人觉得这个应该和Sun工程师在设计Java语言时的规范有关,你完全可以把它当做一种规定稍微记一下就OK的了!
    2、Base base=new Sub();
       base.men2();
       左边的Base base在编译时,会被编译器认为是Base类型的,右边的new Sub()是运行时的类型(生成的是Sub类型的对象,这是由Java虚拟机(JVM)认定的)。这样就会显得栈和堆中的类型不一致了,这时Java虚拟机(JVM)处理的方式是:把子类对象当做父类对象来使用。
       base.men2(),调用这个方法时,因为men2()这个方法在子类中属于重写方法,调用时得分两种情况:1、父类中的men2()方法和子类中重写的men2()方法是非静态的,即public void men2(){}类型时,调用的是子类中重写的men2()方法,即会输出“Sub men2 called____”结果。2、当这两个方法都是静态的,即public static void men2(){}类型时,调用的是父类中的men2()方法,即会输出“base men2 called_______”结果。