第三章:继承(上)

上节答案:A。解析:内部类也是一个类,可以有自己的成员方法和成员变量

 

3 - 1:Java中的继承

在前面的课程里面,对面向对象的三大特征之一,封装有了个基本的认识,那么我们现在再来看看什么是继承。

继承是类和类的一种关系,我们可以把它总结为“is a”的关系。例如,狗是动物,那么我们就可以描述,狗是继承动物。那狗类继承动物类,狗类就叫动物类的子类,或派生类,动物类就是狗的父类,或基类。这是他们两者之间的称呼。其实在生活当中,我们有很多继承的例子,例如,子女继承了父亲的财产,我们就称为富二代;子女拥有了父类的权力,我们就称这是官二代。那大家要注意,在我们Java中,是单继承的,就是说,一个类只有一个父类,和我们人一样,每个人只有一个亲爹。

继承的好处:我们想,生活当中,如果有一个好的父亲,我们通常可以说,可以少奋斗几年,也就意味着,父亲如果选得好的话,那么对于我们的成长是很有帮助的,我们自己就可以少干很多事情。在我们代码世界当中,也是这样的。如果两个类有了继承的关系,那么子类就直接拥有了父类的属性和方法,但是,父类的属性或方法的修饰符不能是private;如果我们父类实现了一些功能子类继承了父类,这样的话,我就可以复用父类所写的代码,我们把它称为代码的复用

语法规则:

class 子类 extends 父类{
    
}

例:

class Dog extends Animals{
    ...
}

好,我们来写一个Demo。

首先,我们有一个父类,动物类,还有一个类为子类,狗类,它继承于动物类,继承于父类动物类,这样的话我们在子类里面就不用再写相应的代码,此时我们就实现了代码的复用。

我们先在包里面创一个类Animal,然后再类里面创建两个属性一个int年龄,和一个名称,同时,可以给这个类一个吃东西的能力(方法)eat,输出动物具有吃东西的能力,这样的话,我一个基本的父类就写好了;

那现在有这样一个子类,Dog类,那我们想想,Dog是动物,所以说,它肯定会继承Animal这个父类,按照我们以前的写法,在Dog类里面也要写这些内容,由于Dog类和Animal有一个继承关系,此时Dog类就可以继承Animal类里面的所有属性和方法,那么,我们就不需要再写这部分代码了,从而实现我们代码复用的能力。

再在这个包里创建一个Dog类,这里要注意,这个类应该与Animal创建关联,所以我们要创建时点一下Superclass后面点一下browse...,出现这个:

点OK,然后Finish,这就创建了一个Dog的子类:

我们只通过extends关键字,就将我们的Dog类和Animal类建立起关联来。那我们在子类里并没有写任何属性和方法,那此时我们再创建一个测试类,Initial类,加入main方法,执行,那么首先,我们来创建一个Dog对象:

那刚刚大家注意到,现在Dog子类里没写任何东西,那我们发现,此时,我们是可以调用dog的属性和方法的,显然这个属性是从父类继承来的,这样,子类就不用自己再写代码了。

那我们要注意一个问题,如果父类的属性是用我们的private修饰符修饰的,那么,private修饰的我们是不能继承的。你会发现,如你调用了一个private的age属性,我们是无法使用的。

思考:

在生活当中还有那些对象是继承关系,试用Java来描述。

 

3 - 2:Java中的方法重写

我们在使用继承的时候,经常还有一种情况, 就是子类虽然可以继承父类的方法,但对父类的方法不满意,我们想写一个子类自己有的一个方法,同时这个名跟父类方法名相同,此时我们就叫方法的重写。

1、什么是方法的重写

如果子类对继承父类的方法不满意,是可以重写父类继承方法的,当调用方法时会优先调用子类的方法。我们要注意,方法在重写的时候,要注意语法规则。

2、语法规则

返回值类型、方法名、参数类型及个数都要与父类继承方法相同,这才叫方法的重写。

我们可以通过Eclipse来看一下。

比如说这里,我们可以从父类继承一个eat方法,但是eat方法里仅仅是可以描述动物是可以吃东西的,而我们现在明明是创建了Dog类,我能不能突出Dog类这个特点呢?所以说,此时我对父类这个eat方法就不满意了。我想重写一个属于子类Dog的方法,那么我们就可以在Dog类写一个eat方法(注意语法规则),像下面这样:

