一篇文章超详细的介绍Java继承

目录
  • 前言
  • 继承
  • 继承的优点
  • 重写和隐藏父类方法
    • 重写父类中的方法
    • 隐藏父类中的方法
    • 方法重写和隐藏后的修饰符
  • 子类访问父类私有成员
  • 使用super关键字
    • 使用super调用父类的无参数构造方法/有参数构造方法
  • 附:继承的使用和认识
  • 总结

前言

继承是面向对象语法的三大特征之一。继承可以降低代码编写的冗余度,提高编程的效率。通过继承,子类获得了父类的成员变量和方法。一个子类如何继承父类的字段和方法,如何修改从父类继承过来的子类的方法呢。今天我们开始学习有关Java继承的知识。

继承

继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

继承的作用:通过继承可以快速创建新的类,实现代码的重用,提高程序的可维护性,节省大量创建新类的时间,提高开发效率和开发质量。

在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:

class 父类{
    ...       //成员变量、成员方法
}
class 子类 extends 父类{
    ...       //类体
}

例如:

class teacher{             //声明一个teacher类为父类
    String name;             //定义父类的成员变量name、age
    int age;
    void show(){           //定义父类成员方法,将成员变量输出
        System.out.println(name);
        System.out.println(age);
    }
}
class Student extends teacher {     //声明一个Student类为子类并继承父类
}
public class myfirst {
    public static void main(String[] args) {
    System.out.println("学生");
    Student student=new Student();     //声明一个Student类的实例对象student
    student.name="Tom";                //子类调用父类的成员变量name并赋值
    student.age=19;                    //子类调用父类的成员变量age并赋值
    student.show();                    //子类调用父类的成员方法show
    }
}

运行结果为:

学生
Tom
19

注意:

  • 子类不能选择性继承父类;
  • Java不支持多重继承,但一个类可以实现多个接口,从而克服单继承的缺点;
  • 构造方法不会被子类继承,但可以从子类中调用父类的构造方法。

继承的优点

  • 继承过来的字段和方法,可以像任何其他字段和方法一样被直接使用;
  • 在子类中可以声明一个与父类中同名的新字段或静态方法,从而“隐藏”父类中的字段或方法;
  • 可以在子类中声明一个在父类中没有的新字段和方法;
  • 可以在子类中编写一个父类当中具有相同名的新实例方法,这称为“方法重写”或“方法覆盖”;
  • 可以在子类中编写一个调用父类构造方法的子类构造方法,既可以隐式地实现,也可以通过使用关键字super来实现。

重写和隐藏父类方法

子类继承了父类中的所有成员及方法,但在某种情况下,子类中该方法所表示的行为与其父类中该方法所表示的行为不完全相同,例如,在父类语言中定义了说话这个方法,而在子类中说话的方法是不同的:外国人说英文,中国人说中文,这时我们就需要重写或隐藏父类的该方法。

重写父类中的方法

当一个子类中一个实例方法具有与其父类中的一个实例方法相同的签名(指名称、参数个数和类型)和返回值时,称子类中的方法“重写”了父类的方法。例如:

class A{
    public void sayHello() {                      //输出英文欢迎
        System.out.println("Hello,Welcome to Java!!!");
    }
    public void sayBye() {
        System.out.println("GoodBye,everyone");
    }
}
class B extends A {
    public void sayHello() {                      //输出中文欢迎
        System.out.println("大家好,欢迎学习Java!!!");
    }
}
public class myfirst {
    public static void main(String[] args) {
    B b=new B();                                //创建子类B的一个实例对象,使用默认构造方法
    b.sayHello();                               //调用子类中重写的方法
    b.sayBye();                                 //调用父类中的方法
    }
}

运行结果为:

大家好,欢迎学习Java!!!
GoodBye,everyone

注意:重写的方法具有与其所重写的方法相同的名称、参数数量、类型和返回值。

隐藏父类中的方法

如果一个子类定义了一个静态类方法,而这个类方法与其父类的一个类方法具有相同的签名(指名称、参数格式和类型)和返回值,则称在子类中的这个类方法“隐藏”了父类中的该类方法。

  • 当调用被重写的方法时,调用的版本是子类的方法;
  • 当调用被隐藏的方法时,调用的版本取决于是从父类中调用还是从子类中调用。
