关于Java继承中父类和子类构造函数的问题

Java子类在实例化时默认调用的是父类的无参构造函数,不论实例化时调用的是子类的有参还是无参构造函数,

可以参考这篇Java子类实例化总是默认调用父类的无参构造操作

1、当父类没有显式定义构造方法时,

编辑器会默认为此类添加一个隐式无参构造函数。此时子类可以有自己的无参和有参构造方法。不论实例化时调用的是子类的有参还是无参构造函数,默认调用的是父类的无参构造函数。

2、当父类有显式定义无参构造方法时,

此时子类也可以有自己的无参和有参构造方法。类似于1,同样默认隐式调用父类的无参构造方法。

3、当父类只有显式定义有参构造方法时,

(1)子类定义无参方法会出错:Implicit super constructor Father() is undefined. Must explicitly invoke another constructor,即隐式父类构造函数Father()未定义, 必须显式调用另一个构造函数,当此时调用父类的有参构造函数时,使用super(i),这里i是参数,会提示i没有定义,因为此时是无参构造函数,此时要使子类也有无参构造函数,只能在子类的无参构造函数中调用父类的有参构造函数,并给父类的有参构造函数赋一个实参;

(2)在子类的有参构造函数中使用super(i)调用父类的有参构造函数不会出错,因此若父类只有有参的构造方法,子类也只能有有参的构造方法,且子类的有参构造方法必须显示调用父类的有参构造方法。

分析:默认都是调用父类的无参构造函数,当父类有有参构造函数时,编辑器不会为父类添加无参的构造函数,在子类继承父类时,本来是默认在构造函数第一行都是默认有使用super()调用父类无参构造函数的,现在父类没有无参构造函数,因此提示显示调用另一个构造函数(即有参构造函数)。

提醒一点,当没有子类继承父类时,父类只定义有参构造函数是没有问题的。

4、当父类和子类都有无参和有参构造方法时,默认是子类构造方法都是调用父类的无参构造方法的,但当子类的有参构造方法使用super(i)调用父类的有参构造方法时,带参数实例化时就不再调用父类的无参构造方法,而是调用父类的有参构造方法,因为是显示调用(人为强制的)。

总结:

父类有无参构造函数时(显示或隐式),子类的有参和无参构造函数都是默认调用父类的无参构造函数;当父类只有有参构造函数时,子类可以有有参和无参构造函数,子类有参构造函数必须显式调用父类的有参构造函数,子类无参构造函数也必须显式调用父类的有参构造函数,但需给父类有参构造函数赋实参。

1中的示例:

package classTest;
class Father1{

}
class Son1 extends Father1{
 public Son1() {
 System.out.println("子类的无参构造方法");
 }
 public Son1(int i) {

 System.out.println("子类中有参构造方法"+i);
 }
}
public class TestExtend {
public static void main(String[] args) {
 Son1 s = new Son1();
}
}

运行结果:

子类的无参构造方法

2中的示例:

package classTest;

class Father1{
 public Father1() {
 }
}
class Son1 extends Father1{
 public Son1() {
 System.out.println("子类的无参构造方法");
 }
 public Son1(int i) {
 System.out.println("子类中有参构造方法"+i);
 }
}
public class TestExtend {
public static void main(String[] args) {
 Son1 s = new Son1();
}
}

运行结果:

子类的无参构造方法

3中的示例(1):

package classTest;
class Father1{

 public Father1(int i) {
 System.out.println("父类中的有参构造方法"+i);
 }
}
class Son1 extends Father1{

 public Son1() {
  //下两行需注释掉一行
 super(i);//此时会报错
 super(1);//此时不会报错,调用父类构造函数,但参数值是固定的,不能在调用时传入其他值。
 System.out.println("子类的无参构造方法");
 }
 public Son1(int i) {
   super(i);
 System.out.println("子类中有参构造方法"+i);
 }
}
public class TestExtend {
public static void main(String[] args) {
 Son1 s = new Son1();
}
}

结果:显示参数没有定义

Exception in thread "main" java.lang.Error: Unresolved compilation problem: i cannot be resolved to a variable

3中的示例(2):

