美文网首页
《Oracle Java SE编程指南》13-02:继承的概念

《Oracle Java SE编程指南》13-02:继承的概念

作者: AT阿宝哥 | 来源:发表于2020-04-22 22:22 被阅读0次
课程封面-JavaSE-AT阿宝哥

内容导航

  • 前言
  • 1、定义
  • 2、继承的语法形式
  • 3、类的单继承
  • 4、类的层次结构
  • 5、子类的使用
  • 6、继承的作用

前言

在先前的课程中,我们已经不止一次提到继承,继承机制是面向对象程序设计不可缺少的关键概念,是实现软件可重用的根基,是提高软件系统的可扩展性与可维护性的主要途径。

那么,什么是继承呢?


1、定义

继承(Inheritance),在Java语言中,可以从其他类派生新的类,即基于一个已有类定义一个新类,从而实现已有类的代码复用。从已有类派生的新类被称为子类,也称为派生类、扩展类。派生类的已有类被称为超类,也称为基类或父类。

子类从其超类继承所有成员,包括字段、方法和嵌套类,构造器不是成员,所以子类不会继承它们,但是可以从子类调用超类的构造器。另外,子类还能扩展新的字段、方法和嵌套类,使其达到丰富结构和扩展能力的效果。


2、继承的语法形式


【访问级别修饰符】    【特性修饰符】    子类名    extends    父类名  {

    //子类体

}

示例代码-Shape类:


package com.company.project.demo0201;

//类:图形
public class Shape {

    // 属性:x坐标
    private int x;

    // 属性:y坐标
    private int y;

    // 构造器:无参的
    public Shape() {

    }

    // 方法:绘图
    public void draw() {
        // 绘制图形的算法
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

}


示例代码-Circle类:


package com.company.project.demo0201;

//类:圆形
public class Circle extends Shape {

    // 属性:半径
    private int r;

    // 构造器:无参的
    public Circle() {

    }

    // 方法:绘图
    public void draw() {

        // 绘制圆形的算法

    }

    // 方法:获取直径
    public int getDiameter() {

        return 2 * r;
    }

}

示例代码-Rectangle类:


package com.company.project.demo0201;

//类:矩形
public class Rectangle extends Shape{

    // 属性:w宽度
    private int w;

    // 属性:h高度
    private int h;

    // 构造器:无参的
    public Rectangle() {

    }

    // 方法:绘图
    public void draw() {

        // 绘制矩形的算法

    }

    public int getW() {
        return w;
    }

    public void setW(int w) {
        this.w = w;
    }

    public int getH() {
        return h;
    }

    public void setH(int h) {
        this.h = h;
    }

}


我们观察上面的代码发现,类CircleRectangle的定义中通过使用extends关键字继承了类Shape,此时,我们把Shape称为父类,反之,把类CircleRectangle称为子类。

而且,子类Circle新增了半径属性r,新增了获取直径的方法getDiameter()。子类Rectangle新增了宽度属性w和高度属性h。这意味着,子类丰富了自己的结构,且扩展了新的能力。


3、类的单继承

在Java平台中的继承是单继承,是指除了没有超类的Object类之外,每个类都有且只有一个直接超类

3.1、根类Object类

Object是根类,它没有超类。

官方源码:


package java.lang;

/**
 * Class {@code Object} is the root of the class hierarchy.
 * Every class has {@code Object} as a superclass. All objects,
 * including arrays, implement the methods of this class.
 *
 * @author  unascribed
 * @see     java.lang.Class
 * @since   JDK1.0
 */
public class Object {

}

3.2、隐式直接子类与间接子类

在没有任何其他显式超类的情况下,每个类都是Object类的隐式直接子类。在拥有任何其他显式超类的情况下,每个类都是Object类的间接子类

示例代码-Shape类:


package com.company.project.demo020302;

//类:图形
public class Shape {

    // 属性:x坐标
    private int x;

    // 属性:y坐标
    private int y;

    // 构造器:无参的
    public Shape() {

    }

    // 方法:绘图
    public void draw() {
        // 绘制图形的算法
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

}


示例代码-Circle类:


package com.company.project.demo020302;

//类:圆形
public class Circle extends Shape {

    // 属性:半径
    private int r;

    // 构造器:无参的
    public Circle() {

    }

    // 方法:绘图
    public void draw() {

        // 绘制圆形的算法

    }

    // 方法:获取直径
    public int getDiameter() {

        return 2 * r;
    }

}


示例代码-Rectangle类:


package com.company.project.demo020302;

//类:矩形
public class Rectangle extends Shape{

    // 属性:w宽度
    private int w;

    // 属性:h高度
    private int h;

    // 构造器:无参的
    public Rectangle() {

    }

    // 方法:绘图
    public void draw() {

        // 绘制矩形的算法

    }

    public int getW() {
        return w;
    }

    public void setW(int w) {
        this.w = w;
    }

