让我们进入面向对象的世界(三)

news2025/8/2 21:56:03

文章目录

  • 前言
  • 一.了解什么是继承
  • 二.我们针对继承来设计一个动物继承树
  • 前言
    • 2.1 第一步 找出共同属性和行为的对象
    • 2.2 设计代表共同状态行为的类
    • 2.3 决定子类是否让某项行为有不同的运作方式。
    • 2.4我们仔细去观察一下子类的特征,争取更多的抽象化的机会。
  • 三.继承的相关语法
    • 3.1 父类的成员的访问
    • 3.2 子类访问父类的成员方法
    • 3.3 super关键字
  • 四.怎么去检验继承关系
  • 五.总结


前言

自从上节课我们开始进入面向对象的封装已经有一些日子了,接下来我们会进入对象村非常有意思的环节,就是继承与多态。为什么我们要去学习这些特性呢?因为这是面向对象非常的重要,还记得我们在第一次进入面向对象村举的第一个例子吗?你的老板要你和你的朋友几个不同的形状,来满足需求,这个时候我们就可以给你的朋友解释一下什么是继承了。


一.了解什么是继承

在设计类的时候,你会把共同的带啊放在某个类中,然后告诉其他的类说此类是它们的父类。当某一个类继承另一个类的时候,也就是子类继承父类的时候。
以java的方式来说,这是“子类继承父类“。继承关系意味着子类继承了父类的方法,当我们提及“类的成员”时,成员的意思就是实例变量和方法。


说了这么多,我举一个简单的例子,让你们大致的了解一下,我上面说的一堆话,到底是什么。
这是一个简单的继承的一个范例:

public class Doctor {
    boolean worksAtHopsptial;
    void treatPatient(){
        //执行检查
    }
}
public class FamilyDoctor extends Doctor{
    boolean makesHouseCalls;
    void giveAdvice(){
        //提出诊断
    }
}
public class Surgeon extends Doctor{
    void treatPatient(){
        //执行检查
    }
    void makeIncision(){
        //截肢
    }
}


在这里插入图片描述
这里面具体的例子就是,我们子类在继承父类的时候可以覆盖父类的方法,也可以增加子类自己独有的实例变量和方法,这这是一个简单例子,让大家继承的了解更清楚一些。


二.我们针对继承来设计一个动物继承树

在开始设计动物继承树之前,我们先来了解一下java继承的语法,在Java中如果要表示类之间的继承关系,需要extends关键字去来实现继承关系。具体怎么操作,跟着我去完成照这个动物继承树的例子之后,你就明白了。


前言

1.假设你要设计一个仿真系统程序,可以让用户设定将一群动物丢到某种环境中以观察会发生什么事情。现在不需要写出程序,我们只在乎设计。
2.我们已经被告知一部分会用到的动物,但是并不知道还有多少种动物会加进来。每个动物都会用一个对象来表示,且动物会在环境中活动,执行任何被设计出的行为。
3.这个程序必须能够在任何时间加入新类型的动物

2.1 第一步 找出共同属性和行为的对象

我这里列举六个动物
在这里插入图片描述大家想一想着六种动物有什么共同点在里面?
当然我已经给大家列出来了。我的答案并不是标准的。
我么可以设五个实例变量
picture:动物图像的名称
food:动物所吃得食物。现在持有meat和grass俩种值
hunger:代表饥饿程度的值,根据动物吃了多少而改变。
boundaries:动物活动的区域的长宽
location:动物活动区域的X与Y坐标。
还有四个方法:
makeNoise():动物发出的声音
eat():动物吃的行为
sleep():不同的动物的睡觉行为
roam():其他行为


2.2 设计代表共同状态行为的类

因为对象都是动物的原因,我们可以用Animal作为共同父类的名称。
并且构造图如下。
在这里插入图片描述


2.3 决定子类是否让某项行为有不同的运作方式。

这里就非常有趣了。我们想一想我们应该让子类覆盖哪些方法呢?其实按照常识来说,狮子的叫声绝对不会跟河马的叫声一样,如果你说一样,那我也没办法了,所以我们要根据不同的类型去设计不同的行为程序。
观察animal的这个类以后,我们认为eat()与makeNosie()应该由各个子类自行覆盖。


2.4我们仔细去观察一下子类的特征,争取更多的抽象化的机会。