class A{
    public static void sayHello() {             //静态类方法
        System.out.println("大家好,这是A的静态类方法");
    }
    public void sayHello2() {                   //实例方法
        System.out.println("大家好,这是A中的实例方法");
    }
}
class B extends A {
    public static void sayHello() {             //静态类方法
        System.out.println("大家好,这是B的静态类方法");
    }
    public void sayHello2() {                   //实例方法
        System.out.println("大家好,这是B的实例方法");
    }
}
public class myfirst {
    public static void main(String[] args) {
        B b=new B();                           //创建B类的实例对象b
        A a=b;                                 //隐式对象类型转换
        A.sayHello();                          //调用A类的静态类方法
        a.sayHello();                          //调用a对象的静态类方法
        B.sayHello();                          //调用B类的静态方法
        a.sayHello2();                         //调用a对象的实例方法
        b.sayHello2();                         //调用b对象的的实例方法
        A a2=new A();                          //创建A类的实例对象a2
        a2.sayHello2();                        //调用a2对象的实现方法
    }
}

运行结果为:

大家好,这是A的静态类方法
大家好,这是A的静态类方法
大家好,这是B的静态类方法
大家好,这是B的实例方法
大家好,这是B的实例方法
大家好,这是A中的实例方法

可以看出,得到调用的隐藏方法是父类中的方法,而得到调用的重写方法是子类中的方法。

方法重写和隐藏后的修饰符

在子类中被重写的方法,其访问权限允许大于但不允许小于被其重写的方法,例如:父类中一个受保护的实例方法(protected)在子类中可以是公共的(public)的,但不可以是私有的(private)。如果一个方法在父类中是static方法,那么在子类也必须是static方法;如果一个方法在父类中是实例方法,那么在子类中也必须是实例方法。

子类访问父类私有成员

子类继承其父类的所有public和protected成员,但不能继承其父类的private成员。那么如何在子类中访问到父类中的字段呢,我们可以在父类中提供用来访问其私有字段的public或protected方法,子类使用这些方法来访问相应的字段。例如:

class A{                     //父类A
    private int value=10;    //声明一个私有变量value并赋值为10
    public int getvalue() {  //声明一个公有成员方法getvalue,返回value
        return value;
    }
}
class B extends A{           //A的子类B
}
public class myfirst {
    public static void main(String[] args) {
      B b=new B();           //创建子类B的一个实例对象
      System.out.println("子类通过父类提供的公共接口访问A中的私有字段value:"+b.getvalue());
    }
}

运行结果为:

子类通过父类提供的公共接口访问A中的私有字段value:10

使用super关键字

使用super调用父类中重写的方法、访问父类中被隐藏的字段
子类重写了父类中的某一个方法,隐藏父类中的字段,假如想在子类中访问到父类中被重写的方法和隐藏父类的字段,可以在子类中通过使用关键字super来调用父类中被重写的方法和访问父类中被隐藏的字段。例如:

package first;
class A{
    public String name="张飞";         //添加成员变量
    public void say() {                //添加成员方法say
        System.out.println("我是父类A成员方法say");
    }
}
class B extends A{
    public String name="关羽";         //与父类中同名的字段,隐藏父类
    public void say(){                 //重写方法say
        super.say();                   //使用super关键字调用父类中的方法
        System.out.println("我是子类B成员方法say");
        System.out.println("父类的name名字:"+super.name); //使用super关键字访问父类中的变量
    }
}
public class myfirst {
    public static void main(String[] args) {
      B b=new B();                     //创建子类的一个实例对象
      b.say();                         //调用子类中重写的方法
      System.out.println("子类的name名字:"+b.name);   //调用子类中的name
    }
}

运行结果为:

我是父类A成员方法say
我是子类B成员方法say
父类的name名字:张飞
子类的name名字:关羽

使用super调用父类的无参数构造方法/有参数构造方法

子类不继承其父类的构造方法。

  • 当使用无参数的super()时,父类的无参数构造方法就会被调用;
  • 当使用带有参数的super()方法时,父类的有参数构造方法就会被调用。

例如:

class SuperClass {              //创建父类SuperClass
      private int n;            //声明一个私有变量n
      SuperClass(){             //父类无参数构造方法
        System.out.println("这是父类SuperClass无参数构造方法");
      }
      SuperClass(int n) {       //父类有参数构造方法
        System.out.println("这是父类SuperClass有参数构造方法");
        this.n = n;
      }
    }
    class SubClass extends SuperClass{     // SubClass类继承SuperClass类
      private int n;                       //声明一个私有变量n
      SubClass(){                          // 自动调用父类的无参数构造器
        System.out.println("这是子类无参数构造方法");
      }  

      public SubClass(int n){              //子类有参数构造方法
        super(300);                        //调用父类中带有参数的构造器
        System.out.println("这是子类有参数构造方法"+n);
        this.n = n;
      }
    }
