【JAVA零基础入门系列】(已完结)导航目录

  继承是类的一个很重要的特性,什么?你连继承都不知道?你是想气死爸爸好继承爸爸的遗产吗?(滑稽)

  开个玩笑,这里的继承跟我们现实生活的中继承还是有很大区别的,一个类可以继承另一个类,继承的内容包括属性跟方法,被继承的类被称为父类或者基类,继承的类称为子类或者导出类,在子类中可以调用父类的方法和变量。在java中,只允许单继承,也就是说 一个类最多只能显示地继承于一个父类。但是一个类却可以被多个类继承,也就是说一个类可以拥有多个子类。这就相当于一个人不能有多个父亲一样(滑稽,老王表示不服)。

  话不多说,先看栗子:

public class Employee {
   private int age;// 年龄
private String name;//姓名
private double salary;//薪水
//构造函数
public Employee(String name,int age,double salary){
this.name = name;
this.age = age;
this.salary = salary;
}
  
public String getName() {
return name;
} public double getSalary() {
return salary;
} public int getAge() {
return age;
}
}

  我们定义了一个Employee类(雇员类),并定义了一些简单的成员变量以及方法,接下来定义一个Manager类(经理类)来继承这个类。

public class Manager extends Employee{
private double bonus;//奖金   //构造器
public Manager(String name, double salary){
super(name,salary);
bonus = 0;
}
  //设置奖金
public void setBonus(double bonus) {
this.bonus = bonus;
}
  //重载父类的getSalary方法
@Override
public double getSalary() {
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
}

  这里需要说明的是super跟this的使用,super是父类引用,可以用它来调用父类的方法和属性,可以把它看作是父类跟子类沟通的桥梁,而this则是自身引用,可以通过它来调用自身的属性和方法,在构造器中我们使用了 super(name,salary); 这样会调用父类的构造函数,

 

  为什么Manager可以继承Employee这个类呢?是因为它们之间存在is-a的关系,经理也是一个雇员,有很多跟雇员相同的属性如姓名,薪水,以及方法,如取姓名,取薪水,但是它也有自己独有的属性和方法,还可以重载父类的方法,如上面的getSalary。这里的Manager类对象,继承了父类Employee的方法,因此Manager对象可以直接使用getName()方法,重载了getSalary方法,因此调用Manager对象的该方法时,调用的是子类的getSalary方法,而不是父类,

  那到底可以继承父类的哪些信息呢?

  1.子类可以继承父类的成员变量

  当子类继承了某个类之后,便可以使用父类中的成员变量,但是并不是完全继承父类的所有成员变量。具体的原则如下:

  1)能够继承父类的public和protected成员变量;不能够继承父类的private成员变量;

  2)对于父类的包访问权限成员变量,如果子类和父类在同一个包下,则子类能够继承;否则,子类不能够继承;

  3)对于子类可以继承的父类成员变量,如果在子类中出现了同名称的成员变量,则会发生隐藏现象,即子类的成员变量会屏蔽掉父类的同名成员变量。如果要在子类中访问父类中同名成员变量,需要使用super关键字来进行引用。

  2.子类继承父类的方法

  同样地,子类也并不是完全继承父类的所有方法。

  1)能够继承父类的public和protected成员方法;不能够继承父类的private成员方法;

  2)对于父类的包访问权限成员方法,如果子类和父类在同一个包下,则子类能够继承;否则,子类不能够继承;

  3)对于子类可以继承的父类成员方法,如果在子类中出现了同名称的成员方法,则称为覆盖,即子类的成员方法会覆盖掉父类的同名成员方法。如果要在子类中访问父类中同名成员方法,需要使用super关键字来进行引用。

  这里说了很多次public,private和protected,关于访问权限好像没还有正式介绍,这里来顺便简单介绍一下吧:

  Java类具有三种访问控制符:private、protected和public,同时当不写这三个访问控制符时,表现为一种默认的访问控制状态。因此,一共具有四种访问控制级别。

  具体访问控制表现如下:

  private修饰的属性或方法为该类所特有,在任何其他类中都不能直接访问;

  default修饰的属性或方法具有包访问特性,同一个包中的其他类可以访问;

  protected修饰的属性或方法在同一个中的其他类可以访问,同时对于不在同一个包中的子类中也可以访问;

  public修饰的属性或方法外部类中都可以直接访问。

  为什么要引入访问权限这个概念呢?当然是为了更好的封装,就像制作一台机器一样,自然希望把所有的电线都藏在盒子里而不是大摇大摆的吊在外面被人吐槽,而且这样也更加安全,只给用户或用户程序员看那些想给他们看的内容就好了,其他的一律隐藏起来。

  子类Manager虽然没有继承父类Employee的name和salary属性,但不代表对这两个属性的操作没有意义,可以理解成一个子类对象中包含有一个父类对象,打个比方,就像是我们组装好几款不同的电脑,为了方便起见可以选用同一款主机箱,里面配置了相同的电源和风扇,而其它的配置每台电脑都可以不一样,甚至如果需要的话,某些电脑还可以更换一下风扇和电源,虽然最后性能可能相去甚远,但是从外表上看起来,它们都是差不多的。(当然,如果你非要改装的完全不一样也是可以的)这里的配置好风扇跟电源的主机箱就相当于我们的父类,而不同的电脑就相当于子类,子类可以调用父类的公开方法,如转动风扇,但不能直接改变主机箱的颜色,因为父类并没有提供这样的权限。但这不代表主机箱的颜色对于子类没有用,它仍属于子类的一部分,只是不能直接操作它罢了。

  访问权限的内容就介绍到这里了,现在回归到我们的继承上来,下面是使用Manager类的一个栗子:

