面向对象编程的三大特性详解

2023-11-10

封装、多态和继承是面向对象编程的三大特性。

封装(Encapsulation)

封装的目的是为了保证变量的安全性,使用者不必在意具体实现细节,而只是通过外部接口即可访问类的成员

如果不进行封装,类中的实例变量可以直接查看和修改,可能给整个代码带来不好的影响

因此在编写类时一般将成员变量私有化,外部类需要同getter和setter方法来查看和设置变量

继承(Inherit)

继承实际上也是为了提高代码的复用性和可扩展性在定义不同类的时候存在一些相同属性,为了方便使用可以将这些共同属性抽象成一个父类,在定义其他子类时可以继承自该父类,减少代码的重复定义,子类可以使用父类中非私有的成员

定义继承的格式如下:

​ class 子类 extends 父类 { }

可以用以下例子表示:

public class Fu {
    public void show() {
        System.out.println("父类中的show方法被调用");
    }
    public void method() {
        System.out.println("父类中的method方法被调用");
    }
}
public class Zi extends Fu {
    @override
    public void method() {
        System.out.println("子类中的method方法被调用");
    }
}
public class Demo {
    public static void main(String[] args) {
        //创建对象,调用方法
        Fu f = new Fu();
        f.show(); // 父类中的show方法被调用

        Zi z = new Zi();
        z.method(); // 子类中的show方法被调用
        z.show(); // 父类中的show方法被调用
    }
}

在以上代码中,Zi继承自Fu,在Zi类中重写了Fu类中的method方法,Zi类在执行method方法时执行的是重写的方法,在执行show方法时执行的是Fu类中的方法。由此可得:如果子类对父类中方法进行了重写,子类在调用该方法时执行的是重写后的方法。

除此之外,子类中还可以定义新的变量和方法

在这里插入图片描述

在使用继承关系时,不仅是单层继承,一般会形成一个层次关系明显的继承树,以定义狼来说,其父类可以有犬类和动物类,下图用一个稍微复杂一点的例子显示了他们之间的关系,在Java API中,大部分的继承关系都不会超过三层

在这里插入图片描述

继承中需要注意:

  • 父类可以不知道他有哪些子类,但是子类必须明确他有哪些父类

  • 子类在重写父类时,如果想在父类功能基础上增加新的功能,可以用super实现,如:

    •   public void roam(){
            // 父类中的方法
            super.roam();
            // 新增的行为
            new stuff;
        }
      
  • 不能作为继承的子类:

    • 存取控制
    • 使用final修饰符,防止父类方法被重写一般就是添加final修饰符
    • 只有private构造方法
  • 子类的参数的个数和类型要和父类完全一致,返回类型要兼容

  • 子类中方法的存取权限只能改为更低,不能高于父类中方法的存取权限

多态(Polymorphism)

在这里插入图片描述

多态指的是同一个对象可以表现出多种形态,通俗来说就是一个对象的引用类型既可以是实际类也可以是实际类的父类。

下面一个代码实例可以直观表示

public class Animal {
    public int age = 40;

    public void eat() {
        System.out.println("动物吃东西");
    }
}
public class Cat extends Animal {
    public int age = 20;
    public int weight = 10;

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    public void playGame() {
        System.out.println("猫捉迷藏");
    }
}
public class AnimalDemo {
    public static void main(String[] args) {
        //有父类引用指向子类对象,向上转型
        Animal a = new Cat();
        Cat c = new Cat();

        System.out.println(a.age); // 40
        a.eat; // 猫吃鱼
        // 向下转型
        Cat t = (Cat) a;
		System.out.println(t.age); // 20
        System.out.println(t.weight); // 10

        System.out.println(c.age); // 20
        System.out.println(a.weight); // 10

    }
}

以上代码还涉及到了多态中的向上转型和向下转型问题,Animal a = new Cat();是一种向上转型,相当于定义了一个Animal类型的引用变量a指向一个Cat类的对象,Cat t = (Cat) a是向下转型,将Animal类型的引用比那里a传给了Cat类型的引用变量t,两者在成员变量和成员方法上的调用有所区别:

  • 成员变量的调用
    • a调用的成员变量都是Animal中的成员变量
    • t调用的成员变量都是Cat中的成员变量
  • 成员方法的调用
    • a在调用成员方法时只能调用Animal中的声明过的成员方法,如果a对Animal中声明的方法进行重写,那调用的是重写后的方法,如果没有,调用的是Animal中的方法
    • t在调用成员方法时调用的都是Cat中的成员方法

