【JAVA 零基础入门系列】Day13 Java 类的继承与多态

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

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

  话不多说,先看栗子:

public class Employee {
    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 来继承父类的属性跟方法,多态则是可以在合适的时候将子类对象视为父类对象进行统一处理,从而实现和增加代码的复用度,让你的代码越来越风骚。

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,729评论 2 9
  • 父类与子类 在Java术语中,如果C1类扩展自另一个类C2,我们称C2为父类,也称超类或基类,称C1为子类,也称次...
    Steven1997阅读 1,133评论 1 2
  • 一、Java 简介 Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计...
    子非鱼_t_阅读 4,148评论 1 44
  • 生活最终还是会回到平淡
    wwwwwhy阅读 91评论 0 0
  • 凡事不能往好的方面想,因为希望越大伴随的失望也越大,正所谓福祸相依。其实只要一颗平常心却对待就好,可是很难控制的住...
    柯和丹阅读 314评论 0 0