子类重写父类成员方法

最近在学习到Java的继承和多态时遇到了这样的一个问题:关于继承链中子类对父类的私有方法是否能够覆盖的问题,在此记录一下本身对这个问题解决之后的一些心得。html

 

首先要明确:子类是不可以覆盖(重写)父类的私有方法的。比较直观的理由是,子类要可以重写父类的方法的前提条件是继承,子类对父类的私有方法并不继承,也没有访问权限,天然也是不能重写的。接下来看一个例子:java

 

 

[java] view plaincopy函数

<span style="font-size:14px;">public class Test {  学习

    public static void main(String[] args) {  测试

        new A().printPerson();  this

        new B().printPerson();  spa

    }  htm

}  对象

  

class A {  blog

    public void printPerson() {  

        System.out.println(getInfo());  

    }  

    private String getInfo() {  

        return "A";  

    }  

}  

  

class B extends A{  

    public String getInfo() {  

        return "B";  

    }  

}</span>  

运行结果是 A A。若是将private修饰词去掉,换成protected和public修饰,运行结果是A B这是毫无疑问的,由于那正是B重写了父类A的getInfo方法;而加上了private修饰词之后,父类A的getInfo和子类B的getInfo实际上就是两个无关的方法,由于私有方法是不能被子类重写的,私有方法并非父类接口的一部分,只是隐藏在父类中的一段程序代码。

但是为何使用子类B的实例调用printPerson,结果是打印A呢?要注意到printPerson方法是在父类A中定义的,所以刚执行new B().printPerson()这行代码时,编译器在子类B中没法找到匹配的printPerson方法,因而到父类A中去寻找;此时在父类A中找到了匹配的printPerson方法,并调用该方法。

 

此处须要说起一会儿类在继承父类时对父类的成员变量及方法继承的问题。对于使用protected或者public修饰的成员变量及方法,会被子类继承,且可经过子类直接调用,那么,对于子类不可见的private成员,以及没有修饰词修饰的成员(若子类与父类在不一样的包中,这一类成员也是对子类不可见的),他们不被子类继承,那么在子类的实例所表明的内存空间中,这些成员是否存在呢?答案是确定的,父类的私有变量及方法虽然不会被子类继承,对于子类来讲不可见,但当建立了子类的实例的时候,这些成员同样会被加载入内存,并“隐藏”在内存当中。

 

所以,经过子类B的实例调用printPerson方法,会在父类的成员中寻找匹配的printPerson方法,找到之后,进入printPerson的方法体,调用getInfo方法,程序回到上层去寻找getInfo方法的匹配,并在内存空间中寻找到了A中的getInfo方法,同时因为该getInfo方法是私有的,没法被重写,所以不会触发java的动态绑定机制,因而直接调用该方法。所以,经过B的实例调用printPerson,打印的结果也是A了。

============================================

 

最近学习继承,从书中看到子类继承父类,子类拥有父类全部的属性和方法,因而使用程序去验证,发现父类的私有属性和私有方法,子类是不能访问的,固然一些父类的私有属性可能能够经过相应的方法访问到,可是私有的方法彷佛不能简单的访问,这里暂不考虑Java反射机制,因而我分析,子类不能继承父类私有的属性及方法,可是分析了内存后,我发现我是错的,在一个子类被建立的时候,首先会在内存中建立一个父类对象,而后在父类对象外部放上子类独有的属性,二者合起来造成一个子类的对象。因此所谓的继承使子类拥有父类全部的属性和方法其实能够这样理解,子类对象确实拥有父类对象中全部的属性和方法,可是父类对象中的私有属性和方法,子类是没法访问到的,只是拥有,但不能使用。就像有些东西你可能拥有,可是你并不能使用。因此子类对象是绝对大于父类对象的,所谓的子类对象只能继承父类非私有的属性及方法的说法是错误的。能够继承,只是没法访问到而已。

 

当子类覆盖父类的成员变量时,父类方法使用的是父类的成员变量,子类方法使用的是子类的成员变量

 