接口和抽象类中的Object介绍中也给出了向上转型和向下转型的图释,编译器根据引用类型来判断哪些方法可以调用

在这里插入图片描述

此外,多态还可以应用到参数和返回类型中,如下代码

class Vet{
    public void giveShot(Animal a){
        a.makeNoise();
    }
}
class PetOwner{
    public void start(){
        Vet v = new Ver();
        Dog d = new Dog();
        Hippo h = new Hippo();
        v.getShot(d); //调用Dog类中的makeNoise方法
        v.getShot(h); //调用Hippo类中的makeNoise方法
    }
}

方法重写(override)和重载(overload)的区别

方法重载:方法重载指的是同一个类中定义多个同名方法,这些同名方法的参数个数和类型不同,返回类型和存取权限可以不同

方法重写:方法重写指的是有继承关系的子类继承父类中的方法并定义不同的方法体,子类和父类中的方法名和参数个数类型要完全一样,是一种覆盖。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

面向对象编程的三大特性详解 的相关文章

  • 如何编写 Maven 构建脚本来执行 Java

    如何在构建过程中或构建刚刚完成后执行 Java 程序 可以直接从 pom 中执行此操作吗 mvn exec java Dexec mainClass org sonatype mavenbook weather Main EDIT 假设我想
  • 从txt文件中读取数据而不下载它?

    我想从提供的文本文件中解析信息 有没有一种方法可以在应用程序中执行此操作 而无需先下载文件 以某种方式传输文本内容 打开到 URL 的 Http 连接 使用内置 HttpURLConnection 或使用 commons httpclien
  • 在Java Servlet中获取通过jquery ajax发送的参数[重复]

    这个问题在这里已经有答案了 我在网上搜索这个主题 但找不到有效的示例 我会很高兴有人能给我帮助 这就是我测试的 ajax url GetJson type POST dataType json contentType application
  • IBM Websphere MQ - 用于 Tomcat 部署的 EJB 和 MDB 迁移

    我已经为此苦苦挣扎了很长一段时间 我有一个 IBM Websphere MQ 它使用 EJB 和 MDB 以下是配置ejb mdb的地方
  • 从 Android 函数更新 Textview

    有人可以告诉我如何从函数更新 Android Textview 控件吗 我在互联网上进行了深入搜索 看到很多人都问同样的问题 我测试了线程但无法工作 有人有一个简单的工作示例吗 例如 调用一个函数 在循环中运行多次 并且该函数在 TextV
  • openFileOutput 在单例类中无法正常工作 - 想法/解决方法?

    作为一名 Android 开发新手 我遇到了一些奇怪的问题 我想创建一个类 它方法其他类 活动 任何可以用于以某种特殊方式处理文件的类 假设为了简单起见 我们将记录一些内容 如果我在活动中执行以下操作 例如在 OnClick 侦听器中 则一
  • Java 错误和警告列表

    在哪里 如何获得所有 java 和 javac 的错误和警告消息的列表 This http mindprod com jgloss compileerrormessages html我认为页面是您所需要的
  • java中高效的输入流到字符串方法

    因此 我在 Java 中的 诚然非常简单 应用程序上运行探查器 令我惊讶的是 仅次于需要在时间上发出 HTTP 请求的方法的是我的方法 inputStreamToString方法 目前它的定义如下 public static String
  • 当我们使用赋值而不是比较时,如何评估 if/while 条件?

    我在学习 Java 的 OCA OCP 时发现了这个令人惊讶的事情 下面是第一段代码 其中 if 测试条件 部分 让我惊讶 public class BooleanIf public static void main String args
  • Google 表格使用 API 密钥而不是 client_secret.json

    In the QuickStart java示例Java 快速入门 https developers google com sheets api quickstart java他们使用OAuth client ID识别该应用程序 这会弹出一
  • 使用正则表达式验证电子邮件的最大长度

    我找到了用于电子邮件验证的正则表达式 a z0 9 a z0 9 a z0 9 a z0 9 a z 2 4 我希望电子邮件的最大长度为 20 个字符 因此我将其更改为 a z0 9 a z0 9 a z0 9 a z0 9 a z 2 4
  • java:为什么主线程等待子线程完成

    我有一个简单的java程序 主线程 main 创建并启动另一个线程t class T extends Thread Override public void run while true System out println Inside
  • 获取接收者的设备令牌以在 Firebase 中发送通知

    所以我正在学习如何使用 firebase 发送设备到设备的通知 我看到了这个answer https stackoverflow com a 42548586 5237289发送通知 看起来很简单 现在 我知道要获取发件人的令牌 它应该如下
  • Java 8:如何创建毫秒、微秒或纳秒的 DateTimeFormatter?

    我需要创建格式化程序来解析具有可选的毫秒 微米或纳秒分数的时间戳 例如 对于我的需求 我看到以下机会 DateTimeFormatter formatter new DateTimeFormatterBuilder append DateT
  • 在 Tensorflow-lite Android 中将位图转换为 ByteBuffer(浮点)

    在用于图像分类的tensorflow lite android演示代码中 图像首先转换为ByteBuffer格式以获得更好的性能 这种从位图到浮点格式的转换以及随后到字节缓冲区的转换似乎是一个昂贵的操作 循环 按位运算符 float mem
  • 在 Spring MVC 中将请求写入文件

    我希望能够将整个请求写入 Spring MVC 控制器中的文件 我已尝试以下操作 但即使我使用大量参数发出 POST 请求 文件也始终为空 RequestMapping method RequestMethod POST value pay
  • 使用 Hibernate Envers 的复合表

    我有一个带有复合表的应用程序 其中包含一个额外的列 一切正常 直到我们添加 Hibernate Envers Audited org hibernate MappingException 无法读取 no pack response Resp
  • junit4 使用特定测试方法创建测试套件

    在 junit4 中 我想执行来自不同类的特定测试方法 即想要使用来自不同类的特定测试方法创建一个测试套件 假设我有两门课 public class Test Login Test public void test Login 001 Sy
  • 假布尔值=真?

    我在一本书中找到了这段代码 并在 Netbeans 中执行了它 boolean b false if b true System out println true else System out println false 我只是不明白为什
  • FetchType.LAZY 不适用于休眠中的 @ManyToOne 映射

    简而言之 我的 Child 类与 Parent 类之间存在多对一的关系 我想加载所有的孩子 而不必加载他们的父母详细信息 我的孩子班级是 Entity public class Child implements Serializable I

