java继承中除了public和protected成员方法外其余的属性是拥有非继承

来源:互联网 发布:去除数组重复元素js 编辑:程序博客网 时间:2024/06/04 19:32

     一。静态方法

JAVA静态方法形式上可以重写,但从本质上来说不是JAVA的重写。因为静态方法只与类相关,不与具体实现相关,声明的是什么类,则引用相应类的静态方法(本来静态无需声明,可以直接引用),看下例子:

 

Java代码  收藏代码
  1. class Base{  
  2.         static void a( ){System.out.println("A");  }  
  3.                  void b( ){System.out.println("B"); }  
  4. }  
  5. public class  Inherit extends Base{  
  6.           static void a( ){System.out.println("C");  }  
  7.                   void b( ){System.out.println("D"); }  
  8.            public static void main(String args[]){  
  9.                     Base b=new Base();  
  10.                     Base  c=new Inherit();  
  11.                     b.a();  
  12.                     b.b();  
  13.                     c.a();  
  14.                     c.b();  
  15.          }  
  16. }  
 

 

以上输出的结果是:A  B  A  D
        非静态方法 按重写规则调用相应的类实现方法,而静态方法只与类相关。

       所谓静态,就是在运行时,虚拟机已经认定此方法属于哪个类。

专业术语有严格的含义,用语要准确."重写"只能适用于实例方法.不能用于静态方法.对于静态方法,只能隐藏(刚才的例子可以重写那只是形式上的 ,并不满足多态的特征,所以严格说不是重写)。

      静态方法的调用不需要实例化吧..  不实例化也就不能用多态了,也就没有所谓的父类引用指向子类实例.因为不能实例化 也就没有机会去指向子类的实例。所以也就不存在多态了。

二。私有方法

接着我们回归前文的目的,继续考察子类是否能够继承父类中的私有成员。我们通过上面的讨论,可以知道私有属性是被保留在父类中的,而不会被子类继承。接着我们看看私有方法。如下:

package com.patrickhe.test.inheritprivate;
public class ParentClass {
    private String msg() {
       return "I am an attribute in ParentClass.";
    }
    public String getMsg() {
       return msg();
    }
}

package com.patrickhe.test.inheritprivate;
public class ChildrenClass extends ParentClass{
    private String msg() {
       return "I am an attribute in ChildrenClass.";
    }
}

测试类的代码保持不变。运行测试类,可以看到控制台的输出结果为:

ParentClass object outputs:
I am an attribute in ParentClass.

ChildrenClass object outputs:
I am an attribute in ParentClass.

如果将 ParentClass 和 ChildrenClass 中 msg 方法的访问限定符改为 public,再运行测试类,我们可以看到输出结果变为:

ParentClass object outputs:
I am an attribute in ParentClass.
 

ChildrenClass object outputs:
I am an attribute in ChildrenClass.
 

我们知道,在 Java 中 可以通过在子类中声明具有相同名字相同签名的方法来覆盖掉父类中的相应方法。具体讨论私有方法的继承问题,如果说子类是可以继承父类的私有方法的话,那么 子类也就能够覆盖掉父类中的私有方法;反之,如果子类覆盖不了父类中的私有方法的话,也就是说子类不能从父类继承其私有方法。在实验结果中,我们看到了子 类是不能覆盖掉父类中的私有方法的,也就意味着子类没有从父类继承私有方法,但是子类可以继承父类的非私有方法。最后引述一段 Java Programming Language 中的话:“方 法只有在它可以被访问的时候才能被覆盖。如果一个方法不能被访问的话,也就是说这个方法不能被继承,它既然不能被继承的话那么也就不能被覆盖。例如,私有 方法在它所在类之外是不能被访问的。如果子类中碰巧定义了一个方法和父类中的私有方法具有完全相同名字、签名和返回值类型,那么这两个方法是完全没有任何 联系的——子类中的方法将不会覆盖父类中的方法”。

三。成员变量

我们知道,子类可以通过声明具有相同名字的属性来覆盖掉从父类中继承而来的相应属性,也可以声明具有相同名字相同签名的方法来覆盖掉从父类中继承而来的相应方法。也就是说,如果子类可以从父类中继承私有成员,那么也就可以覆盖掉继承而来的私有成员。反之,如果子类覆盖不了父类中的私有成员,我们就不能说子类继承了父类中的私有成员。

我们可以设计一个实验来验证父类中的私有成员是否会被子类继承。考虑如下两个类:

public class ParentClass {
    private String msg = "I am a attribute in ParentClass.";

    public String getMsg() {
        return msg;
    }
}

public class ChildrenClass extends ParentClass {
    private String msg = "I am a attribute in ChildrenClass.";
}

测试类:

public class TestClass {
    public static void main(String[] args) {
        ParentClass p = new ParentClass();
        ChildrenClass c = new ChildrenClass();

        System.out.println("ParentClass object outputs:");
        System.out.println(p.getMsg());
        System.out.println("");
        System.out.println("ChildrenClass object outputs:");
        System.out.println(c.getMsg());
    }
}

编译后运行测试类我们可以看到控制台输出以下结果:

ParentClass object outputs:
I am a attribute in ParentClass.

ChildrenClass object outputs:
I am a attribute in ParentClass.

可以看到,虽然我们在子类中定义了一个属性试图覆盖掉父类中的同名属性,但是从输出结果看来,这个行动是无效的。因为没有从父类中继承私有成员,所以也谈不上覆盖父类中的同名属性——没有可供覆盖的属性。相同的道理,子类也不会继承父类中的私有方法,有兴趣的程序员可以自己写一个类似的实验程序试一试。

四。总结

其实不复写父类中的非私有成员函数,在子类对象调用继承的成员方法时会调用父类的方法。此时,父类中的this的引用的实例是子类的,但是引用的类型是父类的,相当于Fu fu=new Zi()的这种形式,我们知道这是多态的表达形式,对于非私有的成员函数会有多态的表现,主要是通过父类的引用子类的对象调用方式时,是子类的成员函数起作用,这是对于有指针指向子类的多态情况。其余的静态函数,成员变量,和私有方法,都是调用父类自己的变量和方法。

class Fu{

public int age=100;

}


class Zi extends Fu{

public int age=10;

}


class test{

public static void main(String[] args){

Fu fu=new Zi();

System.out.println(fu.age);

}

}


结果为:100;

对于成员变量,private类型的在子类中是拥有不是继承,而且在子类中无法直接使用该成员变量,只能通过调用父类的get,set方法才可以操作相应的属性,子类中可以写同名的成员变量,只是覆盖了父类的信息,子类可以单独操作同名的成员变量。如果是protected或者是public的成员变量,子类可以直接在子类中操作此变量,子类中的改变会影响父类的值,他们在内存空间中是同一片区域。也可以通过同名的成员变量覆盖相应的父类中的变量。

0 0
原创粉丝点击