广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java全面分析面向对象之继承
  • 714
分享到

Java全面分析面向对象之继承

2024-04-02 19:04:59 714人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录继承什么是继承呢?子类访问父类的成员变量子类访问父类非同名成员变量子类访问父类同名成员变量子类访问父类的成员方法子类访问父类的非同名方法子类访问父类的同名方法super关键字su

继承

什么是继承呢?

继承(Inheritance)是一种联结类与类的层次模型。指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系;继承是一种is-a关系。

看了这些概念你可能还是百思不得其解,我来用大白话给你讲解一下,我们在现实生活中也听过继承,不过是继承家产,继承传承文明.......等等,那这些继承是不就把上一代人传下来的东西全部交给继承人了,这些继承下来的东西,继承人随时都可以用,但是继承人也有属于自己的东西。没错这就是继承,而在我们写代码的时候将一些类所具有的共性全部集中在一起放到一个类中(这个类就是父类),然后子类想要调用从父类继承下来的成员就随时可以调用了。这也就将共性全部抽取出来,实现了代码的复用。

说了这么多不写代码理解可能还是理解的不太通透,好接下来我就举个例子来给大家理解。

实现一个狗类:

//实现一个狗类
class Dog{
      public String name;//名字
      public int age;//年龄
      public String furColor;//毛颜色
      public void eat() {
          System.out.println(this.name+"吃饭!!!");
      }
      public void sleep() {
          System.out.println(this.name+"睡觉!!!");
      }
      public void bark() {
          System.out.println(this.name+"汪汪汪");
      }
}

实现一个猫类:

//实现一个猫类
class Cat{
    public String name;//名字
    public int age;//年龄
    public String furColor;//毛颜色
    public void eat() {
        System.out.println(this.name+"吃饭!!!");
    }
    public void sleep() {
        System.out.println(this.name+"睡觉!!!");
    }
    public void mew() {
        System.out.println(this.name+"喵喵喵");
    }
}

我们都知道猫和狗都是动物,他们都有共性的属性比如名字,年龄,吃饭,睡觉,并且它们还有自己的属性比如狗会汪汪汪,猫会喵喵喵。既然他们有共同的属性我们就可以创建一个动物类。

//实现一个动物类
class Animal{
    public String name;//名字
    public int age;//年龄
    public String furColor;//毛颜色
    public void eat() {
        System.out.println(this.name+"吃饭!!!");
    }
    public void sleep() {
        System.out.println(this.name+"睡觉!!!");
    }
}
//实现一个狗类
class Dog{
      public void bark() {
          System.out.println("汪汪汪");
      }
}
//实现一个猫类
class Cat{
    public void mew() {
        System.out.println("喵喵喵");
    }
}

既然把他们共性都抽取出来怎么用呢?

显然直接用是用不了的。那需要怎么用呢。我们想的是这个狗和猫都要有这些属性,当我们向用的时候随时用,号接下来我们讲的继承就会很好地解决这个问题。

 继承的语法:继承是利用extends关键字将子类与父类建立联系。

//实现一个狗类
class Dog extends Animal{
      public void bark() {
          System.out.println(this.name+"汪汪汪");
      }
}
//实现一个猫类
class Cat extends Animal{
    public void mew() {
        System.out.println("喵喵喵");
    }
}

这回就不报错了。

我们来分析一下这段代码:

在这里子类又叫做派生类,父类可以叫做父类,基类还有超类。

这里有一个问题:

子类继承了父类的什么呢?

答案是:除了构造方法所有。

子类访问父类的成员变量

子类访问父类非同名成员变量

//实现一个猫类
class Cat extends Animal {
    public void mew() {
        System.out.println(this.name + "喵喵喵");
    }
    public void Init() {//访问父类
        this.name = "咪咪";
        this.age = 2;
        this.furColor = "橘黄色";
    }
    public void show() {
        System.out.println(name);
        System.out.println(age);
        System.out.println(furColor);
    }
}

 这里就体现了继承的关系,子类继承了父类的属性(成员变量和成员方法);

这里我们还可以调用构造方法初始化成员,调用toString方法来打印信息

//实现一个猫类
class Cat extends Animal {
    public void mew() {
        System.out.println(this.name + "喵喵喵");
    }
    public Cat(String name,int age,String furColor) {
        this.name =name;
        this.age=age;
        this.furColor =furColor;
    }
    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", furColor='" + furColor + '\'' +
                '}';
    }
}
public class TestDemo1 {
    public static void main(String[] args) {
        //Cat cat = new Cat();
        Cat cat = new Cat("咪咪",2,"橘黄色");
        cat.eat();
        cat.sleep();
        cat.mew();
        System.out.println(cat.toString());
    }
}