public class ManagerTest {
public static void main(String[] args){
Manager boss = new Manager("Frank",100000);//定义一个Manager变量
boss.setBonus(10000);//设置奖金 Employee[] staff = new Employee[3];//创建一个Employee数组
     
     //给数组赋值
staff[0] = boss;
staff[1] = new Employee("Alan",8000);
staff[2] = new Employee("Tom",9000);
     //遍历输出数组元素
for (Employee e:staff)
System.out.println("name:"+e.getName()+" salary:"+e.getSalary());
}
}

  这里我们定义了一个Employee数组,然后把一个Manager变量赋值给了Employee数组的第一个元素,看到这里,你也许会感到疑惑,不是说只能在相同类型的变量之间使用赋值操作吗?确实如此,但是因为Manager类是Employee的子类,一个Manager对象同时具有Employee的所有属性跟方法,也就是说Employee能做的事情,它也同样能做,所以,把Manager类的变量赋值给Employee变量是没有问题的,但反之则不行,因为Manager类有它自己的方法setBonus(),Employee是无法实现。在遍历输出的时候,我们把所有元素都当成Employee对象来使用,输出如下:

name:Frank salary:110000.0
name:Alan salary:8000.0
name:Tom salary:9000.0

  我们boss变量,在调用getSalary方法的时候,显然是调用了子类的方法,将基本薪水加上了奖金之后才进行返回。

  那说了这么多,为什么非要使用继承呢?

  原因很简单,一个是可以实现代码的复用,像这个例子一样,Employee的getName方法被子类Manager复用了,Manager中可以直接使用这个方法,这样可以省去很多代码。

  其次是可以实现多态,说出来你可能不信,我们刚才的栗子已经使用到了一个很伟大的概念——多态,在遍历输出的时候,一个父类对象的引用指向了子类对象,并调用了子类方法。

  那么这样做的好处是什么呢?多态的意义何在?

  简单,方便,继续用我们刚才的栗子,假如我们现在有一个人事管理类,PersonnelManagement,需要对员工的信息进行录入,有一个record方法,我们如果使用了多态的特性,只需要给record方法传入一个Employee对象即可,不管是经理还是普通雇员都能使用相同的方式进行处理,否则我们需要为经理跟雇员分别设计一个方法,这样也许觉得没事,但如果现在又多了很多其它岗位,如总经理,副经理,经理助手,人事部经理,采购部经理,这时候你还能为每个岗位设计一个方法吗?显然不现实,而且这样就失去了可扩展性跟灵活性,把一门艺术活变成了体力活,这样会让你丧失对编程的乐趣。

  所以,继承跟多态其实也很简单,继承就是使用extends来继承父类的属性跟方法,多态则是可以在合适的时候将子类对象视为父类对象进行统一处理,从而实现和增加代码的复用度,让你的代码越来越风骚。

  至此类的继承与多态就讲解完毕了,欢迎大家继续关注!喜欢我的教程的话记得动动小手点下推荐,也欢迎关注我的博客。

