疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java之变量隐藏、静态方法隐藏


 

   

  隐藏变量

  在一个类里,如果一个变量的名字和父类的变量的名字一样,即使他们的类型不一样,那么在子类中,父类的同名变量无法直接通过变量名访问。

  但是,父类的同名变量可以通过super访问。一般来说,不推荐隐藏变量,这样会让代码难以阅读

  当子类继续父类时,出现相同字段时父类字段不会将子类字段覆盖,而只是将其“隐藏”。

  例子:

  父类:

  [java]

  public class Super {

  public int field=0;

  public int getField() {

  return field;

  }

  }

  子类:

  [java] view plain copy 在CODE上查看代码片派生到我的代码片

  public class Sub extends Super {

  public int field=1;

  public int getField() {

  return field;

  }

  public int getSuperField(){

  return super.field;

  }

  }

  测试:

  [java]

  public class Test {

  public static void main(String[] args) {

  // TODO Auto-generated method stub

  Super sup=new Sub();

  System.out.print(sup.field+" "+sup.getField());//对于域的访问由编译器决定(静态绑定)

  }

  }

  结果:0 1

  结论:从结果可以知道,子类field字段并没有将父类的field字段覆盖,而只是“隐藏”而已;另外也可以知道对于域(字段)的访问是由编译器决定的,即静态绑定。

  一个大的原则:静态方法不能被覆盖。实例方法被覆盖,静态方法被隐藏。被覆盖的方法只有覆盖它们的类才能访问它们,而访问被隐藏的方法是提供该方法的全局名。

  静态方法隐藏

  例子:

  父类:

  [java]

  public class Father {

  public static void display(){

  System.out.println("father");

  }

  }

  子类:

  [java]

  public class Son extends Father{

  public static void display(){

  System.out.println("son");

  }

  }

  测试:

  [java]

  public static void main(String[] args) {

  Father f=new Son();

  Son s=new Son();

  s.display();

  f.display();

  }

  结果:

  son

  father

  结论:对于静态方法,子类中的静态方法也不会覆盖父类中的静态方法,而只是“隐藏”而已,具体调用哪个方法取决于对象引用类型;对于普通方法则是覆盖。

  在继承时需要注意的几点原则:

  1)试图用子类的静态方法隐藏父类中同样标识的实例方法不合法,编译器会报错;

  2)试图用子类的实例方法覆盖父类中同样标识的静态方法也不合法,编译器会报错;

  3)静态方法和最终方法不能被覆盖;

  4)实例方法能够被覆盖;

  5)抽象方法必须在具体类中被覆盖。

  方法覆盖和隐藏小结

  下面的表格总结了在子类声明了一个与父类签名一样的方法的各种情况

  Superclass Instance Method Superclass Static Method

  Subclass Instance Method Overrides Generates a compile-time error

  Subclass Static Method Generates a compile-time error Hides

  继承中方法的重载:

  Java父类和子类中的方法都会参与重载,例如,父类中有一个方法是 func(){ ... },子类中有一个方法是 func(int i){ ... },就构成了方法的重载。

  覆盖和重载的不同:

  方法覆盖要求参数列表必须一致,而方法重载要求参数列表必须不一致。

  方法覆盖要求返回类型必须一致,方法重载对此没有要求。

  方法覆盖只能用于子类覆盖父类的方法,方法重载用于同一个类中的所有方法(包括从父类中继承而来的方法)。

  方法覆盖对方法的访问权限和抛出的异常有特殊的要求,而方法重载在这方面没有任何限制。

  父类的一个方法只能被子类覆盖一次,而一个方法可以在所有的类中可以被重载多次。