子类访问父类同名成员变量

当子类成员变量名与父类成员变量同名了会怎么办呢???

//实现一个动物类
class Animal{
    public String name = "花花";//名字
    public int age;//年龄
    public String furColor;//毛颜色
    public void eat() {
        System.out.println(this.name+"吃饭!!!");
    }
    public void sleep() {
        System.out.println(this.name+"睡觉!!!");
    }
}
//实现一个猫类
class Cat extends Animal {
    public String name = "咪咪";
    public void mew() {
        System.out.println(this.name + "喵喵喵");
    }
    public void Init() {//访问父类
        name = "咪咪";
        this.age = 2;
        this.furColor = "橘黄色";
    }
}
public class TestDemo1 {
    public static void main(String[] args) {
        Cat cat = new Cat();
        System.out.println(cat.name);
    }
}

总结:当父类与子类同名时遵循就近原则,如果实例化子类对象就去子类找,找不到就去父类,父类没有就报错,如果实例化父类对象就直接去父类找,父类没有就报错。

子类访问父类的成员方法

子类访问父类的非同名方法

class Cat extends Animal {
    public String name = "咪咪";
    public void mew() {
        System.out.println(this.name + "喵喵喵");
    }
    public void methodSon() {
        System.out.println("我是子类的方法!!");
    }
    public void method() {
        methodSon();//访问子类
        methodFather();//访问父类
    }
}

子类访问父类的同名方法

//实现一个动物类
class Animal{
    public String name = "花花";//名字
    public int age;//年龄
    public String furColor;//毛颜色
    public void method(int a) {
        System.out.println("我是父类的方法!!"+a);
    }
}
//实现一个猫类
class Cat extends Animal {
    public String name = "咪咪";
    public void mew() {
        System.out.println(this.name + "喵喵喵");
    }
    public void method() {
        System.out.println("我是子类的方法!!");
    }
}
public class TestDemo1 {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.method();//没有带参数的只有子类有,如果两者都有method同样的方法,那就涉及到重写(前提是引用子类对象)优先访问子类
        cat.method(2);//带参数的只有父类有
        //cat.method();
    }
}

子类访问父类同名的方法也是一样的也是采取就近原则,当引用子类对象的时候优先子类,然后去父类寻找,找不到报错。

但是方法这里有两个特殊情况,一是方法重载,说明的是同一个类可以支持方法重载,不同类但是有继承关系的也是支持方法重载的。当出现方法重载,就会根据参数列表的不同来访问。

二是方法重写,方法重写指的是方法名相同返回值相同,参数列表相同,当出现方法重写的时候(前提是引用子类对象)就优先子类,会出现动态绑定,这个咱后面讲解。

上面我们都说同名的时候都会遵循就近原则。就比如我们引用子类对象的时候,我就想优先调用父类,那怎么办呢????

那就该super关键字出场了;

super关键字

super就是一个普通的关键字,来引用当前对象的父类,当我们看见super的时候我们就要知道它是访问父类的就可以了。

好我们来实践一下。

super访问父类成员变量

//实现一个动物类
class Animal{
    public String name = "花花";//名字
    public int age;//年龄
    public String furColor;//毛颜色
}
//实现一个猫类
class Cat extends Animal {
    public String name = "咪咪";
    public void mew() {
        System.out.println(this.name + "喵喵喵");
    }
    public void method() {
        System.out.println(super.name);
    }
}
public class TestDemo1 {
    public static void main(String[] args) {
       Cat cat =new Cat();
       cat.method();
    }
}

super访问父类成员方法

//实现一个动物类
class Animal{
    public String name = "花花";//名字
    public int age;//年龄
    public String furColor;//毛颜色
    public void method() {
        System.out.println("我是父类的方法!!!");
    }
}
//实现一个猫类
class Cat extends Animal {
    public void method() {
        System.out.println("我是子类的方法");
    }
    public void methodA() {
        super.method();
    }
}
public class TestDemo1 {
    public static void main(String[] args) {
       Cat cat =new Cat();
       cat.methodA();
    }
}

创建构造方法 

当我们为父类创建了一个构造方法并且为子类创建构造方法的时候就会报错,原因是什么呢???

