一句话概括就是:子类一定会调用(不是继承)父类的构造方法!
即遵循一个原则:子类的构造一定是在父类已构造的基础上!
这句话要分为几种情况来理解(下面只讨论父类有构造函数):
子类构造函数自动调用super() (也可以手动加上)
但如果父类只有含参数的构造方法,那么子类必须申明一个构造方法,其中包含对super(args)的调用
一、父类含有无参构造函数
1、子类没有构造方法或者含有无参的构造方法:
这种情况,都会默认地调用super()
2、子类含有有参数构造方法:
同样会在首句默认调用super() //其实跟情况1类似
二、父类含有含参数的构造方法,不含无参数的构造方法:
子类没得选择:
子类必须申明一个构造方法(且含super的args),且方法里要首先调用super(args),否则报错。
三、父类含 含参数的构造方法和无参的构造方法:
此时子类可以选择性调用:
可以无构造方法:仍会默认调用super()
也可以有构造方法:其中会默认地调用super(),你也可以在开头加上这句,如果你不希望调用父类默认的无参方法,那么在 子类构造方法 中调用 父类含参构造方法。
上述看似情况复杂,其实基于其原则理解并不难。
综上:java为了保持 子类的构造基于父类的构造 这一原则,子类构造时必须通过某些方式首先调用父类的构造方法,否则会报错。不妨给你个例子程序,更能说明问题。下面是正方形类继承矩形类
interface EqualDiagonal{
public double getDiagonal();
}
class Rectangle implements EqualDiagonal{
double a , b;
Rectangle(){}
//如果父类中没有无参的构造方法,编译出错
Rectangle (double x,double y){
thisa = x;
thisb = y;
}
public double getDiagonal(){
return Mathsqrt(a a + b b);
}
}
class Square extends Rectangle implements EqualDiagonal{
double a;
Square (double x){
super();//子类在构造的过程中必须调用其父类的构造方法
//这句话可写可不写,因为
//如果子类的构造方法中没有显示调用父类构造方法,则编译器默认调用父类无参数的构造方法
thisa = x;
}
public double getDiagonal(){
return Mathsqrt(20 a a);
}
}
class TestSquare{
public static void main(String []args){
Rectangle r = new Rectangle(30,40);
Square s = new Square (10);
Systemoutprintln(rgetDiagonal());
Systemoutprintln(sgetDiagonal());
}
}
打字不易,如满意,望采纳。
您好,提问者:
太不专业了,构造方法怎么会存在继承?
不写默认的有个隐士的构造方法,举个例子吧:
class A{void add();
}
public class B extends A{
public B(){
super(); //这个super也是隐士的。
}
}
//如何知道有个默认的super()呢?看下面代码
class AA{
public AA{
Systemoutprintln("super()");
}
}
public class BB extends AA{
public static void main(String[] args){
new BB(); //输出super();
}
}
先小小纠正一下,java里面一般不叫函数,叫方法,这是Java的一个小习惯。
你这个问题原因很简单。
首先,任何类都有构造方法,难怕是你不写,也会默认你有一个有无参构造方法。,所以你的A里面就会有一个叫A()的构造方法。
当你new A()时,默认你有一个有无参构造方法A()的方法里的第一句,会自动加上一个super();的方法,这句就是调用父类构造方法的意思,这是java规定的规则。
你可以尝试一下,在A里写一个构造方法:
A(){
super(); //这个一定要放在第一句
SystemoutXX;
}
这与你不写super()这句效果是一样的,因如果没写,java会默认在第一句加上super。
1构造函数的命名必须和类名完全相同。在java中普通函数可以和构造函数同名,但是必须带有返回值;
2构造函数的功能主要用于在类的对象创建时定义初始化的状态。它没有返回值,也不能用void来修饰。这就保证了它不仅什么也不用自动返回,而且根本不能有任何选择。而其他方法都有返回值,即使是void返回值。尽管方法体本身不会自动返回什么,但仍然可以让它返回一些东西,而这些东西可能是不安全的;
3构造函数不能被直接调用,必须通过new运算符在创建对象时才会自动调用;而一般的方法是在程序执行到它的时候被调用的;
4当定义一个类的时候,通常情况下都会显示该类的构造函数,并在函数中指定初始化的工作也可省略,不过Java编译器会提供一个默认的构造函数此默认构造函数是不带参数的。而一般的方法不存在这一特点;
5构造函数有回滚的效果,构造函数抛出异常时,构造的是一个不完整对象,会回滚,将此不完整对象的成员释放(c++)
6当一个类只定义了私有的构造函数,将无法通过new关键字来创建其对象,当一个类没有定义任何构造函数,C#编译器会为其自动生成一个默认的无参的构造函数。[1]
7在Python中构造函数必须通过重写__init__方法实现
子类不能继承父类的显式定义的构造方法,若想要继承父类的构造方法,需要通过覆盖该构造方法,并在方法中通过super调用父类的该构造方法的方式来继承。
三种情况说明:
1、父类中没有显式定义任何构造方法,此时父类中实际有一个默认的无参数构造方法。这时,在子类中显式定义任何构造方法时,可以不用使用super调用父类的默认方法。
2、父类中显式定义了默认的无参数构造方法,那么子类可以定义任意的构造方法,而不必使用super调用父类的构造方法
3、父类中显示定义了构造方法,却没有显示定义默认的无参数构造方法,那么子类定义任何构造方法中都需要通过super调用父类的构造方法
相关代码比较
1public class Father {
public void otherMethod(){
}
}
public class Child extends Father {
//任意构造方法
public Child(int b){
Systemoutprintln(b);
}
public void otherChildMethod(){
}
}
2
public class Father {
public Father(){
}
public Father(String q){
Systemoutprintln(q);
}
public void otherFatherMethod(){
}
}
public class Child extends Father {
//任意构造方法
public Child(int b){
Systemoutprintln(b);
}
public Father(String q){
Systemoutprintln(q);
}
public Child(String t, int b){
}
public void otherChildMethod(){
}
}
3
public class Father {
public Father(String q){
Systemoutprintln(q);
}
public void otherFatherMethod(){
}
}
public class Child extends Father {
public Child(String b){
super(b);
Systemoutprintln(b);
}
//任意构造方法
public Child(String t, int b){
super(t);
Systemoutprintln(b);
}
public Child(String t, int b){
}
public void otherChildMethod(){
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)