    public int getH() {
        return h;
    }

    public void setH(int h) {
        this.h = h;
    }

}


观察上述代码,类Shape没有任何其他显式超类,它是Object类的隐式直接子类。类CircleRectangle都拥有显式超类Shape,它们都是Object类的间接子类。

3.3、类的直接超类有且只有一个

每个类的直接超类有且只有一个。这意味着extends关键字后面的超类不能有多个,即不能是列表。

假如我们异想天开的定义一个圆角矩形类RoundedRectangle,使其同时继承圆形类Circle和矩形类Rectangle,那么将导致编译时错误。

示例代码-Circle类:


package com.company.project.demo020303;

//类:圆形
public class Circle {

}

示例代码-Rectangle类:


package com.company.project.demo020303;

//类:矩形
public class Rectangle {

}

示例代码-Rectangle类:


package com.company.project.demo020303;

//类:圆角矩形
//报错:Syntax error on token ",", . expected
public class RoundedRectangle extends Circle , Rectangle {

}


提示
接口支持多继承,这意味着Java编程语言中的单继承机制仅仅针对类而言;
尽管类不支持多继承,但是可以实现多个接口;
我们将在接口章节详述这些知识点。

4、类的层次结构

Object类,在java.lang包,定义并实现所有类共有的行为,包括我们自己编写的类。我们摘录了Object类的部分官方源码,以作了解,具体请查阅JDK安装目录的src源码文件夹。

官方代码-Object类:


package com.company.project.demo020401;

package java.lang;

/**
 * Class {@code Object} is the root of the class hierarchy. Every class has
 * {@code Object} as a superclass. All objects, including arrays, implement the
 * methods of this class.
 *
 * @author unascribed
 * @see java.lang.Class
 * @since JDK1.0
 */
public class Object {

    package java.lang;

/**
 * Class {@code Object} is the root of the class hierarchy. Every class has
 * {@code Object} as a superclass. All objects, including arrays, implement the
 * methods of this class.
 *
 * @author unascribed
 * @see java.lang.Class
 * @since JDK1.0
 */
public class Object {

    private static native void registerNatives();

    static {
        registerNatives();
    }

    public final native Class<?> getClass();

    public native int hashCode();

    public boolean equals(Object obj) {
        return (this == obj);
    }

    protected native Object clone() throws CloneNotSupportedException;

    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

    public final native void notify();

    public final native void notifyAll();

    public final native void wait(long timeout) throws InterruptedException;

    public final void wait(long timeout, int nanos) throws InterruptedException {

    }

    public final void wait() throws InterruptedException {

    }

    protected void finalize() throws Throwable {
        
    }
}

类可以从超类派生而来,还可以从派生类继续派生新的类,如此父生子、子生孙、孙生玄孙...子子孙孙无穷尽也。反之,它们最终都从最顶层的Object类派生而来,形成类的层次结构。

Java中所有的类都是Object的后代

在层次结构的顶部,Object是所有类中最一般化的,靠近层次结构底部的类提供了更专门化的行为,当然,这需要根据实际情况去扩展子类。

那么,我们如何扩展子类呢?


5、子类的使用

子类继承父类的所有public成员和protected成员,不管子类在哪个包中。如果子类与其父类在同一个包中,它还继承父类的package-private成员。我们可以按原样使用继承的成员,替换它们,隐藏它们,或者扩充新成员。

子类的可能使用场景

  • 继承的字段可以直接使用,就像任何其他字段一样。
  • 可以在子类中声明与超类中同名的字段,从而隐藏它(不建议这样做)。
  • 可以在子类中声明不属于超类的新字段。
  • 继承的方法可以直接使用。
  • 可以在子类中编写与超类中具有相同签名的新实例方法,从而覆盖它。
  • 可以在具有与超类相同签名的子类中编写新的静态方法,从而隐藏它。
  • 可以在子类中声明不属于超类的新方法。
  • 可以通过隐式或使用关键字super编写调用超类构造器的子类构造器。

6、继承的作用

继承的思想很简单,但很强大。当我们创建一个新类,并且一个已有类已经包含想要的一些代码时,就可以从已有类派生新类。

因此,继承的主要作用是代码复用,表现为子类及对象可以直接调用父类成员,包括字段、方法和内部类型,而不必重复编写和调试它们。

//类:使用场景
public class Client {

    public static void main(String[] args) {

        Circle circle = new Circle();

        // 访问父类的属性和方法
        circle.setX(1);
        circle.setY(1);

        circle.draw();

        // 访问子类的属性和方法
        circle.setR(9);

        circle.getDiameter();

    }

}

持续更新,欢迎留言提议!
码字很累,多点赞多赞赏!


扫描二维码,关注AT阿宝哥

相关文章

网友评论

      本文标题:《Oracle Java SE编程指南》13-02:继承的概念

      本文链接:https://www.haomeiwen.com/subject/yvigihtx.html