一、继承的概念及用法

      继承背后的思想就是        基于已存在的类来构建新类

        当从已存在类继承时,就重用了它的方法和属性,还可以添加新的方法和属性来定制新类以应对需求

        约定:从其他类导出的类叫做子类

                        被导出的类叫父类

        在Java中,除了object类之外,所有类都是子类,都只有唯一的父类

首先先看一段c代码

这边两个结构体,一个Person结构体,一个Student结构体

发现这里面有很多重复的地方,造成了代码的浪费

如果你改成这样,逻辑上有点奇怪

那么Java就是来解决这个尴尬的问题

生活中,继承的概念随处可见

继承需要符合的关系:is-a;父类更通用更抽象、子类更特殊更具体

继承背后的思想就是        基于已存在的类来构建新类:

这是一个已存在的类

struct Person
{
    int name;
    char *address;                              
    void (*pEat)();
    void (*pDrink());
};

这是一个新类

struct Student
{
    int name;
    char *address;
    void (*pEat)();
    void (*pDrink());
    
    int score;
    void (*goToSchool)());
};

我们肯定要基于person构建student,因为person和student在代码上有重复,从我们人为的角度,学生也是一种人,

   当从已存在类继承时,就重用了它的方法和属性,还可以添加新的方法和属性来定制新类以应对需求

        约定:从其他类导出的类叫做子类

                        被导出的类叫父类

这种情况下student叫做子类,person叫做父类

    在Java中,除了object类之外,所有类都是子类,都只有唯一的父类:

那么这个object是什么呢?

比如我们以前写过的代码demo2.java里面有两个类

一个是demo2,一个是student

我们来看一下student 的父类是什么

选择student 然后在选择F4那个

会看到student的父类是一个object

然后同样的方法,我们再来看一下demo2的父类

这些类创建的时候, 没有显示继承于谁,默认都是继承object

继承在oop中不可缺

创建一个类时,总是在继承

继承的意义

        代码重用        体现不同抽象层次

父子类关系

        父类更抽象,更一般        子类更具体,更特殊

继承在oop中不可缺

创建一个类时,总是在继承

你写也是在继承,不写也是在继承,你不写就是继承object

在java语言中,用extends关键字来表示一个类继承另一个

Public   class   Teacher   extends     Person{

        //其余代码省略        

}

我么现在新建一个工程

记得新建类的时候要大写开头 

然后我们把之前的代码拿过来修改一下

下面还是没有继承的概念,一个person类,一个student 类,只是把c语言的结构体,改成java面向对象

代码运行一下

运行结果

那我们引入继承的概念是什么意思呢?

student继承于person

继承很重要的一点是代码的复用

也就是说第17行到24行,可以去掉

但是如果我们直接删掉的话

错误提示name cannot be resolved or is not a field

name不是一个普通的变量

错误提示The method eat() is undefined for the type Student

学生这个类没有eat

我们加上一个extends Person 错误就消失啦

运行一下

在修改一下

运行结果

二、Java继承之super关键字

  super关键字的特点

               super和this 关键字的特点类似:super 代表的是父类对象的引用

                当子父类的成员出现同名时,可以通过super 来区分

                子类的构造方法中,通过super关键字调用父类的构造方法 

        public class JavaTeacher extends Teacher{

                public JavaTeacher(String name,String school){

                        super(name,school);     //通过调用父类的构造方法,完成对相关字段值的初始化

        }

}

强调:当构造一个子类对象的时候一定会先先调用父类的构造方法来构造父类的对象。调用父类构造方法的语句必须是子类构造方法中的第一条指令

 super和this 关键字的特点类似:super 代表的是父类对象的引用

this 代表的是该类对象的引用

  子类的构造方法中,通过super关键字调用父类的构造方法 

                比如说我这里面 的JavaTeacher 继承于Teacher

那么JavaTeacher 的构造方法怎么写呢?如果有两个参数,那么父类也存在有两个参数的构造方法,那么通过super 调用父类的构造方法来实现Java Teacher的初始化

        public class JavaTeacher extends Teacher{

                public JavaTeacher(String name,String school){

                        super(name,school);     //通过调用父类的构造方法,完成对相关字段值的初始化

        }

}

子类的构造方法中,通过super关键字调用父类的构造方法 

我们先新建一个工程(ctrl +c    ctrl +v  复制之前的)

