java中的构造函数为什么不自动被子类复用?

milunhailili 2011-12-09 05:56:01
我们知道,非私有的父类方法调用,非常方便。
但是构造函数为何不行?当然,函数名不一样,但是构造函数有其特殊性,所以编译器是完全可以实现。
但是java,c++中都是设计成不能自动被子类调用,而是要显示调用。

可能有的人不明白我的意思,我写下面两段代码(随手写的,无法编译):


//父类
TPerson = class
strict private
FName: string;
public
constructor Create(AName: string);
procedure Eat; virtual; abstract;
property Name: string read FName write FName;
end;

//子类
TStudent = class(TPerson)
public
procedure Eat; override;
end;

implemention

constructor TPerson.Create(AName: string);
begin
FName = AName;
end;

procedure TStudent.Eat;
begin
ShowMessage(Name + '用筷子吃饭');
end;

//调用的时候
var
S: TStudent;
S : = TStudent.Create('sunny'); //TPeron的构造函数自动成了TStuent的构造函数
S.Eat;





abstract class Person{
String name;
Person(){
System.out.println("Person无参");
}
Person(String name){
this.name = name;
}
abstract void eat();
}

class Student extends Person{
void eat(){
System.out.println(name + "-->用筷子吃饭");
}
Student(){
super();
}
Student(String name){ //这个方法可以省略吗,为什么写在这里这么丑???
super(name);
}
}

//使用
class Test{
public static void main(String args []){
Student s = new Student("sunny"); //如果上面省略了,这里怎么构造学生对象。
s.eat();
}
}
...全文
352 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
walkman_22 2011-12-24
  • 打赏
  • 举报
回复
一般继承的关系很少有完全一致的初始化条件,所以我觉得是非常合理的。
baillluu 2011-12-24
  • 打赏
  • 举报
回复
子类构造默认调用父类的无参构造!
当父类是只有有参构造时,因该在子类指明调用父类有参构造“super(....)”
milunhailili 2011-12-24
  • 打赏
  • 举报
回复
没人对这个问题感兴趣吗。
milunhailili 2011-12-22
  • 打赏
  • 举报
回复
这个问题其实困扰我很久了。可能就是一种人为规定或者取舍吧。
确实如果父类的构造函数初始化了父类的某个私有变量,这样子类自动继承的时候带来了一定的问题。
除此之外我想不到其它的问题。
但是却给子类的初始化带来了更大的方便,所以我一直觉得子类自动继承是利大于弊的。
之前一直用Delphi,它也正是父类的构造函数自动成为子类的,让我的思维有了定势,认为这样是自然的,
可能也是我的思维固化吧。

我觉得一门语言,越自然越好,人为规定的东西越少越好(除了语法之外)。
像java类库中的命中我就蛋疼了很久。像Reader 和InputStream从作用上来看,应该算是兄弟类,可是这名取得。。而且这是终端类,这命名完全看不出作用。与编程理论中的见名知义不符合。

我也只是发发牢骚,肯定无法理解国外大牛们的思维,可能别人有其它方面的考虑吧。
iGoodLoser 2011-12-16
  • 打赏
  • 举报
回复
回楼上:
其实楼主说的应该是为什么子类为什么不能默认自动继承父类的构造器。
比如说,
class Person{
Person(String name){
//...
}
}

class Student{
//..不需显示的声明自己的构造器
}

class Test{
static void main(String[] args){
new Student("NAME");//默认自动继承父类的构造器!
}
}

不知是不是楼主的想法?
或许这当时设计java语言时没有考虑到吧?
其实这样也未尝不好,虽说有时有些累赘,但也不失灵活性
比如,当子类的构造器完全没必要或不需要完成与父类相同的初始化时这样显示的声明然后完成子类想要完成的初始化就行了,而如果自动继承父类额构造器则可能限制子类完成一些不必要的从父类继承下来的初始化动作!个人意见仅供交流!
dxqrr 2011-12-16
  • 打赏
  • 举报
回复
LZ的意思大概是构造方法不能被继承吧
很简单,因为父亲的构造方法不一定会适合子类,比如子类参数变多的情况,
并且,如果继承了话,在代码中该如何使用了,
子类 z = new 父类构造方法(),这可是错误的,所以子类继承构造方法的就没什么意义了