那就是当我们创建一个构造方法的时候一定要先为父类创建构造方法,原因是每个类都要至少要有一个构造方法,以前没有报错是因为编译器自动为我们生成了无参的构造方法。子类对象一般都有继承过来的属性还有自己独有的属性,在创建子类对象的时候,一般先执行父类的构造方法,将子类对象中继承父类的属性初始化完整,然后在调用自己的构造方法,为自己独有的属性初始化完整。

所以我们一定要先为父类创建构造方法。

怎么创建呢??? 与this一样只不过这是父类的构造方法,所以利用super关键字,利用super().

同时super不能在静态方法中使用,并且当调用构造方法的时候this()和super()只能出现一个,并且出现在第一行。

super要点:

  • super关键字不能在静态方法中使用。
  • super关键字只能放在方法中的第一行,并且与this()只能出现一个。
  • super关键字访问父类属性  super.父类方法  super.父类成员变量  super()为父类提供构造方法。
  • super关键字是引用父类的对象,当我们看见super的时候,他一定是引用父类的东西。
  • 当没有为父类写带有参数的构造方法的时候,编译器会为子类自动提供构造方法,当父类写了带有参数的构造方法,编译器不会为子类提供无参的构造方法,需要用户自己写,并且在写子类的构造方法的时候一定要先为父类构造。

super与this的区别

相同点:

  • this与super关键均不能在静态方法中使用,静态方法不依赖于对象。
  • 并且只能放在方法的第一行。
  • 都是java中的关键字

不同点:

  • this是引用当前对象,super是用来引用当前对象的父类
  • this()调用本类中的构造方法,super用来调用父类的构造方法。
  • this调用非静态方法中本类当中的属性,super调用非静态方法中的父类的属性
  • this是非静态方法中的隐藏参数,而super不是
  • 构造方法一定会有super的调用,当没有时候编译器会自动增加,而this不会

同时增加一个this和super的内部图示:

顺序

静态代码块与实例代码块及构造方法的初始化顺序

我们之前在上一篇文章讲解了初始化顺序,那时候还没有讲解继承思想,我们再来回忆一下,应该是静态代码块>实例代码块>构造方法,并且代码块只执行一次,也就是只保存一份,当我们构造了两个对象的时候,在实例化第一个对象会执行静态代码块,当实例化第二个代码块的时候,静态代码块不会执行。

接下来我们与继承结合也就是有了父类和子类的静态代码块,构造方法,实例代码块。

那他们的顺序又会是怎样的呢???

我们来用代码实践一下,看结果到底是什么呢???

class Animal {
    public String name = "花花";//名字
    public int age;//年龄
    public String furColor;//毛颜色
    static {
        System.out.println("我是父类的静态代码块!!!");
    }
    {
        System.out.println("我是父类的实例化代码块!!!");
    }
    public void eat() {
        System.out.println(this.name + "吃饭!!!");
    }
    public void sleep() {
        System.out.println(this.name + "睡觉!!!");
    }
    public void method() {
        System.out.println("我是父类的方法!!!");
    }
    public Animal(String name, int age, String furColor) {
        this.name = name;
        this.age = age;
        this.furColor = furColor;
        System.out.println("我是父类的构造方法!!!");
    }
}
//实现一个猫类
class Cat extends Animal {
    public String name = "咪咪";
    static {
        System.out.println("我是子类的静态代码块!!!");
    }
    {
        System.out.println("我是子类的实例化代码块!!!");
    }
    public Cat(String name, int age, String furColor) {
        super(name, age, furColor);
        System.out.println("我是子类的构造方法!!!");
    }
    public void mew() {
        System.out.println(this.name + "喵喵喵");
    }
    public void method() {
        System.out.println("我是子类的方法");
    }
    public void methodA() {
        super.method();
    }
    }
public class TestDemo {
    public static void main(String[] args) {
        Cat cat = new Cat("咪咪",18,"橘黄色");
    }
}

这里还是用了上面的代码,定义了两个类,Animal类和子类Cat,我们同时定义了静态代码块实例代码块,构造方法。接下来运行一下看看顺序到底是什么呢???

我们这里就可以总结一下了,还是静态代码块优先执行,只不过这里因为在构造子类时候优先构造父类所以是父类的静态的代码块优先于子类的静态代码块,然后是父类的实例和构造方法,最后是子类的实例和构造。

还是一样的我们在创建一个对象看还会跟上次的结果一样么??

总结:

 初始化顺序:父类静态代码块>子类静态代码块>父类实例代码块>父类构造方法>子类实例代码块>子类构造方法。如果是第二次实例化对象,那就没有静态代码块。

