Javase杂谈(十)
一、继承
这一节我们学习面向对象的第二个特征——继承。
那么什么是继承呢?继承有作用是什么?
我们先通过一个例子来说明:
class Student//学生类
{String name;//姓名int age;//年龄void printInfo()//打印信息{System.out.println("姓名:"+name+"\t年龄:"+age);}void study()//学生在学习{System.out.println(name+"正在学习。");}
}class Worker//工人类
{String name;//姓名int age;//年龄void printInfo()//打印信息{System.out.println("姓名:"+name+"\t年龄:"+age);}void work()//工作在工作{System.out.println(name+"正在工作。");}
}class ExtendTest
{public static void main(String[] args) {Student student = new Student();student.name = "小强";student.age = 15;student.printInfo();student.study();Worker worker = new Worker();worker.name = "光头强";worker.age = 28;worker.printInfo();worker.work();}
}
我们看结果:
这里我们定义了两个类,一个是学生类,一个是工人类,但是我们会发现,上面的代码重复的内容太多了,与我们要实现的代码复用相悖,那么我们可以看到,对于学生和工作,它们有的共同之处就是它们都是一个人,有人的所有特征,那么我们在这里就可以重新定义一个Person类,如下:
class Person
{String name;int age;void printInfo(){System.out.println("姓名:"+name+"\t年龄:"+age);}
}
在Person类中,我们封装了人的共性特征,姓名和年龄,以及一个打印信息的方法。
那么我们该怎么做呢?当然就是要建立Student类和Worker类与Person类之间的关系了,这就是我们这一节要说的继承,让Student类和Worker类都继承于Person类,就可以直接继承这些共有成员了。
我们可以extends关键字来实现继承:
class Student extends Person//学生类
{void study()//学生在学习{System.out.println(name+"正在学习。");}
}class Worker extends Person//工人类
{void work()//工作在工作{System.out.println(name+"正在工作。");}
}
结果:
这时我们会发现,运行结果正常,也是我们所要看到的,但是比较之前的代码,我们真正意义上提高了代码的复用性。
由此我们也可以总结出继承的优点:
1.提高了代码的复用性。
2.让类与类之间产生的关系,为面向对象的第三个特征“多态”提供了前提。
二、单继承与多重继承
这一节我们来看java中的单继承和多重继承。
在java语言中,支持的是单继承,不直接支持多继承,但是对C++中的多继承进行了改良。
那么什么是单继承和多继承呢?
单继承:一个子类只能有一个直接父类。
多继承:一个子类可以有多个直接父类。这个在java中是不允许的。
为什么不允许呢?我们看一个例子:
class A
{void method(){System.out.println("a");}
}
class B
{void method(){System.out.println("b");}
}
class C extends A,B
{
}
对于上面的情况,如果当我们调用C对象的method方法时,就会出现不确定性错误了,java也是以这个问题进行改良,从而不直接支持多继承。
所以我们可以看到,java中不直接支持多继承的原因就是:当多个类中有相同成员时会产生调用的不确定性。
java语言中还支持多重继承。
比如下面的例子就是一个多重继承:
class A
{
}
class B extends A
{
}
class C extends B
{
}
这就是多重继承的形式,对于上面的继承,就出现了继承体系,而在这个继承体系中,A是最顶层类,C是对子类。
通过上面的继承体系我们不难看出,A实现的是最基本最基础的功能。
那么我们在实际开发中应该如何使用这个继承体系呢?
第一步:查看该体系中的顶层类(这里是A),了解该体系的基本功能。
第二步:创建体系中的最子类对象(这里是C),完成功能的使用。
通过上面的两步,我们就可以按需使用一个继承体系了。
这两节我们一直在说继承,在9.1中我们也说到继承可以提高代码的复用性,但是我们一定要注意:千万不要为了提高代码复用性去定义继承。
这是为什么呢?我们看下面例子:
class A
{void method1(){}void method2(){}
}
class B
{void method1(){}void method3(){}
}
我们发现两个类中都有method1方法,那么我们为了提高复用性而去继承:
class A
{void method1(){}void method2(){}
}
class B extends A
{void method3(){}
}
B类中确实有了method1方法,可以也同时继承了method2方法,但method2方法其实并不是B中的方法,这就出现了问题。
这就让我们必须明确什么时候定义继承:当类与类之间存着所属关系时,就定义继承。
那么什么是所属关系呢?比如X是Y中的一种,就是说X属于Y,就是一种所属关系。
我们这样表示所属关系:is a 关系,就是所属关系。
所以当我们发现两个类是一种is a 关系时,我们就可以定义继承。
三、 子父类中成员变量特征体现
这一节我们来说一说继承中子父类中的成员变量有什么特征。
我们先看从一个例子说起:
class Father//父类
{int age1 = 48;
}
class Son extends Father//子类
{int age2 = 22;public void printInfo(){System.out.println("父亲的年龄:"+age1+"\n儿子的年龄:"+age2);}
}
class ExtendTest2
{public static void main(String[] args) {Son son = new Son();son.printInfo();}
}
我们上面的例子中有一个儿子类继承了一个父亲类,我们看到子类中访问了父类的年龄这个成员变量,那么我们看下结果:
这时输出了正确的结果。
但是我们会发现这两个成员变量的名称是不一样的,那么我们来看一种特殊情况,当两个成员变量名一样时,会是什么样子呢?
class Father//父类
{int age = 48;
}
class Son extends Father//子类
{int age = 22;public void printInfo(){System.out.println("父亲的年龄:"+age+"\n儿子的年龄:"+age);}
}
此时我们再看结果:
我们发现父亲和儿子的年龄都是儿子的年龄,这就出现了问题,当子父类中的成员变量名相同时,我们发现会直接使用子类中的成员变量。
那么怎么解决这个问题呢?
我们很自然想起前面学习时当一个类中成员变量和局部变量同名时,我们使用了this关键字进行了区分,那么这里有没有一个标记让我们区分子父类中的同名成员变量呢?
答案当然是肯定的,这个关键字就是super关键字。
我们来看例子:
class Father//父类
{int age = 48;
}
class Son extends Father//子类
{int age = 22;public void printInfo(){System.out.println("父亲的年龄:"+super.age+"\n儿子的年龄:"+this.age);}
}
这时我们再看一下运行结果:
很显然,结果就是我们想要的。所以我们看到一个新关键字super,当子父类中的成员变量同名时,我们用super关键字来区分。
同时,我们会发现,this关键字和super关键字的用法很相似,不过我们一定要明确的是,它们只是相似,而不是相同哦!
为什么这么说呢?我们来说一下两个关键字的不同之处:
this关键字:代表一个本类对象的引用,这我们之前就已经学习了。
super关键字:并不代表父类对象,而代表一个父类的空间。因为我们这里根本就没创建父类的对象,只有子类的对象。
下面我们再来看一个比较容易产生疑问的地方,就是父类中的私有成员,子类具有访问权限吗?
我们直接看例子:
class Father//父类
{private int age = 48;
}
class Son extends Father//子类
{int age = 22;public void printInfo(){System.out.println("父亲的年龄:"+super.age+"\n儿子的年龄:"+this.age);}
}
我们把父类中的成员变量私有化,然后看运行结果:
我们会发现在编译时就已经报了错,很明显我们在子类中是不能直接访问父类中的私有内容。
那么我们要怎么访问呢,我们可以用以下方法:
class Father//父类
{private int age = 48;public int getAge(){return this.age;}
}
class Son extends Father//子类
{int age = 22;public void printInfo(){System.out.println("父亲的年龄:"+super.getAge()+"\n儿子的年龄:"+this.age);}
}
结果:
我们可以通过上面的方法去访问一个类中的私有成员哦。
Javase杂谈(十)相关推荐
- 【JavaSE 第十六天】
[JavaSE 第十六天] 一.List 接口的实现类 ArrayList 1. ArrayList 集合的特点 ArrayList 类实现接口 List,ArrayList 具备了 List 接口的 ...
- JavaSE(二十)——面向对象的概念及三个基本特征
文章目录 1. 面向对象的概念 2. 面向对象的三个基本特征 2.1 封装 2.2 继承 2.3 多态 1. 面向对象的概念 面向对象是一种符合人类思维习惯的编程思想.现实生活中存在各种形态不同的事物 ...
- JavaSE(十)之反射
开始接触的时候可能大家都会很模糊到底什么是反射,大家都以为这个东西不重要,其实很重要的,几乎所有的框架都要用到反射,增加灵活度.到了后面几乎动不动就要用到反射. 首先我们先来认识一下对象 学生---- ...
- JavaSE(二十六)——多线程之模拟龟兔赛跑
文章目录 1. 案例说明 2. 代码实现及运行结果 1. 案例说明 (1)首先设定赛道距离,要离终点越来越近 (2)判断比赛是否结束 (3)打印出胜利者 (4)龟兔赛跑开始 (5)故事中是乌龟赢,兔子 ...
- JavaSE(二十五)——String与StringBuffer、StringBuilder的区别、创建对象的几种方法、Http和Https的区别
文章目录 1. String与StringBuffer.StringBuilder的区别 2. Java创建对象的几种方法 3. Http和Https的区别 1. String与StringBuffe ...
- JavaSE(二十四)——冒泡排序、选择排序、直接插入排序以及二分查找
文章目录 1. 冒泡排序 2. 选择排序 3. 直接插入排序 4. 二分查找 1. 冒泡排序 原理:数组元素两两比较,大的往后放,经过一轮比较后,最大元素在最后面,如此往复. 举例说明: 代码: // ...
- JavaSE(二十二)——TCP协议的三次握手
文章目录 1. TCP协议 2. TCP的三次握手 3. 为什么一定是三次握手? 1. TCP协议 TCP协议:传输控制协议,是可靠连接,类似于打电话,只有等待对方接通的时候才可以交流,也就是确认了对 ...
- JavaSE第十五天20160823
线程 一.JAVA中创建线程的两种方法: 1.继承java.lang.Thread类. 2.实现java.lang.Runnable接口. 3.在JAVA中Thre ...
- Javase杂谈(四)
这一节我们学习java语言中的函数概念和定义格式. 一.函数的定义 函数就是定义在类中的具有特定功能的一段独立小程序.我们可以看到,这里面比较需要注意的词语,一个就是具有特定功能,另一个就是独立. / ...
最新文章
- 【原创视频教程】学生信息管理系统6--学员信息管理(完结篇)
- oracle创建定时任务
- android Mp3播放器之音频文件扫描
- 数据输出:如何将数据带给页面||SpringMVC除过在方法上传入原生的request和session外还能怎么样把数据带给页面
- 重复制造和离散制造特点
- 简析.NET Core 以及与 .NET Framework的关系
- django开源电子文档管理系统_「开源推荐」BookStack v2.8 发布,简洁美观的在线文档管理系统
- python运行不了指令_python不是内部命令或外部命令,也不是可执行程序解决方法...
- POI处理超过65536条记录
- 搭建属于自己的私有链,部署简单的智能合约
- 工作5年后我才发现:90%的技术问题,可以解决
- 微服务架构-设计总结
- git 安装及常用命令
- c语言岩石1ms,2017年注册岩土工程师基础考试真题下午和答案解析
- python第一次考试_python 全栈开发,Day16(函数第一次考试)
- SAXReader 读文件读不出来
- 尤雨溪:Vue3.0 官宣彻底抛弃 IE 浏览器
- 什么是JWT及在JAVA中如何使用?
- 职场思维:你的屁股决定你的未来?一张图,点醒了大部分人!建议收藏
- 仿QQ聊天软件(JavaFX+云端数据库)