类的继承结构已经大致成型。我们让每个子类都去覆盖掉makeNoise()与eat()这两个方法,因此狗不会瞄瞄叫、河马也不会抢狮子的食物。
但或许我们还能做更多的设计。我们必须观察Animal的子类找寻是否有可以组织归纳使用共同程序代码的部分。看起来小红帽的好朋友大野狼跟狗有共同的部分。猫、狮子与老虎也有共同的部分。
1.我们观察到Wolf与Dog可能有某些共同的行为,在Lion、Tiger、Cat之间也是。
2.相信你应该知道我们说的是什么,因为动物本来就有组织化的层次(界、门、纲、目、科、属、种),我们可以用这些层次来制作有意义的类设计。我们使用犬科和猫科动物的分类来作出Feline与Caninc这两个类。
3.我们决定Canine使用共同的roam()方法,因为它们都以相同的方式移动。Feline之间也是差不多。而Hippo则持续使用继承下来的roam()方法。

于是我们得出了下面的继承图
在这里插入图片描述

上述我们对动物继承类的构造已经完成了。大家应该明白的差不多了吧。


三.继承的相关语法

前言

3.1 父类的成员的访问

1.子类和父类不存在相同的成员变量

public class Base {
int a;
int b;
}
public class Derived extends Base{
int c;
public void method(){
a = 10; // 访问从父类中继承下来的a
b = 20; // 访问从父类中继承下来的b
c = 30; // 访问子类自己的c
}
}

2.子类和父类的成员变量相同

public class Base {
int a;
int b;
int c;
}
/
public class Derived extends Base{
int a; // 与父类中成员a同名,且类型相同
char b; // 与父类中成员b同名,但类型不同
public void method(){
a = 100; // 访问父类继承的a,还是子类自己新增的a?
b = 101; // 访问父类继承的b,还是子类自己新增的b?
c = 102; // 子类没有c,访问的肯定是从父类继承下来的c
// d = 103; // 编译失败,因为父类和子类都没有定义成员变量b
}
}

总结:
如果访问的成员变量子类中有,优先访问自己的成员变量。
如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。
如果访问的成员变量与父类中成员变量同名,则优先访问自己的。


3.2 子类访问父类的成员方法

1.成员方法名字不同

public class Base {
public void methodA(){
System.out.println("Base中的methodA()");
}
}
public class Derived extends Base{
public void methodB(){
System.out.println("Derived中的methodB()方法");
}
public void methodC(){
methodB(); // 访问子类自己的methodB()
methodA(); // 访问父类继承的methodA()
// methodD(); // 编译失败,在整个继承体系中没有发现方法methodD()
}
}
  1. 成员方法名字相同
public class Base {
public void methodA(){
System.out.println("Base中的methodA()");
}
public void methodB(){
System.out.println("Base中的methodB()");
}
}
public class Derived extends Base{
public void methodA(int a) {
System.out.println("Derived中的method(int)方法");
}
public void methodB(){
System.out.println("Derived中的methodB()方法");
}
public void methodC(){
methodA(); // 没有传参,访问父类中的methodA()
methodA(20); // 传递int参数,访问子类中的methodA(int)
methodB(); // 直接访问,则永远访问到的都是子类中的methodB(),基类的无法访问到
}
}

总结:
通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到
则访问,否则编译报错。
通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用
方法适传递的参数选择合适的方法访问,如果没有则报错;


3.3 super关键字

由于设计不好,或者因场景需要,子类和父类中可能会存在相同名称的成员,如果要在子类方法中访问父类同名成
员时,该如何操作?直接访问是无法做到的,Java提供了super关键字,该关键字主要作用:在子类方法中访问父
类的成员。

public class Base {
    int a;
    int b;
    public void methodA(){
        System.out.println("Base中的methodA()");
    }
    public void methodB(){
        System.out.println("Base中的methodB()");
    }
}