随机推荐

  • Pandas数据的导入与导出

    Excel格式数据导入 文件格式 读取方法 Excel文件 read excel CSV文件 read csv txt文件 read table Json文件 read json MySQL文件 read sql table 对于上述这些方
  • 圆形电子围栏检测嵌入式C实现

    js代码 fileoverview GeoUtils类提供若干几何算法 用来帮助用户判断点与矩形 圆形 多边形线 多边形面的关系 并提供计算折线长度和多边形的面积的公式 主入口类是 a href symbols BMapLib GeoUti
  • linux修改时区 修正时间

    1 tzselect 2 选择Asia 3 选择china 4 选择beijing 5 最后执行TZ Asia Shanghai export TZ 6 重启
  • html弹窗口并获取返回值,Js 弹出框口并返回值的两种常用方法

    1 window showModalDialog url args dialogattrs 参数说明 url 弹出页面地址 agrs 主窗口传给对话框的参数 可以是任意类型 数组也可以 dialogattrs 弹出窗口的样式参数 模式对话框
  • 【面试精讲】Java:Exception 和 Error 有什么区别?

    前言 众所周知 没有 BUG 的程序只会出现在程序员的梦里 异常情况如影随形地纠缠着我们 只有正确处理好意外情况 才能保证程序的可靠性 Java 语言在设计之初就提供了相对完善的异常处理机制 这也是 Java 得以大行其道的原因之一 因为这
  • NVIDIA GPU 算力表

    来自nvidia官方 https developer nvidia com cuda gpus
  • 线程同步

    线程同步 作者 buaawhl 我们可以在计算机上运行各种计算机软件程序 每一个运行的程序可能包括多个独立运行的线程 Thread 线程 Thread 是一份独立运行的程序 有自己专用的运行栈 线程有可能和其他线程共享一些资源 比如 内存
  • Selenium系列教程 - 文件上传

    主要内容 一 通过send keys方法 该方法只适用于input标签 二 通过AutoIt来处理上传文件 适用所有 三 其他方法 四 多文件上传 在Web UI自动化测试中可能会遇到文件上传的场景 针对该场景我们要区分上传按钮的种类 大体
  • 第四周作业

    实验作业 1 完成课本每一个编程题 要求先画出流程算法图或N S图 然后编程实现 有可能的话使用两种以上方法 2 编程求 百钱百鸡 问题 鸡翁一值钱五 鸡母 一值钱三 鸡雏三值钱一 百钱买百鸡 问鸡翁 鸡母 鸡雏各几何 3 编程输入一个整数
  • centos7下boot空间不足解决办法

    root localhost admin rpm qa grep kernel 看下有哪些 然后用yum remove kernel devel 3 10 0 327 el7 x86 64 删除
  • 创建Numpy数组(zeros()、ones()、empty()、arange())

    创建Numpy数组 zeros 创建出来的数组里边的元素都是0 例如 data01 np zeros 3 4 print data01 ones 创建出来的数组里边的元素都是1 例如 data02 np ones 3 4 print dat
  • 前端通过spark-md5.js计算本地文件md5

    背景 说到本人第一次使用spark md5 js还是差不多一年以前的时候了 当时后台老大说要搞一个文件分片上传的功能 我当时就心想 what 啥是文件分片上传 完全没听过好吗 至于我当时内心那个慌就不多描述了 总之文件分片上传需要一个识别文
  • Leetcode--Java--377. 组合总和 Ⅳ

    题目描述 给你一个由 不同 整数组成的数组 nums 和一个目标整数 target 请你从 nums 中找出并返回总和为 target 的元素组合的个数 题目数据保证答案符合 32 位整数范围 样例描述 示例 1 输入 nums 1 2 3
  • LeetCode(Python)—— 两数之和(简单)

    两数之和 概述 给定一个整数数组 nums 和一个整数目标值 target 请你在该数组中找出和为目标值 target 的那两个整数 并返回它们的数组下标 你可以假设每种输入只会对应一个答案 但是 数组中同一个元素在答案里不能重复出现 你可
  • 在广告宣传领域,PS透明屏有哪些优点表现?

    PS透明屏是一种新型的显示技术 它将传统的显示屏幕与透明材料相结合 使得屏幕能够同时显示图像和透过屏幕看到背后的物体 这种技术在商业展示 广告宣传 产品展示等领域有着广泛的应用前景 PS透明屏的工作原理是利用透明材料的特性 通过控制屏幕上的
  • C程序在内存中的布局与常见的漏洞

    1 C程序员通用的漏洞指南 C语言中大多数漏洞都与缓冲区溢出和字符串操作相关 在大多数情况下 都会导致段错误 segmentation fault 但仅过精心设计的输入值 但是 根据体系结构和环境特别设计的恶意输入值可能会导致任意代码的执行
  • UDP/TCP 通信中 server端ip为0的问题

    在UDP或TCP通信中 客户端也可以不需要bind自身IP和端口号 而服务器需要bind自身IP地址和端口号 看代码时候发现在UDP TCP通信中 server端本地信息初始化时ip设置为0了 如上图两个部分代码所示 查了一些资料 INAD
  • [Go版]算法通关村第二关青铜——终于学会链表反转了

    目录 题目 反转链表 解决方法 方法1 借助虚拟头节点反转 方法2 不借助虚拟头节点 仅靠自身反转 方法3 利用递归来反转 题目 反转链表 题目链接 LeetCode 206 反转链表 解决方法 源码地址 GitHub golang版本 方
  • CentOS7.5 搭建ElasticSearch6.4.2 + Kibana6.4.2 环境

    本文目录 1 创建用户 2 授权sudo 3 下载ElasticSearch Kibana 3 1 创建目录 3 2 下载文件 4 配置Elasticsearch 5 配置Kibana 参考资料 看下CentOS版本 root test h
  • 面向对象编程的三大特性详解

    封装 多态和继承是面向对象编程的三大特性 封装 Encapsulation 封装的目的是为了保证变量的安全性 使用者不必在意具体实现细节 而只是通过外部接口即可访问类的成员 如果不进行封装 类中的实例变量可以直接查看和修改 可能给整个代码带