这个应该很好记忆就是静态代码块优先然后实例代码块然后构造方法,因为构造子类之前要先构造父类所以父类的实例代码块和构造方法要大于子类的实例代码块和构造方法。

详解访问修饰限定符

访问修饰限定符public(公共的)private(私有的)protected(受保护的)default(默认权限)
同一包的同一类yes√yes√yes√yes√
同一包的不同类yes√No×yes√yes√
不同包的子类yes√No×yes√No×
不同报的非子类yes√No×No×No×

看这个你可能会有些懵,接下来我会详细讲解。前提我们先要知道这些都是访问权限超过它自己的权限就不可以访问了。

public:它是公共的意思是无论在哪里同一个包还是不同的包,同一类还是不同的类都可以进行访问。

pivate :只能访问本类中的成员。

default:默认权限就是成员前面啥也不加只能在同一个包中访问。

这里注意:

 protected:可以在同一包中访问,可以再不同包中的子类访问,但是不可以在非子类访问,所以它与继承有很大的关系。

总结访问修饰限定符:

public 可以再同一包中的同一类不同类都能够访问,不同包的子类和非子类也能够访问。

private 只能在本类中使用。

default 也就是默认访问权限,什么也不加,只能在同一个包中访问。

protected 可以在同一包中访问,也可以在不同包的子类访问。

继承方式与组合

继承方式

继承方式多种多样,如果能的话就可以一直继承下去,但在java中继承方式都有哪些呢???

java中的继承方式可以进行单继承,多层继承。

这里还有一个重要的点:那就是虽然可以继承很多,但是最少不要超过3成继承关系。那如果不小心多继承了呢?没关系我们可以利用final修饰,这样就可以停止继承了。

 但是java中不支持多继承也就是一个子类同时继承两个父类。

 这种是不可以的,如果java中要进行多继承的话那就出现了接口。

组合

如果要说组合的话,我们举个例子,组合嘛那就是一个东西由什么组成呗,比如汽车由发动机引擎,轮胎等等组成,学校由老师,学生,工作人员等等组成,而这些老师,学生,工作人员又有自己的属性。我们把这个学校就称为组合。

那用代码如何表示呢??

class Teacher{//老师类
    private String name;
    private int age;
}
class Student{//学生类
    private String name;
    private int id;
}
class School{
    //学校由学生和老师组成
    private Student student[];
    private Teacher teacher[];
}

从这里我们也可以知道继承与组成本质到底是什么样的关系;

我们把继承看做是一种 is   a 关系:比如狗是一个动物,猫是一个动物

我们把组合看做是一种 has   a的关系:比如学校有 学生,老师,工作人员组成。

那我们到底什么时候用组合,什么时候用继承呢???

两种方式不一定就要用哪个。我们他们两的区别:1.继承是一种is....a的关系,我们都知道程序是先编译后运行,而继承关系就是在编译器编译截断下确定好的。组合关系是在运行时确定的。

所以组合比继承更加简单灵活高效。我们如果非必要情况下优先选择组合。

到此这篇关于Java全面分析面向对象之继承的文章就介绍到这了,更多相关Java继承内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java全面分析面向对象之继承

