我是靠谱客的博主 光亮朋友,这篇文章主要介绍Java中父类和子类关于构造方法和私有属性的几个问题,现在分享给大家,希望可以做个参考。

Java中父类和子类关于构造方法和私有属性的几个问题

一、什么是默认构造方法?子类构造方法与父类构造方法的关系?
通过前面的学习可以知道:默认构造方法是指无参构造方法,(1)隐式包含的默认构造方法:当类的定义中没有任何显式的构造方法(无参或有参)时,则系统默认会给该类一个隐式的无参构造方法。 (2)显式定义的默认构造方法:当类中显式定义了一个无参构造方法。
对于以下示例:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//父类 public class Person { public String name; public int age; public Person(){ System.out.println("父类无参构造方法执行了"); } } //子类及其实现 public class Charactor extends Person { public void run(){ System.out.println("Charactor的实例对象开始奔跑!"); } public static void main(String[] args) { Charactor cp=new Charactor(); cp.run(); } }

运行结果如下:

复制代码
1
2
父类无参构造方法执行了 Charactor的实例对象开始奔跑!

这里注意到子类Charactor中并没有显式定义构造方法,但依然可以执行的原因是JVM编译时自动为其添加了默认构造方法(无参的),如下:

复制代码
1
public Charactor(){ }

如果显式地添加上述代码,运行结果是一致的。
我们还注意到运行结果中有“父类无参构造方法执行了”,说明父类构造方法也执行了,其实这里说明任何一个类的实例对象的实现(创建)都依赖于其父类实例对象的实现。而这里Charactor的构造方法中其实也隐式地调用了父类的构造方法,完整的Charactor构造方法如下:

复制代码
1
2
3
public Charactor(){ super(); }

可以发现显式添加上述代码后,运行结果依然一致。
从上面可以总结出:
*子类实例的创建依赖于父类的实例,所以就依赖于父类的构造方法,而如果没有显式地定义子类的构造方法,系统会自动隐式地给其添加无参构造方法。无论是直接显式编写代码还是系统自动添加的无参构造方法,系统都会在其中隐式地添加父类的默认构造方法。
那么当父类中缺少默认构造方法时呢?*

