不能说的秘密-重载、重写与继承中的构造方法
2016-11-07 14:45
281 查看
我相信有些同学在学习过程中肯定会遇到一些问题,本帖就是针对同学门遇到的一些问题讲解一下。
首先,大家要先弄懂重载和重写的区别:
重载(Overloading):在同一个类中,方法名相同,参数列表不同,与返回值和修饰符无关。
重写(Overriding): 在子类与父类中,方法名和参数列表都相同,返回值类型要与父类中被重写的方法中声明的返回类型或子类型完全相同,修饰符的访问级别一定不能比被重写方法强,可以比被重写方法的弱 。
关于重写和重载的区别,这个帖子写的很详细
那么大家看一下这个问题,B类里面的run方法是重载了还是重写了A类中的run方法?:
由于新手很容易搞混淆重载和重写,一看在两个类里面就先入为主说是重写,但是仔细看一下,这里的A和B中的run方法参数列表是不同的,虽然在两个类里面,但是B类继承了A类,所以B类继承了A类里面的run方法(可以看成B类里面也有了一个run方法,跟A类里面的一模一样,只不过你看不到罢了),所以这也是方法的重载,不是重写!
那我们再来说一下继承中的构造方法:
首先我们先看一下这个例子:
在上面这个例子中,我们创建了一个B类的对象,但是你发现B的构造器会编译报错,为什么呢?我们首先来看一下继承中的构造方法要遵循哪些原则
1、子类的构造过程中必须调用其基类的构造方法(也就说在运行子类构造方法时肯定是先运行父类的构造方法)。
2、子类可以在自己的构造方法中使用super(argument_list)调用基类的构造方法。
2.1、使用this(argument_list)调用本类的另外构造方法。
2.2、如果调用super,必须写在子类构造方法的第一行。
3、如果子类的构造方法中没有显示的调用基类的构造方法,则系统默认调用基类的无参数构造方法。
4、如果子类构造方法中既没有显示调用基类构造方法,而基类又没有无参数的构造方法,则编译出错。
而在上面的例子中,我们创建了一个B类的对象,这时会先执行B的构造器,在执行B的构造器时会先执行其基类,也就是A的构造器。我们发现B类里面并没用super()调用基类的构造器,所以会默认调用它的无参构造,但是A类的构造器已经被A(int a)重载了,已经没有无参构造了,所以会在B的构造方法编译报错。违反了上述第4条。
我们再来验证一下上面几条规则:
1、
在new一个B的对象时会先执行它的构造方法,再执行它的构造方法时会先执行其基类的构造方法。
2、
在new B();时会先执行B的无参构造,而在B的无参构造器中调用了B的有参构造,所以会先执行A的有参构造,所以输出结果是A-有参B-有参B-无参。
3、
在new B();时会先执行B的无参构造,而在B的无参构造器并没有调用其基类的构造方法,所以会先默认执
a311
行A的无参构造,所以输出结果是A-无参B-有参B-无参。
4、看刚开始的例子。
首先,大家要先弄懂重载和重写的区别:
重载(Overloading):在同一个类中,方法名相同,参数列表不同,与返回值和修饰符无关。
重写(Overriding): 在子类与父类中,方法名和参数列表都相同,返回值类型要与父类中被重写的方法中声明的返回类型或子类型完全相同,修饰符的访问级别一定不能比被重写方法强,可以比被重写方法的弱 。
关于重写和重载的区别,这个帖子写的很详细
那么大家看一下这个问题,B类里面的run方法是重载了还是重写了A类中的run方法?:
class A{ void run(String run){ System.out.println("A"); } } class B extends A{ void run(int run){ System.out.println("B"); } }
由于新手很容易搞混淆重载和重写,一看在两个类里面就先入为主说是重写,但是仔细看一下,这里的A和B中的run方法参数列表是不同的,虽然在两个类里面,但是B类继承了A类,所以B类继承了A类里面的run方法(可以看成B类里面也有了一个run方法,跟A类里面的一模一样,只不过你看不到罢了),所以这也是方法的重载,不是重写!
那我们再来说一下继承中的构造方法:
首先我们先看一下这个例子:
class A{ public A(int a){ System.out.print("A"); } } class B extends A{ public B(){ System.out.print("B"); } } class Test{ public void main(String []args){ B b=new B();//是输出 AB 还是会编译报错?若报错,在哪里报错? } }
在上面这个例子中,我们创建了一个B类的对象,但是你发现B的构造器会编译报错,为什么呢?我们首先来看一下继承中的构造方法要遵循哪些原则
1、子类的构造过程中必须调用其基类的构造方法(也就说在运行子类构造方法时肯定是先运行父类的构造方法)。
2、子类可以在自己的构造方法中使用super(argument_list)调用基类的构造方法。
2.1、使用this(argument_list)调用本类的另外构造方法。
2.2、如果调用super,必须写在子类构造方法的第一行。
3、如果子类的构造方法中没有显示的调用基类的构造方法,则系统默认调用基类的无参数构造方法。
4、如果子类构造方法中既没有显示调用基类构造方法,而基类又没有无参数的构造方法,则编译出错。
而在上面的例子中,我们创建了一个B类的对象,这时会先执行B的构造器,在执行B的构造器时会先执行其基类,也就是A的构造器。我们发现B类里面并没用super()调用基类的构造器,所以会默认调用它的无参构造,但是A类的构造器已经被A(int a)重载了,已经没有无参构造了,所以会在B的构造方法编译报错。违反了上述第4条。
我们再来验证一下上面几条规则:
1、
class A{ public A(){ System.out.print("A"); } } class B extends A{ public B(){ System.out.print("B"); } } class Test{ public void main(String []args){ B b=new B();//会输出 AB } }
在new一个B的对象时会先执行它的构造方法,再执行它的构造方法时会先执行其基类的构造方法。
2、
class A{ public A(){ System.out.print("A-无参"); } public A(int a){ System.out.print("A-有参"); } } class B extends A{ public B(){ this(0); System.out.print("B-无参"); } public B(int a){ super(0);//必须写在子类构造器的首行,否则报错 System.out.print("B-有参"); } } class Test{ public void main(String []args){ B b=new B();//会输出 A-有参B-有参B-无参 } }
在new B();时会先执行B的无参构造,而在B的无参构造器中调用了B的有参构造,所以会先执行A的有参构造,所以输出结果是A-有参B-有参B-无参。
3、
class A{ public A(){ System.out.print("A-无参"); } public A(int a){ System.out.print("A-有参"); } } class B extends A{ public B(){ this(0); System.out.print("B-无参"); } public B(int a){ System.out.print("B-有参"); } } class Test{ public void main(String []args){ B b=new B();//会输出 A-无参B-有参B-无参 } }
在new B();时会先执行B的无参构造,而在B的无参构造器并没有调用其基类的构造方法,所以会先默认执
a311
行A的无参构造,所以输出结果是A-无参B-有参B-无参。
4、看刚开始的例子。
相关文章推荐
- 面向对象,类的组合关系,继承,实现,方法重写,方法重载,this的使用,抽象方法和抽象类的比较,父类构造方法存在的意义,多态的是用和解析,各种访问修饰符
- JavaDay06--Homework(方法重载和重写的区别,构造方法,继承类)
- 关于继承、构造、重载、重写
- 构造,封装,继承,多态,重载,重写,接口
- Scala 深入浅出实战经典 第12讲:Scala中的继承:超类的构造、重写字段、重写方法代码实战
- JAVA【类】析构器、重载与继承、方法的重写、自动转型、多态、方法与类的分类、接口继承
- (七)黑马程序员——oc基础之继承与重写构造方法
- EXT 笔记 构造方法,类继承,类实例方法重写
- Objective-C 类的继承、方法的重写和重载
- 类、对象、继承、封装、多态、方法的重载和重写、Java的访问修饰符与其它关键字
- 关于继承Fragment后重写构造方法而产生的错误
- 构造器、方法重载、继承、方法重写、自动转型、多态课堂笔记
- 简单的java实验,涉及到 类继承以及接口问题,方法体的重写(区别于重载)
- Dt大数据梦工厂王家林老师 Scala实战详解之第12讲 Scala中的继承:超类的构造、重写字段、重写方法代码实战
- C#中继承实现父类方法、重写、重载
- Java学习之面向对象(方法的重写 overwrite,super的使用,继承中的构造方法)
- java方法的重载(overload)与重写(override)的区分与构造方法的重载
- 类的继承,抽象类,接口,方法重写和重载
- Objective-c 类的继承 方法重写 方法重载
- JAV中一些基本概念:构造函数、方法重载、继承、方法重写、多态。