比如现在我们父类有一个构造方法

构造方法的作用,一般给属性赋初值

我们这样一写出问题了

Implicit super constructor Person() is undefined for default constructor. Must define an explicit constructor

也就是说构造方法,不写的话,会默认一种无参的构造方法

当你在父类写构造方法的时候(第8到11行),父类就不存在无参的

无参的构造方法什么时候才有呢?

你没有自己写构造方法,系统会自动给你做一个

解决方式有两种

子类默认没有构造方法,没写的话就会调用无参构造方法

1、public 给他提供一个无参的构造方法(第8行)

2、去调用父类的构造方法,参数是肯定需要的

错误提示第30行

Implicit super constructor Person() is undefined. Must explicitly invoke another constructor

他不认定我是个构造方法

那么如何才能正确呢?调用父类的初始化

那么如果我们this.name =name;
                        this.address =address;

可以吗?

不可以,这是他设置的一种机制

如果你父类里面存在两个有参的构造方法,你的子类的构造方法,需要去调用父类的构造方法,来初始化里面的参数

子类的构造方法中,通过super关键字调用父类的构造方法 

比如说父类的构造方法有多种

子类继承的时候,继承一种构造方法,跟父类多少种没有关系

但是可以认定的话,子类必须调用父类的构造化方法来初始化自己

你不调用父类的话,单独写39行到41行

会产生错误

Implicit super constructor Person() is undefined. Must explicitly invoke another constructor

不认定你的构造方法是存在的

所以子类只能调用父类的构造方法

当然你可以在自己的构造方法中添加一些语句,这是允许的

你去调用super 的时候,父类的构造方法也会被调用

现在person里面我们做了address 和name ,所以要传参

我们把多余 都去掉只看关于构造方法的代码

运行结果

new一个构造方法的时候,36行会被调用,学生被调用的时候,他会调用父类的,所以父类的构造方法会被打印出来,当然之前会把11行,和12行给初始化掉,紧接着打印自己的子类构造方法

我们添加点代码看看,第57行

运行结果

当子父类的成员出现同名时,可以通过super 来区分

我想加个eat,在子类这面        47,49行

然后可以调用父亲的eat        48行

子类有eat,父类有eat ,你可以调用super ,来调用父类的

函数可以这样做,基本变量也可以这样做

运行结果

三、Java继承之私有权限

对继承过来的方法和权限做一些研究

对于public 没什么好研究的,不论是子类对他的继承还是其他包里面对他的调用都是没有什么问题的

关键是私有的,假如我把address改成私有的变量        第6行private

目前还没有错,

我们在new 一个student的时候,传递的是"哪",

"哪"student           他会调用父类的student让这个地址初始化     第40行

我们再写一个函数吧         第32行  33行

通过函数的默认属性,或者公开的属性printAddr,第32行

来访问父类里面的private 这个属性   第6行

我们要研究这个private修饰的这个属性      第6行   是否会被student继承过来

如果你看到是“哪”,说明私有属性也是可以继承的

第32行到34行,第66行

运行一下

我们看到address是可以被继承过来的

那么如果把方法的权限给他改成private 呢?

马上就出现问题了

The method printAddr() from the type Person is not visible

虽然你的63行 student是继承于父类,但是对父类里面的方法是不继承的

之前我们讲封装的时候,private是只供给同一个类,作为一个属性的话,是可以访问 的到

但是作为一个方法的话,是没办法访问的

public         该类或非该类均可访问

private        只有该类可以访问

protected        该类及其子类的成员可以访问,同一个包中的类也可访问

默认                同一个包中的类可以访问

位置                        private                默认                protected                public

同一个类                             是                      是                       是                        是

同一个包内的类                   否                      是                      是                        是

不同包内的子类                否                        否                        是                        是

不同包并且不是子类            否                       否                        否                          否

属性的话,比如这面的学生,我封装了一个属性

我们在student这面做一个函数,用this 的方式访问address是访问不到的         第55行  56行

The field Person.address is not visible

虽然刚才我们的第67行的“哪”  被设置进去了,但是是通过父类的构造方式设置的

我们调用的是super 的构造方法,来对他设置的

继承的时候,你会发现私有的成员也没被student 继承过来,但为什么student 刚才既能被设置也能打印呢?因为我们构造student 是通过父类的构造方法来设置的,打印也是父类这面的printInfo设置的