【JAVA零基础入门系列】Day13 Java类的继承与多态的更多相关文章

  1. 【JAVA零基础入门系列】Day11 Java中的类和对象

    今天要说的是Java中两个非常重要的概念--类和对象. 什么是类,什么又是对象呢?类是对特定集合的概括描述,比如,人,这个类,外观特征上,有名字,有年龄,能说话,能吃饭等等,这是我们作为人类的相同特征 ...

  2. 【JAVA零基础入门系列】Day12 Java类的简单应用

    俗话说的好,实践出真知,所以除了理论知识掌握扎实以外,更重要的是要多加操练,这样才能掌握核心科技. 今天我们就用刚学会的类来实践一下,目标便是完成上一篇中的剁手任务. 我们的商品类已经准备好了,代码重 ...

  3. 【JAVA零基础入门系列】Day2 Java集成开发环境IDEA

    开发环境搭建好之后,还需要一个集成开发环境也就是IDE来进行编程.这里推荐的IDE是IDEA,那个老掉牙的Eclipse还是先放一边吧,(手动滑稽). IDEA的下载地址:http://www.jet ...

  4. 【JAVA零基础入门系列】Day4 变量与常量

    这一篇主要讲解Java中的变量,什么是变量,变量的作用以及如何声明,使用变量. 那么什么是变量?对于初学者而言,可以将变量理解为盒子,这些盒子可以用来存放数据,不同类型的数据需要放在对应类型的盒子里. ...

  5. 【JAVA零基础入门系列】Day5 Java中的运算符

    运算符,顾名思义就是用于运算的符号,比如最简单的+-*/,这些运算符可以用来进行数学运算,举个最简单的栗子: 已知长方形的长为3cm,高为4cm,求长方形的面积. 好,我们先新建一个项目,命名为Rec ...

  6. 【JAVA零基础入门系列】Day6 Java字符串

    字符串,是我们最常用的类型,每个用双引号来表示的串都是一个字符串.Java中的字符串是一个预定义的类,跟C++ 一样叫String,而不是Char数组.至于什么叫做类,暂时不做过多介绍,在之后的篇章中 ...

  7. 【JAVA零基础入门系列】Day8 Java的控制流程

    什么是控制流程?简单来说就是控制程序运行逻辑的,因为程序一般而言不会直接一步运行到底,而是需要加上一些判断,一些循环等等.举个栗子,就好比你准备出门买个苹果,把这个过程当成程序的话,可能需要先判断一下 ...

  8. 【JAVA零基础入门系列】Day9 Java中的那个大数值

    什么是大数值?用脚趾头想也知道,当然是"大"的数值(233).Java中有两个用于表示大数值的类,BigInteger和BigDecimal,那到底能表示多大的数值呢?理论上,可以 ...

  9. 【JAVA零基础入门系列】Day10 Java中的数组

    什么是数组?顾名思义,就是数据的组合,把一些相同类型的数放到一组里去. 那为什么要用数组呢?比如需要统计全班同学的成绩的时候,如果给班上50个同学的成绩信息都命名一个变量进行存储,显然不方便,而且在做 ...

随机推荐

  1. EGit使用教程:第一篇 添加工程到版本控制

    配置 确定身份 当每次提交的时候,Git需要跟踪这次提交,确认是哪个用户提交的.用户由 user.name 和 user.email 组成,这个信息包含在 ~/.gitconfig 文件中. ~ 代表 ...

  2. Ubuntu16.04.1上搭建分布式的Redis集群

    为什么要集群: 通常为了,提高网站的响应速度,总是把一些经常用到的数据放到内存中,而不是放到数据库中,Redis是一个很好的Cache工具,当然了还有Memcached,这里只讲Redis.在我们的电 ...

  3. 使用jsonp来实现跨域请求

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  4. angularjs——路由篇

    路由 路由功能是由 routeProvider服务 和 ng-view 搭配实现,ng-view相当于提供了页面模板的挂载点,当切换URL进行跳转时,不同的页面模板会放在ng-view所在的位置; 然 ...

  5. 调试 ASP.NET Core 2.0 源代码

    在Visual Studio 2017中可以通过符号以及源链接,非常方便对 ASP.NET Core 2.0中源代码进行调试.在这篇文章中,我们将重点介绍如何使用源链接对ASP.NET Core源进行 ...

  6. Spring Framework 5.0 新特性

    Spring Framework 5.0是在Spring Framework 4.0之后将近四年内一次重大的升级. 在这个时间框架内,主要的发展之一就是Spring Boot项目的演变. Spring ...

  7. 51 nod 1097 拼成最小的数 思路:字符串排序

    题目: 思路:1.以字符串输入这些整数. 2.对这些字符串排序,排序规则为尽量让能让结果变小的靠前. 代码中有注释,不懂的欢迎在博客中评论问我. 代码: #include <bits\stdc+ ...

  8. 解决子级用css float浮动 而父级div没高度不能自适应高度

    解决子级对象使用css float浮动 而父级div不能自适应高度,不能被父级内容撑开解决方法,父级div没有高度解决方法. 最外层的父级DIV不能自适应高度-不能随对象撑开没有高度 当在对象内的盒子 ...

  9. C#-WinForm 串口通信

    //C# 的串口通信,是采用serialPort控件,下面是对serialPort控件(也是串口通信必备信息)的配置如下代码: serialPort1.PortName = commcomboBox1 ...

  10. 面试题:使用LinkedList来模拟一个堆栈或者队列数据结构

    请使用LinkedList来模拟一个堆栈或者队列数据结构. 堆栈:先进后出 First In Last Out  (FILO) 队列:先进先出 First In First Out  (FIFO) 我 ...