public class Derived extends Base{
    int a; // 与父类中成员变量同名且类型相同
    char b; // 与父类中成员变量同名但类型不同
    // 与父类中methodA()构成重载
    public void methodA(int a) {
        System.out.println("Derived中的method()方法");
    }
    // 与基类中methodB()构成重写(即原型一致,重写后序详细介绍)
    public void methodB(){
        System.out.println("Derived中的methodB()方法");
    }
    public void methodC(){
// 对于同名的成员变量,直接访问时,访问的都是子类的
        a = 100; // 等价于: this.a = 100;
        b = 101; // 等价于: this.b = 101;
// 注意:this是当前对象的引用
// 访问父类的成员变量时,需要借助super关键字
// super是获取到子类对象中从基类继承下来的部分
        super.a = 200;
        super.b = 201;
// 父类和子类中构成重载的方法,直接可以通过参数列表区分清访问父类还是子类方法
        methodA(); // 没有传参,访问父类中的methodA()
        methodA(20); // 传递int参数,访问子类中的methodA(int)
// 如果在子类中要访问重写的基类方法,则需要借助super关键字
        methodB(); // 直接访问,则永远访问到的都是子类中的methodA(),基类的无法访问到
        super.methodB(); // 访问基类的methodB()
    }
}


四.怎么去检验继承关系

这里其实我们当用一个类去继承另外一个类的时候,我们会去说这是子类应该去继承父类,若你想知道某物是否会去继承父类的时候,则可以用IS-A去验证。
三角形是一个多边形?
外科医生是一个医生?
狮子是一种动物?
这些都是继承关系。
要确认你的设计是否正确,使用这样的测验来加以检验。如果不合理,则表示你的设计有问题。
就比如我们洗澡的时候,浴室和澡盆有关联吧,确实是有关联,但不是继承上的关系。澡盆和浴室发生的是HAS-A的关系,如果表示浴室有澡盆的话,只能说明澡盆是浴室的实例变量,浴室里面会有一个澡盆的引用,但他们其实没有继承关系。

这一个环节到这里就结束了,哈哈,朋友,简单的对我们的继承做个总结吧。


五.总结

我们通过一个问题来总结,我们对继承的意义,这里你先别说,听我列举,然后你再去思考

1.避免了重复的代码
在单一的位置定义共同程序代码,然后让子类继承父类的程序代码。当你想要改变这个行为程序时,只需修改这个地方,而子类就会发生同样的改变。
2.定出了共同的协议
当你在父类中定义方法时,它们会被子类继承,这样你就是在对其他程序代码声明:“我所有的子类(例如说subclass)都能用这些方法来执行这几项工作……”。也就是说你拟出了一份“合约”。
我们提出动物继承关系的Animal这个类拟出所有动物子型的共同协议。

朋友们,今天到这里就结束了,我们还没有讨论最精彩的部分,就是多态,这里留到下一部分,我们再讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/34986.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

leetcode:887. 鸡蛋掉落【经典dp定义】

目录题目截图题目分析ac code总结题目截图 题目分析 变量:鸡蛋的数量,楼层n,尝试的次数m有一个单调性容易发现:尝试的次数越多,能解决楼层越高的确切值另一个单调性:鸡蛋的数量越多,能够解决楼…

Flutter 实现局部刷新 StreamBuilder 实例详解

一、前言 在flutter项目中,页面内直接调用setState方法会使得页面重新执行build方法,导致内部组件被全量刷新,造成不必要的性能消耗。出于性能和用户体验方面的考虑我们经常会使用局部刷新代替全量刷新进行页面更新的操作。包括Provider、Va…

制造业企业如何高效进行生产计划排单?

随着社会的发展,个性化订单需求越来越多。面对如今更加多样化、紧迫化、随机化的订单,企业必须采用科学合理的方式和手段对生产计划进行控制,以提高企业的经济效益。生产计划在实施的过程中,由于一些原因,往往造成实施…

Node.js 模块化及npm概念介绍

文章目录模块化1 模块化的基本概念1.1 什么是模块化1.2 模块化规范2 Nodejs中的模块化2.1 Nodejs中模块的分类2.2 加载模块2.3 模块的作用域2.4 向外共享模块作用域中的成员2.4.1 module对象2.4.2 module.export对象2.4.3 共享成员时的注意点2.4.4 exports对象2.4.5 exportshe …

栈和队列及其多种接口实现-c语言

今天我们来完成栈和队列,首先我们要明白什么是栈,什么是队列。 目录 栈的选择 栈的结构 栈的初始化 栈的销毁 入栈 出栈 返回栈顶元素 计算数据个数 判断是否为空 队列的选择 队列的结构 入队列 出队列 判断是否为空 取队头元素 取队尾…

Java Spring Bean的生命周期 三级缓存