package classTest;
class Father1{
 public Father1(int i) {
 System.out.println("父类中的有参构造方法"+i);
 }
}
class Son1 extends Father1{
 public Son1(int i) {
   super(i);
 System.out.println("子类中有参构造方法"+i);
 }
}
public class TestExtend {
public static void main(String[] args) {
 System.out.println("-----");
 Son1 a = new Son1(5);
}
}

结果:

-----

父类中的有参构造方法5

子类中有参构造方法5

4中的示例:

package classTest;
class Father1{
 public Father1() {
 System.out.println("父类的无参构造方法");
}
 public Father1(int i) {
 System.out.println("父类中的有参构造方法"+i);
 }
}
class Son1 extends Father1{

 public Son1() {
 System.out.println("子类的无参构造方法");
 }
 public Son1(int i) {
   super(i);
 System.out.println("子类中有参构造方法"+i);
 }
}
public class TestExtend {
public static void main(String[] args) {
 Son1 s = new Son1();
 System.out.println("-----");
 Son1 a = new Son1(5);
}
}

结果:

父类的无参构造方法

子类的无参构造方法

-----

父类中的有参构造方法5

子类中有参构造方法5

以上这篇关于Java继承中父类和子类构造函数的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Java中父类怎么调用子类的方法

    父类能调用子类的方法吗? 答:能. 怎么做? 把子类传递到父类的有参构造中,然后调用. 使用反射的方式调用,你使用了反射还有谁不能调用的?! 父类调用子类的静态方法. 案例展示: package com.ywq; public class Test2{ public static void main(String[] args) { Son son = new Son(); Father father=new Father(son); father.fun1(); father.fun4();

  • 浅谈Java中父类与子类的加载顺序详解

    复制代码 代码如下: class Parent {    // 静态变量    public static String p_StaticField = "父类--静态变量";    // 变量(其实这用对象更好能体同这一点,如专门写一个类的实例)     //如果这个变量放在初始化块的后面,是会报错的,因为你根本没有被初始化    public String p_Field = "父类--变量";    // 静态初始化块    static {        S

  • Java编程关于子类重写父类方法问题的理解

    子类重新实现父类的方法称重写:重写时可以修改访问权限修饰符和返回值,方法名和参数类型及个数都不可以修改:仅当返回值为类类型时,重写的方法才可以修改返回值类型,且必须是父类方法返回值的子类:要么就不修改,与父类返回值类型相同.那么,该如何理解呢?为什么要是父类返回值类型的子类? 提出问题:子类必须重写父类所有方法吗? Java,子类不是必须重写父类所有方法的,分为以下两种情况: 父类方法为抽象方法时,子类必须重写(实现)所有父类的抽象方法: 父类方法为普通方法时,子类可以重写父类方法,也可以不重写

  • java的继承原理与实现方法详解

    本文实例讲述了java的继承原理与实现方法.分享给大家供大家参考,具体如下: 继承 1.java中是单继承的.每个子类只有一个父类. 语法:子类 extends 父类 2.在java中,即使没有声明父类,也有一个隐含的父类,就是Object类 3.在子类中可以使用super来调用父类的方法 4.继承中的构造方法问题 在new一个子类实例的过程中,会优先自动调用父类默认的无参数构造方法,然后再调用子类的构造方法.如果父类没有默认的构造方法,只有带参数的构造方法,此时就会出错. 除了由jvm自动调用

  • 关于Java继承中父类和子类构造函数的问题

    Java子类在实例化时默认调用的是父类的无参构造函数,不论实例化时调用的是子类的有参还是无参构造函数, 可以参考这篇Java子类实例化总是默认调用父类的无参构造操作 1.当父类没有显式定义构造方法时, 编辑器会默认为此类添加一个隐式无参构造函数.此时子类可以有自己的无参和有参构造方法.不论实例化时调用的是子类的有参还是无参构造函数,默认调用的是父类的无参构造函数. 2.当父类有显式定义无参构造方法时, 此时子类也可以有自己的无参和有参构造方法.类似于1,同样默认隐式调用父类的无参构造方法. 3.

  • 浅谈java继承中是否创建父类对象

    1. 调用父类构造方法是真的,但是根本没有创建父类对象,只不过是调用父类构造方法来初始化属性. 如果说调用父类构造方法就等于创建父类对象,那就真的无稽之谈. new指令开辟空间,用于存放对象的各个属/性引用等,反编译字节码你会发现只有一个new指令,所以开辟的是一块空间,一块空间就放一个对象. 然后,子类调用父类的属性,方法啥的,那并不是一个实例化的对象. 在字节码中子类会有个u2类型的父类索引,属于CONSTANT_Class_info类型,通过CONSTANT_Class_info的描述可以

  • Java中父类和子类之间的转换操作示例

    本文实例讲述了Java中父类和子类之间的转换操作.分享给大家供大家参考,具体如下: 一.父类引用强转成为子类引用 package learn20180720; public class People { private String name; private Integer age; private Double height; public People(){ this.name = ""; this.age = 0 ; this.height = 0.0; } public Pe

  • 浅谈Java继承中的转型及其内存分配

    看书的时候被一段代码能凌乱啦,代码是这样的: package 继承; abstract class People { public String tag = "疯狂Java讲义"; //① public String name = "Parent"; String getName(){ return name; } } class Student extends People { //定义一个私有的tag实例变量来隐藏父类的tag实例变量 String tag =

  • java继承中的构造方法实例解析

    本文实例讲述了java继承中的构造方法.分享给大家供大家参考.具体如下: 继承中的构造方法: 1.子类的构造过程中必须调用其基类的构造方法. 2.子类可以在自己的构造方法中使用super(argument_list)调用基类的构造方法. 2.1.使用this(argument_list)调用本类的另外构造方法.   2.2.如果调用super,必须写在子类构造方法的第一行. 3.如果子类的构造方法中没有显示的调用基类的构造方法,则系统默认调用基类的无参数构造方法. 4.如果子类构造方法中既没有显

  • JAVA 多态操作----父类与子类转换问题实例分析

    本文实例讲述了JAVA 多态操作----父类与子类转换问题.分享给大家供大家参考,具体如下: JAVA语言中, 对象变量是多态的 每个子类对象都算是父类对象(子类对象可以当作父类变量所引用) 那反过来可不可以呢? 答案是取决于父类变量引用的是谁 如果父类变量引用的是子类对象的实例, 可以通过强转被子类变量引用 如果父类变量引用的是父类对象的实例,则不能被为子类变量引用 上代码举例子(本篇一直用这两个类举例子,main测试不同): 一个Father类 package test; public cl

  • 解析Java继承中方法的覆盖和重载

    方法的覆盖 在类继承中,子类可以修改从父类继承来的方法,也就是说子类能创建一个与父类方法有不同功能的方法,但具有相同的名称.返回值类型.参数列表. 如果在新类中定义一个方法,其名称.返回值类型和参数列表正好与父类中的相同,那么,新方法被称做覆盖旧方法. 参数列表又叫参数签名,包括参数的类型.参数的个数和参数的顺序,只要有一个不同就叫做参数列表不同. 被覆盖的方法在子类中只能通过super调用. 注意:覆盖不会删除父类中的方法,而是对子类的实例隐藏,暂时不使用. 请看下面的例子: public c

  • 详解Java继承中属性、方法和对象的关系

    大家都知道子类继承父类是类型的继承,包括属性和方法!如果子类和父类中的方法签名相同就叫覆盖!如果子类和父类的属性相同,父类就会隐藏自己的属性! 但是如果我用父类和子类所创建的引用指向子类所创建的对象,父类引用所调用子类对象中的属性值或方法的结果是什么呢? 看代码: public class FieldDemo { public static void main(String[] args){ Student t = new Student("Jack"); Person p = t;/

  • Java继承方法重写实现原理及解析

    这篇文章主要介绍了Java继承方法重写实现原理及解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在Java继承中,子类可以获得父类所有的结构,也可以增加与父类不同的属性和方法.但是,有一种情况,一个相同的方法,子类的行为并不像父类那样,这时,就需要重写父类的方法,下面是重写的代码实现: 代码体现 package com.my.pac12; /** * @author Summerday * @date 2019/12/11 21:26 */

随机推荐