但是子类完全可以调用父类的构造方法

如果子类没有显示的调用super方法,则会自动调用父类没有参数的构造方法,反之,则调用super指定的方法,这样就完全可以复用父类的构造方法了
gukuitian 2011-12-16
  • 打赏
  • 举报
回复
要不父类没有与子类同参的构造函数,楼主又打算怎么办?
龙四 2011-12-16
  • 打赏
  • 举报
回复

class Student extends Person{
void eat(){
System.out.println(name + "-->用筷子吃饭");
}
Student(){
super();
}
Student(String address){
super(name);//你不会想这里的address自动传给name吧
}
}
龙四 2011-12-16
  • 打赏
  • 举报
回复
"但是java,c++中都是设计成不能自动被子类调用"


无论还是c++,如果没有显式调用父类的构造方法,都会自动调用父类无参的构造方法

你不会想它们自动调用父类有参的构造方法吧
milunhailili 2011-12-16
  • 打赏
  • 举报
回复
怎么没几个人来讨论这个问题呢?
既然Java放弃了这种想法,我想一定是有它的道理的。

是不是我的提问太长了,导致一些人懒得看。。

不要浮躁,要有耐心。
lxbccsu 2011-12-16
  • 打赏
  • 举报
回复
说到继承,大家都说子类会继承父类中除private修饰的fields(字段)和methods(方法)

再读了一遍,是子类会继承父类中除private修饰的fields(字段)和methods(方法)

构造器不是method,就是这样。
ntong 2011-12-16
  • 打赏
  • 举报
回复
[Quote=引用楼主 milunhailili 的回复:]
Student(String name){ //这个方法可以省略吗,为什么写在这里这么丑???
super(name);
}
}

//使用
class Test{
public static void main(String args []){
Student s = new Student("sunny"); //如果上面省略了,这里怎么构造学生对象。
s.eat();
}
[/Quote]

Student(String name) 方法可以省略,
还可以这样构造Student 对象:
Student s = new Student();
s.name="sunny";
Antineutrino 2011-12-16
  • 打赏
  • 举报
回复
上面的类B中,重不重写showName方法都是一样的,B类只要定义name变量就行,结果一样
Antineutrino 2011-12-16
  • 打赏
  • 举报
回复
很简单,举个例子:
假设B继承A:
class A:

private String name;
public A(String name) {
this.name = name;
}
public void showName() {
System.out.println(name);
}



class B (extends class A):
private String name;
public void showName() {
System.out.println(name);
}


main方法中:

B b = new B("xxxx");
b.showName(); // print null?!


看出来问题了吗?你明明已经传入了一个名字,但show出来的却是null
其实这只是问题之一而已。构造方法不同于一般的方法,不能让子类随便继承的
龙腾冰 2011-12-16
  • 打赏
  • 举报
回复
11楼说的有道理
beiouwolf 2011-12-16
  • 打赏
  • 举报
回复
真奇怪...
为什么子类构造函数需要去调用父类的有参构造函数???
这问题就像是你喜欢西餐,我喜欢中餐一样
或者说,你跑到小肥羊,说为什么你们这里不卖法式鹅肝?
jason_deng 2011-12-13
  • 打赏
  • 举报
回复
milunhailili的提问非常好,JAVA就是当初设计的时候,没有通过,将这一点(跟milunhailili所想得一样)想到,所以导致了milunhailili所说的为对象的初始化带来了麻烦,子类只能通过super关键字来显示调用父类的构造方法。

milunhailili 2011-12-10
  • 打赏
  • 举报
回复
但是java这样设计为对象的初始化带来了一定的麻烦。

因为父类的构造函数不能默认成为子类的构造函数。

awusoft 2011-12-09
  • 打赏
  • 举报
回复
父类提供了多个构造函数,你子类爱怎么构造就怎么构造啊.反正父类就是提供了这些函数.

class Person
{

String name;
public void setName(String name)
{
this.name=name;
}
public String getName()
{
return this.name;
}
}

你的题目中,如果省略了,你可以
Student s = new Student();
只是它的name是空的而已

62,610

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