相当于以前的类似的get 和set 函数的作用通过共有的函数,访问私有的属性

私有的方法还好,就是私有的属性,会造成一个错觉,我们的私有的属性也被继承过来一样

实际上父类所有私藏的东西,子类都是不知道的

私有的为什么可以这样用呢?Student s = new Student("ta","哪");

因为我们在new 的时候间接调用了构造方法,调的是父亲的构造方法,实例化的是父亲的一个对象,所以我们调用父亲的构造方法,会间接的访问到address

我们在打印的时候也是一样的,会间接访问到父亲的printInfo,会间接的打印address

如果我们改一下呢?第32行

运行结果

四、Java继承之方法重写

什么是方法重写

                方法重写是指子类可以根据需要对从父类继承来的方法进行改写,

                是多态机制的前奏

方法重写注意点

                重写方法必须和被重写方法具有相同的方法名称、参数列表和返回值

                重写方法不能比被重写方法有更严格的访问权限

                父类中的私有方法,不能被重写

                在子类重写的方法中继续调用父类被重写的方法可以通过super.函数名获取

.

.

重写方法必须和被重写方法具有相同的方法名称、参数列表和返回值:

也就是说函数的原型长得一摸一样

  重写方法不能比被重写方法有更严格的访问权限:

如果父类是一个public的方法,你去重写的public方法的时候,不能把他的权限改为私有方法,或者默认方法

父类中的私有方法,不能被重写

连我们的继承都是没有继承过来的,更别说重写了

假设你父类有一个私有方法,你写了一个方法,只有权限不一样,其他的都一样,会发生什么情况

新建一个工程

方法重写和方法重载是不一样的

方法重载:构造函数就是一种重载的方式,方法名字一样,参数列表不一样

方法重写:名字,参数列表,返回值,权限都是一样的

一个类person类,有name,有address

一个类是student类继承了person类,添加了一个属性叫score

重写方法必须和被重写方法具有相同的方法名称、参数列表和返回值

比如说我们现在把        public void printInfo(){
                                        System.out.println("name="+name);
                                            }

拿来重写

然后我们实例化一个student,无参的构造方法

运行结果

第21行  你这个参数列表属性都和  第8行   一摸一样,但是呢,他优先的调用的是子类的

能不能调用父类的呀

在子类重写的方法中继续调用父类被重写的方法可以通过super.函数名获取

可以通过super.函数名   第22行

运行结果

  重写方法不能比被重写方法有更严格的访问权限:

我把public 改成private行不行     第21行

错误提示:Cannot reduce the visibility of the inherited method from Person

不能减除可视的等级

如果我不写呢?第21行

默认也是不行的

那么如果是增加它的等级呢?

第8 行去掉public   第21行补回public

把22行去掉

如果结果你看到System.out.println("子类打印name="+name);

而不是System.out.println("name="+name);

也可以认定为方法的重写

运行一下

  父类中的私有方法,不能被重写

因为address是私有的属性,所以先不打出来        第27行

给人的感觉被重写了

可是我的student继承于person,可是这面显示不能调用

错误提示:The method printAddr() from the type Student is not visible

他这面默认这个printAddr是父亲的私有,即使你写了一个自己的私有,他也不给你用

哪怕你不写

他也认定这个printAddr是父亲的,你是不可见的

错误提示:The method printAddr() from the type Person is not visible

那么如果改成不一样的权限呢?

这个时候就可以用

因为在Java看来你的        void printAddr(){
                                                System.out.println("私有方法");
                                            }

跟父类的                private void printAddr(){
                                System.out.println("address="+address);
                                    }

根本就不是重写

因为父类私有的方法,对子类是不可见的,现在相当于添加了一个自己的方法  第26,27行

既不是重写,也不是重载,是自己添加了一个方法

运行结果

总结一下:

重写和重载的区别:

重写必须必须具有相同的方法名称、参数列表、返回值,重载只要方法名称相同就是一个重载

重写加一个public 你会发现是子类的打印        第20行

运行结果

如果把他去掉的话,他就会调用父亲的name=陈

从运行效果看,他就是重写的一种方式

重写可以增加它的访问权限,但是也不一定,记得查阅资料

运行结果