本文链接: https://www.lsjlt.com/news/147338.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java全面分析面向对象之继承
    目录继承什么是继承呢?子类访问父类的成员变量子类访问父类非同名成员变量子类访问父类同名成员变量子类访问父类的成员方法子类访问父类的非同名方法子类访问父类的同名方法super关键字su...
    99+
    2022-11-13
  • JAVA面向对象之继承 super入门解析
    目录1 继承1.1概念1.2 特点1.3 练习:继承入门案例2 super3 继承的用法3.1 练习:super之继承中成员变量使用3.2 练习:super之继承中构造方法的使用4 ...
    99+
    2022-11-13
  • python 面向对象之继承
    文章目录 前言继承的概念单继承多继承子类重写父类的同名方法和属性子类调用父类同名的方法和属性多层继承私有权限 前言 前面我们已经学习了 python 面向对象的类和对象,那么今天我将为大...
    99+
    2023-09-01
    python 开发语言
  • Java全面分析面向对象之多态
    目录多态的理解向上转型向上转型的三种形式动态绑定和静态绑定方法的重写进一步认识和理解多态多态的优点多态的理解 什么是多态呢??从字面理解就是多种形态,也就是不同类实例化出来的对象调用...
    99+
    2022-11-13
  • Java全面分析面向对象之封装
    目录什么是封装呢封装的好处意义getter方法和setter方法toString方法面向对象封装之包自定义包什么是封装呢 封装就是一种将数据和操作数据的方法进行有机结合,一种函数抽象...
    99+
    2022-11-13
  • Java面向对象之类的继承介绍
    目录继承的作用如果没有继承机制是怎么样的?使用继承机制后的示例?类的继承是什么?子类和父类的继承机制Java单继承Java继承的顶级父类:Object对象的类型转换对象向上转型对象向...
    99+
    2022-11-13
  • python 面向对象之类的继承
    python中什么是继承:新类不必从头编写新类从现有的类继承,就自动拥有了现有类的所有功能新类只需要编写现有类缺少的新功能继承的好处:复用已有代码自动拥有了现有类的所有功能只需要编写缺少的新功能继承的特点:子类和父类是is关系python继...
    99+
    2023-01-30
    面向对象 python
  • python 面向对象之继承顺序
    先来看一个经典类class A:     def __init__(self):         p...
    99+
    2023-01-30
    面向对象 顺序 python
  • Python面向对象——继承
    #coding:utf-8 """ 术语: 1、在python3中,自定义创建的类都默认继承了python类中名为object的类 2、object类提供的方法,是双下划线开头的,是为了提供给python内部使用 3、被继承的类叫做超类,...
    99+
    2023-01-31
    面向对象 Python
  • Java面向对象之继承的概念详解
    目录1. 继承1.1 继承的实现1.2 继承的好处和弊端1.3. Java中继承的特点2. 继承中的成员访问特点2.1 继承中变量的访问特点2.2 super2.3 方法重写2.4 ...
    99+
    2023-05-18
    Java 继承 Java 面向对象
  • 【Java基础篇 | 面向对象】—— 继承
    个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【JavaSE_primary】 本专栏旨在分享学习Java...
    99+
    2023-10-11
    java 开发语言 面向对象
  • javascript面向对象三大特征之继承的示例分析
    小编给大家分享一下javascript面向对象三大特征之继承的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!具体如下:继...
    99+
    2022-10-19
  • 详析Python面向对象中的继承
    目录一单继承1.继承的基本语法格式如下2.查看类继承情况3.继承中的属性和方法4.初始化函数__init__()和super二多层继承三多重继承一 单继承 类继承作为python的三...
    99+
    2022-11-13
  • 详解Java面向对象中的继承
    继承的概念 继承是面向对象编程中的一个概念,它允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)的属性和方法。子类在继承父类的同时也可以添加自己的属性和方法,从而实现代码的...
    99+
    2023-05-19
    Java 面向对象 Java 继承
  • JAVA面向对象中如何继承super
    小编今天带大家了解JAVA面向对象中如何继承super,文中知识点介绍的非常详细。觉得有帮助的朋友可以跟着小编一起浏览文章的内容,希望能够帮助更多想解决这个问题的朋友找到问题的答案,下面跟着小编一起深入学习“JAVA面向对象中如何继承sup...
    99+
    2023-06-28
  • python面向对象之类的继承详解
    目录一、概述 二、类的继承2.1 继承的定义2.2 构造函数的继承 2.3 子类对父类方法的重写三、类继承的事例一、概述  面向对象编程 (OOP) 语言的一个主要功能就是“继承”。...
    99+
    2022-11-12
  • Python面向对象编程之类的继承
    目录1、对继承的理解2、类继承的构建3、Python中最基础的类4、ython类的重载4.1 属性重载4.2 方法重载5、类的多继承1、对继承的理解 继承(Inheritance) ...
    99+
    2022-11-12
  • python 面向对象之继承实例讲解
    面向对象编程语言具有封装、继承、多态三个基本特征,本文就继承举例详谈比如说学校主要有3大角色:学校,讲师,学员学校可以注册学员,统计有多少学员老师负责讲课学生听课,提问,学习,交学费先定义4个类:class School(obje...
    99+
    2023-01-30
    面向对象 实例 python
  • 【JavaSE】面向对象编程思想之继承
     【本节目标】 继承 组合 目录 1. 为什么需要继承 2. 继承概念 3. 继承的语法 4. 父类成员访问 4.1 子类中访问父类的成员变量 4.2 子类中访问父类的成员方法 5. super关键字 6. 子类构造方法 7....
    99+
    2023-09-03
    java 开发语言 学习方法
  • java面向对象继承与多态介绍
    目录一.概述  二.继承2.1 继承的概述2.2 继承机制2.3 类中属性,方法的继承与覆盖2.4 super 关键字三. 多态总结一.概述 ...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作