Java基础知识点4:继承
继承是面向对象编程技术中非常重要的一个基本概念。它背后的基本思想就是:通过已有的类来创建一个新的类,这个新的类可以重用(或继承)已有的类方法;新的类也可以加入新的方法和属性。
在这里我们通过一个实例来讲解继承的基本知识。假设我们在为一个公司设计一个管理系统,管理公司的人员,我们首先定义了一个雇员类Employee,它的定义如下:
1 public Employee {
2 private String name;
3 private double salary;
4
5 public Employee(String name, double salary) {
6 this.name = name;
7 this.salary = salary;
8 }
9
10 public String getName() {
11 return name;
12 }
13
14 public void setName(String name) {
15 this.name = name;
16 }
17
18 public double getSalary() {
19 return salary;
20 }
21
22 public void setSalary(double salary) {
23 this.salary = salary;
24 }
25
26 }
基本语法
基本定义
定义一个继承自已有类的子类所涉及到的关键字是extends,基本语法如下:
子类名 extends 超类名 {
子类定义的新的属性和方法:
}
也就是说,定义一个继承自超类的子类,只需要声明二者不同的地方就可以了。
比如现在我们想为公司的经理们设计一个类Manager,由于经理也是雇员,所以雇员的基本属性经理也都有。但是经理可能有一些其他雇员没有的属性和方法,比如经理会有分红bonus。所以采用继承的方式来定义Manager类是最合适不过的。
public Manager extends Employee {
private double bonus;
public Manager(String name, double salary, double bonus) {
super(name, salary);
this.bonus = bonus;
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
18 }
这样我们就成功的建立了一个继承自Employee的新类Manager,这个Manager不仅仅具有Employee类的属性和方法,而且还包含自己独有的属性和方法。
关于子类这里有几点需要注意
1. 子类能够直接调用超类的public,protected方法。之所以使用protected,这样可以保证这个方法是可以被该超类的子类所应用的。但是不能被其他的类所使用。
2. 子类不能够访问超类中的private属性,方法。
3. 子类只能够通过public的接口去访问超类中的private属性。
覆盖超类方法
在实际情况中还会出现这样的需求,有些方法在超类中定义了,而且子类也需要使用这个方法。但是,子类对于这个方法的定义与超类的定义不一样。以上面的Manager类为例,Manager需要使用getSalary方法获取它的工资,在超类中的定义就是返回私有域salary的值,但是在Manager中,我们需要返回salary和bonus域的和。这里应该怎么去实现?
这里就需要Manager类去覆写(override)这个getSalary方法:
public double getSalary() {
return salary + bonus;
}
public double getSalary() {
double baseSalary = getSalary();
return baseSalary + bonus;
}
public double getSalary() {
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
这里给出了三个版本,其中第一,二个都是错误的,只有第三个是对的。第一个错在不能直接访问超类中的private属性salary,必须调用超类的getSalary方法。第二个版本错在它调用的是子类的getSalary方法,不是超类的,所以这个方法会无限循环执行。只有第三个是正确的。
所以这里要记住:
在子类中可以定义一个声明完全和超类一样的方法,这个叫做方法的覆写,当子类再次调用这个方法时,那执行的就是子类中定义的版本。
另外,在子类中如果想要调用超类的方法,一定要在方法名字前加上super。
构造方法
子类的构造方法的写法也是需要注意的。由于子类是无法直接访问超类中的private的数据域的,所以对于这些域,如果你想通过构造方法来为它们设定初值时,你就需要首先调用超类中的带参数构造方法,然后再为子类中特殊的域设置初值。
比如我们写下Manager类的构造方法:
public Manager(String name, double salary, double bonus) {
super(name, salary);
this.bonus = bonus;
}
其中第一句super就是调用超类中的带参数构造方法。这里要注意,这句super语句如果想这么使用,一定要把它放在第一句的位置。
这里还有一点要注意:
如果子类中没有显示的调用超类的构造方法,那么其实子类就会触发超类的无参数构造方法。如果超类中并不含有一个无参构造方法的话,那么子类还不显示的调用超类其他构造方法,那么java编译器就会报错。
当前例子中Employee没有无参构造器,因为它已经有含参的了,所以如果在Manager中没有调用super方法,那么就会报错。所以这里的解决方案就是在Employee中再定义一个无参构造器。
多态性
子类的对象可以被超类变量所引用,比如我们声明一个Employee引用,它引用的是一个子类对象:
Employee boss = new Manager("Steve", 10000, 5000);
System.out.println(boss.getSalary());
但是这里要注意:采用超类变量引用是无法调用子类中的独有方法的,比如上面的例子中boss变量不能调用setBonus方法。
然后我们再分析上例中第二句:
如果超类变量调用了被子类所覆写的超类方法,则此时要执行的是子类中定义的版本!
所以此时打印出来的是15000。说明即便Manager对象boss被Employee类变量所引用,但是JDK可以识别这个对象到底属于哪一类。所以才会输出正确的结果。
之所以能实现这一点就是归功于jdk的动态绑定技术。
动态绑定技术是在java程序,对象的某个方法被调用时发生的技术。当某个对象引用调用这个对象的某个方法时,将会发生以下几步:
1. 根据声明的方法名,遍历所有可能被调用的函数。
2. 再根据输入参数的类型,确定最可能匹配的函数。如果没有或者是有多个,java都会报错。
3. 如果方法是private,static,final或构造器时,那么被调用的方法直接执行,这个叫做静态绑定。否则的话,java会按照对象到底是属于什么类型来调用正确的方法。
那么如果想让Employee类型的变量boss,调用setBonus方法怎么办?
方法就是强制类型转换,把Employee类型的变量boss强制转换为Manager类型,如下
Manager newBoss = (Manager) boss;
newBoss.setBonus(4000);
强制类型转换之前一般会做一次检查,检查一下要被转换的变量是否真的是要强制转换的类型,如果不是的话,会产生异常。检查的方法就是用instanceof方法:
if(boss instanceof Manager)
Manager newBoss = (Manager) boss;
final修饰符
如果不希望其他程序继承自自己的类,那么可以把这个类用final修饰符修饰,就可以防止其他类去继承它。
如果不希望子类覆写超类的方法,那么在超类中可以把这个方法用final修饰符修饰一下。
抽象类
有的时候可能出现这种情况,好几个类都继承自同一个类,他们还有一个共同的方法,但是每一个类实现这个方法的方式都不一样。当这种问题发生时,你把这个方法的声明写在超类中还是子类中都是有不好的地方。所以这个时候就需要抽象类,抽象方法出场了。
针对这种每个子类都有,但是却都实现方式不同的公有方法,我们可以把它在超类中声明成抽象方法即可。基本语法就是在这个方法的返回类型前面加上abstract修饰符。
public abstract 返回类型 方法名(输入参数表)
如果一个类中包含至少一个抽象方法的话,这个类也必须被声明为抽象类
public abstract 类名 { ... }
当然抽象类中不必所有方法都是抽象的,也可以有已经实现的。
抽象类不能被实例化,一个类即便没有抽象方法也可以被声明为抽象的。当然抽象类的变量还是可以指向其非抽象的子类的。
Java基础知识点4:继承的更多相关文章
- Java基础知识点(三)
前言:准备将Java基础知识点总结成一个系列,用于平常复习并加深理解.每篇尽量做到短小精悍,便于阅读. 1.Math类中相关函数 Math.floor(x):返回不大于x的最大整数.eg:Math.f ...
- Java基础知识点(二)
前言:Java的基础知识点不能间断. 1.Array和ArrayList的区别 关于Array的用法,参看:http://blog.csdn.net/b_11111/article/details/5 ...
- Java基础知识点(一)
前言:本篇随笔,主要记录Java的基础知识点,不管是用于项目或者面试中,笔者认为都非常有用,所以将持续更新...... 1.Java的访问权限 Java中有四种访问权限:默认访问权限.public.p ...
- Java基础知识点总结
前言 本文主要是我之前复习Java基础原理过程中写的Java基础知识点总结.Java的知识点其实非常多,并且有些知识点比较难以理解,有时候我们自以为理解了某些内容,其实可能只是停留在表面上,没有理解其 ...
- JAVA基础知识点总结(全集)
1.JAVA简介 1.1java体系结构:j2se,javaweb,j2ee 1.2java特点:平台无关(虚拟机),垃圾回收(使得java更加稳定) 1.3 JDK与JRE,JDK:java开发环境 ...
- Java基础知识点(四)
前言:记录Java基础知识点,方便熟悉与掌握. 1.面向对象的"六原则一法则" “六原则一法则”:单一职责原则.开闭原则.依赖倒转原则.里氏替换原则.接口隔离原则.合成聚合复用原则 ...
- java基础知识点补充---二维数组
#java基础知识点补充---二维数组 首先定义一个二维数组 int[][] ns={ {1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13,14,15,16} }; 实现遍 ...
- Java 基础知识点
很多 Java 基础的东西都忘记了, 有必要再复习一些基本的知识点. 本文主要参考 https://github.com/Snailclimb/JavaGuide ================== ...
- Java基础知识点
以下10点为JAVA 基础知识,后面将足以总结和完善以备面试 数据类型 (包装类,字符串,数组) 异常处理 Java IO和NIO 数据结构 (集合和容器 ) 多线程(并发) 网络通信(协议) 面向对 ...
- Java基础笔记-抽象,继承,多态
抽象类: abstract修饰 抽象方法必须定义在抽象类中,抽象类不能创建对象. 在抽象方法中可以不定义抽象方法,作用是:让该类不能建立对象. 特点是: 1.定义在抽象类中 2.方法和类都用abstr ...
随机推荐
- Android中Service通信(二)——绑定Service进行通信
一.把输入文本的数据同步到服务的实例(如何执行服务的内部代码) 绑定服务比启动服务更加方便高效,绑定服务中的直接方法调用比Intent作为载体传输更为快捷得多. 1.activity_main.xml ...
- unixLike命令拾遗
针对在日常工作过程中,发现的学习的漏洞和忘记的知识,进行拾遗. 编辑命令 一.vim操作 1.进入编辑模式 在光标移到将要编辑处,点击i,进入编辑模式 2.退出编辑模式 按esc或者crtl+c退出编 ...
- Django Restful Framework (一): Serializer
Serializer 允许复杂数据(比如 querysets 和 model 实例)转换成python数据类型,然后可以更容易的转换成 json 或 xml 等.同时,Serializer也提供了反序 ...
- 复习(1)【Maven】
终于开始复习旧知识了,有输入必然要有输出.输入和输出之间的内化过程尤为重要,在复习的同时,真正把学到的东西积淀下来,加深理解. Maven项目概念与配置 Maven是一个项目管理和综合工具.Maven ...
- css_随笔
1 css 基础语法: 2 派生选择器 li strong { font-style: italic; font-weight: normal; } <p><strong>我是 ...
- oracle忘记密码
1.输入命令: sqlplus /nolog ,进入oracle控制台,并输入 conn /as sysdba;以DBA角色进入. 2.连接成功后,输入"select username fr ...
- 关于更新发布CSS和JS文件的缓存问题
现如今,浏览器大战下,各个浏览器也是拼了命的提高性能,升级JS解析引擎,更好的处理浏览器的页面缓存,让用户的浏览体验更快,占用更小的PC资源.那么,问题就出现在JS和CSS缓存,甚至页面缓存上.至于浏 ...
- android studio2.2 的Find Sample Code点击没有反应
1 . 出现的问题描述: 右键点击Find Sample Code后半天没有反应,然后提示 Samples are currently unavailable for :{**** ...
- $compile
<html ng-app="compile"> <head> <script src="http://apps.bdimg.com/libs ...
- 【原创】web端高德地图javascript API的调用
关于第三放地图的使用,腾讯.百度.高德 具体怎么选择看你自己怎么选择了. 高德地图开放平台:http://lbs.amap.com/ 本次使用的是高德的javascript API http://lb ...