五、Java继承之Object类

    Java中, 所有类都直接或间接继承自java.lang.Object类

                        可以说Object是java中所有类祖先即根类

        Java中任何类都继承了Object类中的方法,主要有

                        toString()

                        equals()

                        hashcode()

                        clone()

                        getClass()

                        finalize()

    Java中, 所有类都直接或间接继承自java.lang.object类

                        可以说Object是java中所有类祖先即根类

我们学习Linux的时候,学习了根目录,根一般来说是最顶层的目录

那Object是根类,也就是所有类最顶层的类

  Java中任何类都继承了object类中的方法

既然是祖先的话,他的子,它的孙,它的曾孙,都包含它的一些方法

用的多的是

                          toString()

                              equals()

新建一个工程,

看看函数p.toString输出是什么

运行结果

jicheng.lizhaopeng.java.        包名

Person

@659e0bfd        地址

打印了Person的内存空间

这个to String从字面上的意思是转化为字符串

这不是我们想看到的东西,我们转化成字符串想要看到什么呢?

我们是不是可以把他的名字和属性给他打出来

我们可以用重写的技术,对这个toString来重写

默认是返回父亲的to String   第16行,第17行

我们不想让他返回父类的toSting 我们可以这样做

运行结果

默认的toStiring打印的是虚拟地址          第31行

然后我们用一下equals()         第33行

我们看到两个名字和地址是完全一样的

运行结果

有点奇怪,按照我们c语言的开发,只要字符串跟里面的某一些属性相等的话,就想要让他觉得两个结构体一样

但他这边比的还是地址

所以我们可以重写一下equals

定义一个person p 然后把arg0强转成person

我们在做一个判断

如果里面的属性的值相等的话,我们就判断这两个对象是相等的   第34行到36行    第38到40行

运行结果

在比较字符串的时候,java是比较灵活的,可以用两个等号,

我们学习c的时候用strcmp,包括给字符串赋值的时候用strcpy

String   toString()

        返回该对象的字符串描述信息。默认输出的格式:

                类名【字段值,字段值·· ···】

        只要对象与一个字符串通过“+”连接,系统就会自动调用toString获得对象的字符描述符

        常被改写:可以根据用户的需求对其进行重写

Boolean    equals()

        object类原始功能是实现判断两个对象是否具有相同的引用,要求判断两个对象状态的相等值

六、Java继承之综合小练习

新建一个工程

现在有个类要设置一下,肯定有个玩家         Play

play有什么特征呢?

昵称,        name

等级,        duanwei

id号,                id

攻击 ,        attack

武器                wapon

比如,我内部还有个武器,武器是不是要做一个武器的类

class Wapon
        {
                    String name;        //武器是不是还有名字
                    void waponAttack()        
                    {
                        System.out.println("武器攻击");
                     }
        }

玩家攻击的时候是不是调用武器攻击,武器攻击有很多种

比如k98攻击,继承它并且重写它

如果现在用我们学过的东西,不太够写,因为需要涉及到多态

运行一下

因为他会调用38行的wapon.waponAttack();

wapon并没有被赋值

那么我们p1.wapon = new Wapon();是不是就可以啦

运行结果

其实可以把    p1.wapon = new Wapon();

变成          p1.wapon = new koushui();

第49行就是我们要讲的多态的概念

运行结果

在修改一下

运行结果

这就是多态的概念          第49行        第52行

多态是在继承的基础上

我们的继承体现在武器上,继承的时候去重写里面的方法

我们给p1.wapon初始化,按照以前的写法是new Wapon,现在可以直接new koushui

因为Wapon包含了koushui 和K98,所以可以直接把你new出来的koushui 和K98的对象直接给这个wapon

七、java继承之简单工厂模式

运行结果