复制代码
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
public class Person { public String name; public int age; public Person(String name,int age){ this.name=name; this.age=age; System.out.println("父类构造方法执行了"); } } public class Charactor extends Person { public Charactor(){ super(null,-1); //必须显式地调用父类的构造方法 System.out.println("Charactor的构造方法执行了"); } public void run(){ System.out.println("Charactor的实例对象开始奔跑!"); } public static void main(String[] args) { Charactor cp=new Charactor(); cp.run(); } }

当把子类无参构造方法中super(null,-1)注释掉会发现编译出错,原因就在于系统会自动给子类构造方法隐式添加父类默认构造方法。可是这里在父类中并没有默认构造方法,所以在子类中必须显式调用父类有参构造方法。

二、私有属性
先看如下示例,属性均设为public访问类型。

复制代码
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
public class Person { public int age; public Person(){} public Person(int age){ this.age=age; System.out.println("父类构造方法执行了,年龄为:"+this.age); } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } public class Charactor extends Person { public Charactor(){} public Charactor(int age){ super(age+25); this.age=age; System.out.println("子类构造方法执行了,年龄为:"+this.age); } public void run(){ System.out.println("子类对象开始奔跑!"); } public static void main(String[] args) { Charactor cp=new Charactor(10); cp.run(); System.out.println("子类实例对象的年龄:"+cp.getAge()); System.out.println("子类实例对象的年龄:"+cp.age); } }

结果如下:

复制代码
1
2
3
4
5
父类构造方法执行了,年龄为:35 子类构造方法执行了,年龄为:10 子类对象开始奔跑! 子类实例对象的年龄:10 子类实例对象的年龄:10

可以看出虽然子类没有定义age属性和其get方法,但还是继承了父类。
而当父类中属性age设为private私有类型时,情况如何呢?

复制代码
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
public class Person { private int age; public Person(){} public Person(int age){ this.age=age; System.out.println("父类构造方法执行了,年龄为:"+this.age); } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } public class Charactor extends Person { public Charactor(){} public Charactor(int age){ super(age+25); this.age=age; System.out.println("子类构造方法执行了,年龄为:"+this.age); } public void run(){ System.out.println("子类对象开始奔跑!"); } public static void main(String[] args) { Charactor cp=new Charactor(10); cp.run(); System.out.println("子类实例对象的年龄:"+cp.getAge()); System.out.println("子类实例对象的年龄:"+cp.age); } }

代码中三处地方编译出错,其中子类参构造方法中:
this.age=age;
提示 The filed Person.age is not visible。即age属性不可见。那到底是子类未能继承父类Person中的age属性还是继承了但“不可见”呢?
为此添加this.name=name;编译出错提示为name cannot be resolved to a variable。提示类型与前面age不一样,而这里name是没有定义的,是不是可以假设age是已经被子类继承的属性,而只是“不可见”呢?如果没有继承该属性,提示应该和name一致吧。
把代码修改如下:

复制代码
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
public class Person { private int age; public Person(){} public Person(int age){ this.age=age; System.out.println("父类构造方法执行了,年龄为:"+this.age); } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } public class Charactor extends Person { public Charactor(){} public Charactor(int age){ super(age+25); this.setAge(age); System.out.println("子类构造方法执行了,年龄为:"+this.getAge()); } public void run(){ System.out.println("子类对象开始奔跑!"); } public static void main(String[] args) { Charactor cp=new Charactor(10); cp.run(); System.out.println("子类实例对象的年龄:"+cp.getAge()); cp.setAge(18); System.out.println("子类实例对象的年龄:"+cp.getAge()); } }

程序运行成功,结果如下:

复制代码
1
2
3
4
5
父类构造方法执行了,年龄为:35 子类构造方法执行了,年龄为:10 子类对象开始奔跑! 子类实例对象的年龄:10 子类实例对象的年龄:18

通过上例,暂且解决了自己关于子类继承父类私有属性的一些疑问,但这里只给自己做适当总结:对于父类中的private属性,子类会继承,但不可以直接访问,必须通过继承于父类的set/get方法访问。

补充:写完这篇去逛论坛,刚好看到这样一个帖子:
http://bbs.csdn.net/topics/391886219?page=1#post-400724401
自己也试着回答了一下,这里需要注意子类的实现依赖于父类,这就是为什么子类构造方法中总会隐式或者直接显式地调用父类构造方法的原因,其实再精确一些描述:子类实例对象的实现依赖于父类实例对象的实现,并且(其实是当然,理所当然)子类属性及其属性值均继承该父类实现。在子类构造方法执行完毕后,除非在其构造方法中对其属性初始值进行了修改设置,否则将与父类属性值相等。

复制代码
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
public class Papa { private String first_name; private int money; public Papa(String fname,int money){ this.first_name=fname; this.money=money; System.out.println(fname+"先生出生了。"); System.out.println(fname+"先生有"+money+"元财产!"); } public String getFirst_name() { return first_name;} public void setFirst_name(String first_name) { this.first_name = first_name;} public int getMoney() { return money;} public void setMoney(int money) {this.money = money;} } public class Son extends Papa{ public Son(String fname,int money){ super(fname,money); System.out.println(fname+"先生的儿子出生了。"); System.out.println(fname+"先生的儿子有"+money+"元财产!"); setMoney(money+10); System.out.println(fname+"先生的儿子的财产增加了,现在有"+(money+10)+"元财产!"); } } public class Test { public static void main(String[] args) { Son s=new Son("Cheng",100); System.out.println("小"+s.getFirst_name()+"有"+s.getMoney()+"元财产!"); } }

最后

以上就是光亮朋友最近收集整理的关于Java中父类和子类关于构造方法和私有属性的几个问题的全部内容,更多相关Java中父类和子类关于构造方法和私有属性内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(82)

评论列表共有 0 条评论

立即
投稿
返回
顶部