Java 浅析三大特性之一继承
上文Java 浅析三大特性之一封装我们说到Java是一个注重编写类,注重于代码和功能复用的语言。Java实现代码复用的方式有很多,这里介绍一个重要的复用方式——继承。
在介绍继承之前,我们要明确一点,继承是一个比较复杂的编写类的方式,他会破坏掉父类的封装,因此只有我们确定需要用到继承的时候,我们才会用继承。
继承的概念
继承是一种构建新类的方式,他是基于已有的类的定义为基础,构建新的类,已有的类称为父类,新构建的类称为子类,子类能调用父类的非private修饰的成员,同时还可以自己添加一些新的成员,扩充父类,甚至重写父类已有的方法,更其表现符合子类的特征。让子类的表现更独特,更专业。
继承的写法
Java规定,一个类后面紧跟 extends
关键字,再加一个类的名字,则表示新建的类继承自extends
后面的那个类。在我们上面这个文章最后,我们列举了一个类,代码如下:
public class Student {
private String name;
private String age;
private String handleName(String name){
return "I'm " + name;
}
private String handleAge(String age) {
return age + " 岁";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = handleName(name);
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = handleAge(age);
}
}
现在我们新建一个类去继承自他,这个类我们就叫Boys,其代码如下:
public class Boys extends Student {
@Override
public void setName(String name) {
super.setName(name);
}
@Override
public String getAge() {
return super.getAge();
}
@Override
public String getName() {
return super.getName();
}
@Override
public void setAge(String age) {
super.setAge(age);
}
}
在上面代码中,我们可以看到很多相似的方法,这些方法的方法签名,参数,返回类型都是与父类的方法是一致,Java允许我们定义和父类一致的方法,以便我们在这个方法中写入新的代码。上面方法中,我们会看见一个新的关键字super
,这个关键字与this相似,不过super表明调用方法的对象是父类的对象,那这段自动生成的代码的意思就是如果我们不添加新的内容,那么当我们子类调用这些方法的时候,执行的是父类的方法。同时我们在这个方法上面看见一个注解 @Override
这表明这个方法是覆盖父类的方法,而不是方法重载,下面我具体说一下什么是方法重载,以及这个注解存在的必要。
方法重载
方法重载是很有必要的一种方式,他其实体现的是一种多态。即我定义了一种方法,这个方法可以承接很多类型的参数,而不要针对每个参数定义不同的方法。其实构造器就是方法重载的一个典型应用,也因为构造器必须要根据不同的参数,构造不同的对象,所以必须要实现方法重载。
下面这个例子,我们看一下什么是重载
public class OverLoading {
public void print(String args1) {
System.out.println(args1);
}
public void print(String args1, String args2) {
System.out.println(args1 + args2);
}
public void print(int args1) {
System.out.println(args1);
}
public String print(double args1) {
System.out.println(args1);
return null;
}
//这不是方法重载,这是错误的语句
// public String print(String args1) {
// System.out.println(args1);
// return null;
// }
public static void main(String[] args) {
OverLoading ol = new OverLoading();
ol.print(1.0);
ol.print(1);
ol.print("1");
ol.print("1", "1");
}
}
//输出结果
1.0
1
1
11
上面的代码当中,只有一个方法print,但这个方法却可以接受多种参数,甚至返回的类型也不一样,但是我们在测试时候发现,根据输入的不同,系统会自动执行不同的print。这就是方法的重载。注意上面我有一注释的语句,这个语句是错误的方法重载,所以我们要如何去区分方法的重载呢。
其实规则比较简单,每一个重载的方法必定有不同的参数列表。条件只有这一个。
第一个当中,参数列表是String args1
,第二个参数列表是String args1, String args2
,第三个参数列表是int args1
,第四个参数列表是double args1
。这四个,每一个参数的列表都是不一样的,所以他们是重载的方法,而第五个也就是说注释的语句显然参数列表是String args1
与第一个是重复的,所以他不是方法重载,系统会直接报错,告诉你这个方法已经被定义了。甚至更极端的情况,参数的顺序都不一样,也算是方法重载,但在这个例子里,是不存在顺序不一样的,但下面这段代码算方法重载
public String print(int args1, String args2) {
return null;
}
public String print(String agrs2, int args1) {
return null;
}
这个看起来好像和继承没什么关系的知识点,但却并不是这样。因为子类会继承父类的非private方法,所以子类也会重载父类的方法。如果子类定义了一个方法签名和父类一致的方法,但参数列表不一样,这就算重载了父类的方法。但我们有时并不是要这样,我们更多的是希望子类定义一个和父类一样的方法签名和参数列表,而里面实现的功能不一样。这样的操作叫覆写。但有时会书写失误,所以我们会在覆写方法上加入@Override
,这样一旦我们写成了方法重载而非覆写就是报错。
继承的一些特点
在写完继承的写法之后,我们可以看出来一下继承的特点,第一,继承是有一个特殊的关键字super
,第二,维持继承关系,我们可以用一个特殊的关键字protected
这个上篇文章是讲过的,第三,很有意思的一点,子类其实可以看成一个特殊的父类,是父类的一种类型。下面我们具体的说一下每一点。
super关键字
super之前也提到过,是区别于this一种关键字,他一般表示的是调用方法的对象是父类的对象。那么我们就可以利用它去调用父类的方法,父类的非private的成员变量。当然他和this一样,也有一种特殊的应用,即用它去调用父类的构造器。一般情况在调用子类的构造器之前,会默认先调用父类的默认构造器,如果父类没有默认的构造器,那么我们在子类的构造器中就要明确用super去调用父类的构造器,否则会报错。例子如下:
public class Father {
public Father(int a){
System.out.println("这是父类的构造器");
}
}
public class Son extends Father{
public Son(){
super(1);
}
}
这里一定要显式的调用父类的构造器,否则编译器无法完成父类对象的构造。关于构造器的顺序,初始化过程等等我们以后再详细讨论。protected
关键字我们在上篇文章中已经讲过,这里就不说了,我们主要说第三点,向上转型。
向上转型
我们使用继承,主要是因为父类和子类之间存在一个种所属关系,子类确实是父类的一种。比如我们可以把动物当做是父类,子类是猫,狗啊等等。猫,狗确实是动物的一种。动物所拥有的方法,猫,狗都有,所以猫,狗是一种类型的动物,既然如此,我们就可以把猫,狗向上转型成动物类型。这是安全且一定成功的。我们可以看下面的例子。
public class Animal {
public void run(Animal animal) {
System.out.println("动物在奔跑");
}
}
public class Dog extends Animal{
public static void main(String[] args) {
Animal animal = new Animal();
animal.run(new Dog());
}
}
这里Animal类的run方法明确规定传入的参数是Animal类型,但我们传入Dog类型也是可以成功的。这种就是向上转型的一种应用。这种转型总是成功的原因,就是上面所说,Dog其实是比Animal更专业,更独特的类型,可以看做是一个专业的类型向通用的类型转换,由一个更大的类向更小的类转换,这种转换除了会丢失一些方法和属性以外,总会是成功的。关于向上转型还有很多要讲的内容,不过这都要和多态联系到一起,我们以后再说。
总结
继承提供了我们复用类和代码的一种方式,但他并不是唯一和最好的一种,当我们明确需要这种继承的关系去编写类的时候,或者我们需要用到向上转型的时候,我们才会用继承。如果不需要的话,我们可以考虑是不是还有其他的方法。
Java 浅析三大特性之一继承的更多相关文章
- 【转】java提高篇(二)-----理解java的三大特性之继承
[转]java提高篇(二)-----理解java的三大特性之继承 原文地址:http://www.cnblogs.com/chenssy/p/3354884.html 在<Think in ja ...
- java提高篇(二)-----理解java的三大特性之继承
在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...
- java提高篇(二)-----理解java的三大特性之继承
在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...
- (转)java提高篇(二)-----理解java的三大特性之继承
在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...
- java基础(二)-----java的三大特性之继承
在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...
- Java的三大特性之继承
此处我会分为这几个部分来理解继承是怎么样的: 1.区分封装.继承和多态 2.区分限定词的范围 3.区分隐藏.覆盖.重载 4.继承的理解 5.一道面试题的原型 --------------------- ...
- Java 浅析三大特性之一封装
在说Java 三个特性之前,我们先了解一下什么是面向对象,以及为什么Java是面向对象的语言. 面向对象是区别于面向过程的一种编程的思想.我们可以通过这个例子冰箱装大象的例子来了解一下面向对象与面向过 ...
- Java 浅析三大特性之一多态
Java 浅析三大特性之一多态 之前我们的文章讲了Java的封装和继承,封装讲的时候,并没有体现出来封装的强大之处,反而还要慎用封装.因为这时的封装还没有和多态联系到一起,还无法看出向上转型的厉害之处 ...
- java面向对象三大特性之继承
通过重用已经测试并验证通过的代码,怎样才减少开发工作,所有开发团队都在为一问题而努力.一个久经考验的方法是通过有效地使用Java继承优化应用程序开发. 继承的从某种意义上讲,继承的短暂美就如同宇宙中所 ...
随机推荐
- 关于在django框架里取已登录用户名字的问题
在 views里取值是这样的 request.user.username而在模板页面取值是这样的:{{request.user}} 判断是否通过验证是这样的 {% if request.user.is ...
- 【Hawk】高级教程——post参数采集万方医学网论文
目标——万方医学网论文列表 http://med.wanfangdata.com.cn/Author/General/A000000001 和普通网页不一样的地方在于点击下一页的时候,URL没有发生变 ...
- 2016 ACM/ICPC Asia Regional Dalian Online 1008 Function 二分+RMQ
Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submissio ...
- asp.net mvc自定义JsonResult类来防止MaxJsonLength超过限制
前不久在做一个项目的时候,我用到了mvc的webapi返回了一个大数据,结果报了500错误,如下图所示: Server Error in ‘/’ Application. Error during s ...
- 【Linux】Linux统计文件夹、文件数量的命令
# 查看当前目录下的文件数量(不包含子目录中的文件) ls -l|grep "^-"| wc -l # 查看当前目录下的文件数量(包含子目录中的文件) 注意:R,代表子目录 ls ...
- 【虚拟机】oracle Virtual Box4.2.6虚拟机正在运行的过程中删除了其上的一个备份,之后虚拟机就无法使用了
原因未知,解决方法没有,网上也没有找到相关的解决方法.偶然的操作导致
- CentOS6.5的vsftp搭建流程(一)
前几次搭建FTP都失败了,不是登陆不了,就是目录没有权限.现在终于摸索出了靠谱的操作流程,分享之~ 1. 查看是否安装了vsftpd,未安装则安装 [root@iZ283tian2dZ /]# rpm ...
- 总结30个CSS3选择器(转载)
或许大家平时总是在用的选择器都是:#id .class 以及标签选择器.可是这些还远远不够,为了在开发中更加得心应手,本文总结了30个CSS3选择器,希望对大家有所帮助. 1 *:通用选择器 * ...
- 栈的JS实现
栈,是一种特殊的线性表,其插入及删除的操作都在线性表的同一端进行.这一端称为栈顶,另一端称为栈底.就类似于餐厅里的一摞盘子,后放的盘子在上方,也会先被人拿走.栈具有"后进先出"的逻 ...
- css 简析folat
1.float?? 不知道大家是否还记得之前我们讲过页面是文档流,具体什么是文档流,我就不说了?于是我们页面布局如果用div的话,那么块状的元素是怎么排列的,什么叫块状自己去看? 如果我们呢用div布 ...