Java:继承之super关键字,继承之私有权限,继承之方法重写,继承之object类,继承之简单工厂模式相关推荐

  1. 简单工厂模式(Java、Python)、工厂方法模式(Java、Python)

    目录 一.试画出简单工厂模式的模式结构图,并对模式进行分析 1.1 简单工厂模式结构图: 1.2 简单工厂模式的实现(Java) 1.3 简单工厂模式的优缺点 1.4 简单工厂模式实现(Python) ...

  2. java圣经_Java设计模式圣经连载(01)-简单工厂模式[转载]

    简单工厂模式是类的创建,又叫静态工厂方法(Static Factory Methord)模式.简单工厂模式是由一个工厂对象决定创造哪一种产品类的实例. 1.1.1 工厂模式的几种形态 工厂模式专门负责 ...

  3. 简单工厂模式,工厂方法模式,抽象工厂模式总结-java版

    文章目录 LOG:更新日志 一.简单工厂模式,工厂方法模式,抽象工厂模式定义 二.三种工厂模式的优缺点以及适用场景 三.名词解释 四.简单工厂模式.工厂方法模式与抽象工厂模式之间的区别 五.抽象工厂模 ...

  4. Java设计模式(二)简单工厂模式—设计模式六大原则

    文章目录 设计模式六大原则 1. 开闭原则 2. 里氏代换原则 3. 依赖倒转原则 4. 接口隔离原则 5. 迪米特法则(最少知道原则) 6. 合成复用原则 工厂设计模式 什么是工厂模式 工厂模式的好 ...

  5. (兔C残篇)Java 面向对象的三个基本特征:继承,Super关键字的使用,this关键字的使用,super和this的区别,方法重写

    如文章标题,今天兔C残篇阐述的话题如下: 文章目录 1.什么是继承 1.1 democode 1.2 关于继承的理论知识概念 2. Super 关键字 3.this 关键字 4.this 和 supe ...

  6. 1.4 面向对象编程中级 对象的继承与super关键字-跟着韩老师学JavaSE

    大佬给推荐的韩顺平老师的课程 2021年刚刚录的船新版本! [零基础 快速学Java]韩顺平 零基础30天学会Java 硬把从另一个讲师那里看了300多集的我拽过来 几十节课一下子爱上这个节奏了!安利 ...

  7. Java 面向对象:super关键字的理解

    Java 面向对象:super关键字的理解 一.Super关键字: 1. super调用父类的构造方法,必须在构造方法的第一个 2. super只能出现在子类的方法或构造方法中! 3. super和t ...

  8. java语言之super关键字详解

    文章目录 前言 一.super介绍 二.super的语法 三.super内存图 四.super小结 前言 你第一次遇到super关键字是什么时候呢?是不是使用IDEA或者eclipse快捷键生成类构造 ...

  9. Java继承之object类、继承小练习和继承简单工厂模式

    1.object类常见方法 (1)Java中,所有类都直接或间接继承自java.lang.Object类,Object类可以说是Java中所有类的祖先即根类 (2)Java中任何类都继承了Object ...

最新文章

  1. C# - list数据填充到Dataset里
  2. 扭矩大好还是马力大好_发动机的马力重要还是扭矩重要?加速到底看哪个?
  3. 后端技术:命名不规范,lombok泪两行!
  4. Windows 如何在命令终端(CMD)使用命令来访问本地/远程的 Oracle 数据库呢?
  5. nginx https透明代理_Nginx反向代理https,配置lets-encrypt证书教程
  6. 作者:郭旦怀(1973-),男,博士,中国科学院计算机网络信息中心副研究员、硕士生导师。...
  7. Eclipse中JBOSS5.1无法启动的问题解决办法
  8. 【简讯】ISO确定C++的升级
  9. 服务器不能安装exe文件,云服务器安装exe文件
  10. Python将字符串转换为浮点数
  11. Windows 8实例教程系列 - 数据绑定高级实例
  12. Javascript特效:瀑布流
  13. iOS AutoLayout
  14. java极简使用FastFDFS文件服务器上传图片
  15. C语言题目:新胖子公式 (10 分)
  16. Git-储藏(Stashing)
  17. android开发常用工具类、高仿客户端、附近厕所、验证码助手、相机图片处理等源码
  18. OpenStack虚拟云桌面在携程呼叫中心的应用
  19. 高通 qca-wifi 移植
  20. BT源代码学习心得(八):跟踪服务器(Tracker)的代码分析(用户请求的实际处理) - 转贴自 wolfenstein (NeverSayNever)

热门文章

  1. 【leetcode】1051. Height Checker
  2. 【364天】跃迁之路——程序员高效学习方法论探索系列(实验阶段122-2018.02.04)...
  3. informatica 参数文件配置
  4. Operation category READ is not supported in state standby
  5. 1.eclipse怎么样新建web项目,eclipse新建web项目
  6. spider RPC入门指南
  7. 关于Core Data的一些整理(一)
  8. FTP linux-500 OOPS问题解决 (转载)
  9. ThinkPhp学习13
  10. Http Status 304响应状态的资源更新机制