(1)子类覆盖父类的方法,必须有一样的参数返回类型,不然编译不能经过

          (2)子类覆盖父类的方法,在jdk1.5后,参数返回类能够是父类方法返回类的子类

         (3)子类覆盖父类方法,能够修改方法做用域修饰符,但只能把方法的做用域放大,而不能把public修改成private

          (4)子类方法可以访问父类的protected做用域成员,不可以访问默认的做用域成员

         (5)子类的静态方法不能隐藏同名的父类实例方法

 

 

 

 不能继承,子类只能在父类中写一个public的getXXX的方法来获取父类中的private属性,子类就调用父类的getXXX来获取private属性

 

 父类中的公有方法和域(属性),在类继承中将会被子类继承,可是私有的将不能被继承。

 

那么在继承中子类如何才能继承到父类的私有域呢?

 

答案是:在子类的构造方法中经过super()方法调用父类的构造方法。

 

也就是,在构造子类的同时,为子类构造出跟父类相同的域。如此就在子类的对象中,也拥有了父类声明的域了。

 

而且咱们也应该这样作。

 

[html] view plaincopy

public class Person{  

    private String name;  

      

    public Person(String name){  

        this.name = name;  

    }  

      

    public void setName(String name){  

        this.name = name;  

    }  

      

    public String getName(){  

        return name;  

    }  

}  

[html] view plaincopy

public class Student extends Person{  

      

    public Student(String name){  

        super(name);  

    }  

}  

 

 

 

[html] view plaincopy

public class TestStudent{  

    public static void main(String[] args){  

      

        Student mStudent = new Student("abc");  

        String mName = mStudent.getName();  

        System.out.println("Name is : " + mName);  

          

        mStudent.setName("efg");  

        mName = mStudent.getName();  

        System.out.println("Name is : " + mName);  

          

    }  

}  

打印结果为:

 

Name is : abc

 

Name is efg

 ============================================

 

Java-子类没有继承父类的私有变量和私有方法

 

  在Java子类有没有继承父类的私有变量?关于这个问题在网上找了好久,也没有一个明确的答案。因而综合你们的观点,本身总结了一下。 

   

  官方文档的解释:“A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.”。原文地址:Inheritance 

  那么问题来了。以前在作Java实验时,为何Manger类能使用Employee的私有属性呢? 

  我找了一下答案: 

  观点一: 

  “父类中的公有方法和域(属性),在类继承中将会被子类继承,可是私有的将不能被继承。那么在继承中子类如何才能继承到父类的私有域呢?答案是:在子类的构造方法中经过super()方法调用父类的构造方法。”参考:Java中子类继承了父类的私有属性及方法吗?、 

  写了测试代码体会了一下:

 

public class Father 

{

    private int a;

    public Father()

    {

 

    }

    public Father(int a)

    {

        this.a = a;

    }

    public int getA()

    {

        return this.a;

    }

}

 

public class Children extends Father

{

    int b;

    public Children()

    {

 

    }

    public Children(int a,int b)

    {

        //this.a = a;

        super(a);

        this.b = b;

    }

}

 

public class Main 

{

    public static void main(String[] args) 

    {

        Children child1 = new Children(13,35);

        System.out.println(child1.b+"  "+child1.getA());

 

    }

 

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

  观点二: 

  “父类的任何成员变量都是会被子类继承下去的。实际上,private,public,protected和继承没有关系,他们对成员函数和变量的限制只是在成员的可见性上。”参考:私有的成员能被子类继承吗? 

   

  观点三: 

  “父类的private变量,也会被继承而且初始化在子类父对象中,只不过对外不可见。”。他这个观点的提出是从内存上分析的,值得借鉴。参考:JAVA 继承 父类子类 内存分配 

   

  个人总结: 

  从继承的概念来讲,private和final不被继承。Java官方文档上是这么说的。 

  从内存的角度来讲,父类的一切都被继承(从父类构造方法被调用就知道了,由于new一个对象,就会调用构造方法,子类被new的时候就会调用父类的构造方法,因此从内存的角度来讲,子类拥有一个完整的父类)。子类对象所引用的内存有父类变量的一份拷贝。 

  如图所示,父类为Person类,子类为Student类。首先明确子类不能继承父类的构造方法。这就是为何子类的默认的构造方法会自动调用父类的默认的构造方法。 

  在子类的构造方法中经过super()方法调用父类的构造方法。也就是,在构造子类的同时,为子类构造出跟父类相同的域。如此就在子类的对象中,也拥有了父类声明的域了。

相关文章
相关标签/搜索