Java Spring Bean的生命周期 三级缓存 SpringBean的生命周期:是从 Bean 实例化之后(即通过反射创建出对象之后),到Bean成为一个完整对象,最终存储到单例池中,这个过程被称为Spring Bean的生命周期。Spring…

盘一盘那些年我们使用的Java

一、序 那些年我们使用过的Java版本。我是一个80后,当年在大学时代使用的是Java5,当时是大三的时候学校有了编程课,最开始学的是汇编语言、VB、C然后再是Java。当时就是Java5,搞了个课程设计与顺便也参加了个校园程序设计大赛。当…

MCE | Nrf2 的“戏精”之路

外界刺激 (如药物、紫外线和电离辐射) 和内源性自由基和活性氧 (ROS) 会直接或者间接地损伤蛋白质、脂质和 DNA 等细胞成分,为了抵御这些不利影响,机体形成了一套复杂的氧化应激应答系统来缓解细胞所受的损害。而 Nrf2,作为调控抗氧化应激的一…

SAP ABAP Function Module 的动态调用方式使用方式介绍试读版

在本教程前面的步骤 7,我们介绍了 ABAP Function Module 的基本使用方法: 7. ABAP function module 的使用 最近我的知识星球有朋友提问: 大佬,我想问一下动态获取到物料主数据的字段名之后,如何将获取到的字段名去与…

01. Docker的基本介绍

Docker概述? Docker 是一个开源的应用容器引擎,基于Go语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。 容器…

1网络模型

网络层次可划分为五层因特网协议栈和七层因特网协议栈 五层 互联网分层 物理层 发送端:链路层给的bit把他变成信号,什么电磁波的信号通过介质传出去 接收端:把物理信号还原为原来的数据01010110这种 传的是比特 链路层 网卡:有…

力扣 112. 路径总和

力扣 112. 路径总和 题目 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。…

[附源码]java毕业设计医院挂号系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

css解决uniapp使用image标签图片无法撑满全屏问题

css解决uniapp使用image标签图片无法撑满全屏问题 文章目录css解决uniapp使用image标签图片无法撑满全屏问题前言一、问题还原二、问题解决1、在解决问题之前有必要先来学习一个css的属性2、问题的原因3、解决问题总结前言 本片文章主要讲解了如何解决,开发中遇到需…

RTL8380M管理型交换机系统软件操作指南三:VLAN

接下来对管理型交换机的VLAN部分进行详细的描述,主要包括以下七部分内容: VLAN概述、VLAN优点、VID概念、PVID、端口处理报文方式、基础配置、VLAN端口配置一 VLAN概述 VLAN(Virtual Local Area Network)的中文名为“虚拟局域网”…

数仓之范式

学习目录一、基本概念二、函数依赖三、三范式区别一、基本概念 定义:范式是指数据建模中必须遵守一定的规则 目的:降低数据的冗余性 缺点:获取数据时,需要通过Join拼接出最后的数据 分类:第一范式(1NF)、第二范式(…

大数据可视化之医疗大数据平台

一 项目背景 随着信立泰企业的不断发展,公司管理的需求倒逼业务系统不断引入。经营数据的不断积累使得企业的信息化成为企业进行技术改造及提高企业管理水平的重要手段。信立泰因之而制定了对应的信息化战略,主要任务是最大限度的利用医疗大数据平台加強…

基于java的购物中心商铺管理系统的设计与实现/商铺管理系统

摘 要 随着社会的发展,计算机的优势和普及使得购物中心商铺管理系统的开发成为必需。购物中心商铺管理系统主要是借助计算机,通过对信息进行管理。减少管理员的工作,同时也方便广大用户对个人所需信息的及时查询,其次是大量信息的…

Python:语法进阶

目录 一、运算符 基本运算符 比较运算符 赋值运算符 多变量赋值 逻辑运算符 三元运算符 源码&运行结果 test01 案列 效果 二、循环语句 一、运算符 基本运算符 比较运算符 赋值运算符 多变量赋值 a, b, c 1, 2, 3 # a b c 3 print(b, c) 逻辑运算符 三元运…

docker (五) (搭建MySQL数据库集群)

MySQL集群搭建我们通过PXC【Percona XtraDB Cluster】来实现强一致性数据库集群搭建。 一 Percona XtraDB Cluster (理论) 1 简介 Percona XtraDB Cluster是MySQL高可用性和可扩展性的解决方案,Percona XtraDB Cluster提供的特性如下&…