但是,main函数里没有做任何改变,但是输出时把动物改成了狗:

思考

对于交通工具,具体其车辆有座位数,并提供一个print方法的能力可以输出具体交通工具的坐位数是否也可以重写呢?

 

3 - 3:练习题

Java 中实现继承的关键字是( )

A、extends

B、has

C、import

D、base

 

答案:A。解析:Java 中通过 extends 实现继承关系

 

3 - 4:Java中的继承初始化顺序

在前面的课程里面,我们已经详细学习了继承是什么。现在来看一下,当我们使用教程特性的时候,程序是如何执行的呢?也就是说,我们要关注一下,继承的初始化顺序:1、初始化父类再初始化子类,2、先执行初始化对象中属性,再执行构造方法中的初始化。

切换到我们的代码编辑模式下,按照我们刚才所说的,初始化其实就是相当于执行我们类的构造方法。所以说,我只需要在类的构造方法里面输出一句话,看看它到底是什么时候输出的,就知道它们的执行顺序了。

我在Animal类的构造方法输出Animal类执行了,在Dog类构造方法输出Dog类执行了,在主函数里,我只是创建了子类对象,这样我们来看一下,它的执行顺序是什么。下面的图大家点开来看。

显然大家发现,我仅仅是创建了子类对象,但是,它是先执行了父类的构造方法,然后又执行了子类的构造方法。这样的话,我们就可以证明,当创建对象的时候,它会优先创建我们的父类对象,然后才会创建我们的子类对象。

在创建对象的时候我们发现构造方法有这样的执行顺序,那么对象当中有属性,属性和我们的构造方法在初始化的时候哪一个先执行呢?

那我们可以做一个简单的例子,如果我在创建我们这个父类的时候给我们的属性赋一个初值,然后当我们在执行构造方法的时候再给这个属性赋一个值(不同于初值),拿么我们想想,如果我们在程序中输出这个属性的值,那么这个值是谁的,它其实是后执行的,因为后面的值会把前面的值覆盖掉。例如说,如果我们的最终输出age的值是10,那么显然,我们这个属性的初始化是后做的,而我们的构造方法里面的初始化是先做的,如果我们输出的值是20,那么显然我们属性的初始化是先做的,构造方法里的初始化是后做的,后面这个20会把前面这个10覆盖掉。

好,我们测试一下,我们先创建一下父类对象animai,然后直接输出一下age,看看属性值是多少:

是20,证明先执行的属性初始化,再执行的构造方法初始化。从这个角度来讲,属性的初始化和构造方法里的初始化属性的初始化是先执行的。

创建顺序:父类对象→父类属性初始化→父类构造方法→子类对象→子类属性初始化→子类构造方法。

 

3 - 5:Java中的final的使用

我们在写继承代码的时候,经常还会用到final关键字。

那什么是final关键字呢——final关键字从字面上理解就是“最终的”的含义,就是说,不可修改,不可变化。

final可以修饰类、方法、属性、变量。

final关键字修饰类,则该类不允许被继承。那此时,这个类就成了最终的类了。

final关键字修饰方法,则该方法不允许被覆盖(重写)。

final关键字可以修饰属性,则该类的属性不会进行隐式的初始化(类的初始化属性必须有值),或在构造方法中赋值。

final关键字修饰变量,则该变量的值只能赋值一次,即变为常量。

我们在代码中,如何使用呢:

首先我们在声明类的前面加一个final关键字:

我们会发现,这个类就不允许被继承,Dog类前面就会有错。提示:我们Dog不能继承父类Animal,因为Animal使用了关键字final来修饰。

我们刚才又说过,final关键字又可以修饰方法,我们在Animal类里的eat方法前面加个final,去掉类前面的final。如果final关键字修饰了方法,则子类不允许覆盖父类的方法。

我们还说过,final关键字可以修饰属性。我们给age前面加一个final,则这个属性不能在其他位置进行改值(在构造方法中也不能改)。不过要记得,要给它一个值才行!如果我们不初始化,我们必须在构造方法中初始化才行。

 

 

3 - 6:练习题

如果用 final 修饰一个类的话,代表此类

A、不可被继承

B、是静态类

C、不能被实例化

D、不能继承其他类

 

答案:A。解析:final 修饰的类不可被继承

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值