public class myfirst {
    public static void main(String[] args) {
            SubClass sc1 = new SubClass();      //创建子类SubClass实例对象,调用其无参数构造方法
            SubClass sc2 = new SubClass(100);   //创建子类SubClass实例对象,调用其有参数构造方法
    }
}

运行结果为:

这是父类SuperClass无参数构造方法
这是子类无参数构造方法
这是父类SuperClass有参数构造方法
这是子类有参数构造方法100

注意

  • 如果要初始化父类中的字段,可以在子类的构造方法中通过关键字super调用父类的构造方法;
  • 对父类的构造放的调用必须放在子类构造方法的第一行;
  • 如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器;
  • 如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表;
  • 子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。

附:继承的使用和认识

1、继承是怎么实现的?

使用extends 和 implements 关键字

extends 继承的都是对象

implements 继承实现并实现的是接口

2、在继承的场景下,同一样东西,怎么区分是你老爹的还是你自己的?

使用super 与 this 关键字

super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

this关键字:指向自己的引用。

3、父类的某些方法不想被子类继承,怎么处理?

对方法或属性进行 private 关键字或final关键字修饰

private 关键字修饰,子类无法使用和继承

final关键字修饰,无法继承,但是否可以被使用需要看权限属性

总结

到此这篇关于Java继承的文章就介绍到这了,更多相关Java继承介绍内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java封装、继承、多态三大特征的理解

    首先先简单的说一下其3大特性的定义: 封装:隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别.将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成"类",其中数据和函数都是类的成员.封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,一特定的访问权限来使用类的成员.封装的基本要求是: 把所有的属性私有化,对每个属性提供getter和setter方法,如果有一个带参的

  • java继承中的构造方法实例解析

    本文实例讲述了java继承中的构造方法.分享给大家供大家参考.具体如下: 继承中的构造方法: 1.子类的构造过程中必须调用其基类的构造方法. 2.子类可以在自己的构造方法中使用super(argument_list)调用基类的构造方法. 2.1.使用this(argument_list)调用本类的另外构造方法.   2.2.如果调用super,必须写在子类构造方法的第一行. 3.如果子类的构造方法中没有显示的调用基类的构造方法,则系统默认调用基类的无参数构造方法. 4.如果子类构造方法中既没有显

  • Java中继承、多态、重载和重写介绍

    什么是多态?它的实现机制是什么呢?重载和重写的区别在那里?这就是这一次我们要回顾的四个十分重要的概念:继承.多态.重载和重写. 继承(inheritance) 简单的说,继承就是在一个现有类型的基础上,通过增加新的方法或者重定义已有方法(下面会讲到,这种方式叫重写)的方式,产生一个新的类型.继承是面向对象的三个基本特征--封装.继承.多态的其中之一,我们在使用JAVA时编写的每一个类都是在继承,因为在JAVA语言中,java.lang.Object类是所有类最根本的基类(或者叫父类.超类),如果

  • Java内部类的继承(全)

    下面通过实例代码给大家分享下有关JAVA内部类的继承,具体详解如下: Java内部类的构造器必须连接到指向其外围类对象的引用(构造内部类必须给它一个外部类对象的引用,内部类依赖于外部类对象),所以在继承内部类的时候,需要在导出类的构造器中手动加入对基类构造器的调用. 因为,在导出类实例化时,并不存在一个外围类对象,以让导出类的实例去连接到它. 所以,我们需要创建一个外围类,然后用一个特定的语法来表明内部类与外围类的关系. 在下例子中,需要给导出类InheritInner一个来自内部类的外围类中的

  • 解析Java继承中方法的覆盖和重载

    方法的覆盖 在类继承中,子类可以修改从父类继承来的方法,也就是说子类能创建一个与父类方法有不同功能的方法,但具有相同的名称.返回值类型.参数列表. 如果在新类中定义一个方法,其名称.返回值类型和参数列表正好与父类中的相同,那么,新方法被称做覆盖旧方法. 参数列表又叫参数签名,包括参数的类型.参数的个数和参数的顺序,只要有一个不同就叫做参数列表不同. 被覆盖的方法在子类中只能通过super调用. 注意:覆盖不会删除父类中的方法,而是对子类的实例隐藏,暂时不使用. 请看下面的例子: public c

  • 老生常谈 Java中的继承(必看)

    Java作为一面向对象的语言,具备面向对象的三大特征--继承,多态,封装. 继承顾名思义,继任,承接,传承的意思.面向对象的语言有一个好处,就是可以用生活中的例子来说明面向对象的特性.那么我们先来看看生活中的继承关系有哪些?最常见的:父母子女:汽车,电动车,自行车和车.无论哪种车,都有具备车的特性.再比如说:家里面的电饭锅,电磁炉,电冰箱.他们都属于电器类,都具有名字这个属性,也都需要用电这个方法.如果在程序中我们一个个类去把这些重复的代码都写上去,那不是浪费时间和精力吗?联系之前的知识,我们能

  • java中重载,继承,重写和多态的区别

    重载,继承,重写和多态的区别: 1)继承是子类获得父类的成员. 2)重写是继承后重新实现父类的方法. 3)重载是在一个类里一系列参数不同名字相同的方法. 4)多态则是为了避免在父类里大量重载引起代码臃肿且难于维护. 网上看到一个有趣的说法是:继承是子类使用父类的方法,而多态则是父类使用子类的方法. 下面的例子包含了这四种实现: class Triangle extends Shape { public int getSides() {   return 3;  } } class Rectang

  • java的继承原理与实现方法详解

    本文实例讲述了java的继承原理与实现方法.分享给大家供大家参考,具体如下: 继承 1.java中是单继承的.每个子类只有一个父类. 语法:子类 extends 父类 2.在java中,即使没有声明父类,也有一个隐含的父类,就是Object类 3.在子类中可以使用super来调用父类的方法 4.继承中的构造方法问题 在new一个子类实例的过程中,会优先自动调用父类默认的无参数构造方法,然后再调用子类的构造方法.如果父类没有默认的构造方法,只有带参数的构造方法,此时就会出错. 除了由jvm自动调用

  • java教程之java继承示例详解

    什么是继承(extends)? 继承是:新定义的类是从已有的类中获取属性和方法的现象. 这个已有的类叫做父类, 从这个父类获取属性和方法的类叫做子类. ExtendsDemo1.java 复制代码 代码如下: /*什么是继承*/public class ExtendsDemo1 {    public static void main(String[] args) {        Truck t = new Truck();        t.size = 100;           //不

  • 一篇文章超详细的介绍Java继承

    目录 前言 继承 继承的优点 重写和隐藏父类方法 重写父类中的方法 隐藏父类中的方法 方法重写和隐藏后的修饰符 子类访问父类私有成员 使用super关键字 使用super调用父类的无参数构造方法/有参数构造方法 附:继承的使用和认识 总结 前言 继承是面向对象语法的三大特征之一.继承可以降低代码编写的冗余度,提高编程的效率.通过继承,子类获得了父类的成员变量和方法.一个子类如何继承父类的字段和方法,如何修改从父类继承过来的子类的方法呢.今天我们开始学习有关Java继承的知识. 继承 继承就是子类

  • Java超详细讲解类的继承

    目录 写在前面 1.子类的创建 1.1子类的创建方法 1.2调用父类中特定的构造方法 2.在子类中访问父类成员 3.覆盖 3.1覆盖父类中的方法 3.2用父类的对象访问子类的成员 4.不可被继承的成员和最终类 实例java代码 写在前面 类的继承可以在已有类的基础上派生出来新的类,不需要编写重复的代码,提高了代码的复用性,是面向对象程序设计的一个重要的特点,被继承的类叫做父类,由继承产生的新的类叫做子类,一个父类可以通过继承产生多个子类,但是与C++不同的是Java语言不支持多重继承,即不能由多

  • 一篇文章让你彻底了解Java可重入锁和不可重入锁

    可重入锁 广义上的可重入锁指的是可重复可递归调用的锁,在外层使用锁之后,在内层仍然可以使用,并且不发生死锁(前提得是同一个对象或者class),这样的锁就叫做可重入锁. 我的理解就是,某个线程已经获得某个锁,可以无需等待而再次获取锁,并且不会出现死锁(不同线程当然不能多次获得锁,需要等待). 简单的说,就是某个线程获得某个锁,之后可以不用等待而再次获取锁且不会出现死锁. 常见的可重入锁 Synchronized和ReentrantLock 都是可重入锁. 可重入锁的释放 同一个线程获取同一个锁,

  • Kotlin协程flowOn与线程切换超详细示例介绍

    目录 示例代码 一.flowOn方法 1.ChannelFlowOperatorImpl类 二.collect方法 1.ChannelFlowOperator类的collect方法 2.ChannelFlow类的collect方法 3.flow方法中代码的执行 4.接收flow方法发出的值 三.flowOn方法与流的融合 四.总结 示例代码 本文分析示例代码如下: launch(Dispatchers.Main) { flow { emit(1) emit(2) }.flowOn(Dispatc

  • 一篇文章带你搞懂Java线程池实现原理

    目录 1. 为什么要使用线程池 2. 线程池的使用 3. 线程池核心参数 4. 线程池工作原理 5. 线程池源码剖析 5.1 线程池的属性 5.2 线程池状态 5.3 execute源码 5.4 worker源码 5.5 runWorker源码 1. 为什么要使用线程池 使用线程池通常由以下两个原因: 频繁创建销毁线程需要消耗系统资源,使用线程池可以复用线程. 使用线程池可以更容易管理线程,线程池可以动态管理线程个数.具有阻塞队列.定时周期执行任务.环境隔离等. 2. 线程池的使用 /** *

  • 一篇文章带你深入了解Java类加载

    目录 1.类加载 <1>.父子类执行的顺序 <2>类加载的时机 <3>类的生命周期 <4>类加载的过程 <5>类加载器 1.启动类加载器(BootstrapClassLoader) 2.扩展类加载器(ExtClassLoader) 3.应用程序类加载器(AppClassLoader) 4.2 自定义加载器 <6>类加载机制--双亲委派模型 总结 1.类加载 <1>.父子类执行的顺序 1.父类的静态变量和静态代码块(书写顺序

  • 一篇文章带你搞定JAVA泛型

    目录 1.泛型的概念 2.泛型的使用 3.泛型原理,泛型擦除 3.1 IDEA 查看字节码 3.2 泛型擦除原理 4.?和 T 的区别 5.super extends 6.注意点 1.静态方法无法访问类的泛型 2.创建之后无法修改类型 3.类型判断问题 4.创建类型实例 7.总结 1.泛型的概念 泛型的作用就是把类型参数化,也就是我们常说的类型参数 平时我们接触的普通方法的参数,比如public void fun(String s):参数的类型是String,是固定的 现在泛型的作用就是再将St

  • 一篇文章带你搞定JAVA反射

    目录 1.反射的概念 1.概念 2.获取字节码文件对象的方式 2.1 元数据的概念 2.2 获取class对象的方式 1.访问权限 2.获取方法 2.1 访问静态方法 2.2 访问类方法 3.获取字段,读取字段的值 4.获取实现的接口 5.获取构造函数,创建实例 6.获取继承的父类 7.获取注解 4.反射实例 5.总结 1.反射的概念 1.概念 反射,指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对任意一个对象,都能调用它的任意一个方法.这种动态获取信息,以及动态调用对象方法

  • 一篇文章带你深入了解Java对象与Java类

    目录 1.面向对象是什么? 2.Java类 1.什么是类 2.Java类 类的结构 Java类的格式 3.java对象 4.类和对象 5.类中的变量,方法 1.变量分类 成员变量: 局部变量: 2.方法分类 6.方法重载 7.对象与引用 基本类型和引用类型的区别: 值传递与引用传递 8.static关键字 概念 static属性 static方法 代码块 9.类的加载执行 10.包 包的概念: 包的作用: 包(package)的命名规范: 访问权限修饰符 11.面向对象语言的三大特征 1.封装

  • 一篇文章带你深入了解Java基础

    目录 1.String类 1.1两种对象实例化方式 1.2字符串比较 1.3字符串常量是String的匿名对象 1.4String两种实例化方式区别 1.分析直接赋值方式 2.构造方法赋值 1.5字符串常量不可改变 1.6开发中String必用 1.7字符串和字符数组 1.9字符串比较 1.11字符串的替换 1.12字符串的拆分 1.12字符串的截取 1.13其他操作方法 2.1. 给定一个email地址,要求验证其是否正确,提示:可以简单的验证一下,重点验证"@"和".&q

随机推荐