浅谈对于封装、继承与多态的理解(Java)

news2024/9/29 18:13:47

目录

封装

继承

父类成员的访问 

如何在子类中访问父类同名的成员 

子类构造方法 

代码块在继承上的执行顺序

多态

多态的实现条件

重写 

多态的优缺点


面向对象程序的三大特征:封装继承和多态。

封装

· 封装:将数据和操作数据的方法进行有效的结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互

Java主要通过类和访问权限来实现封装,类可以将数据以及封装数据的方法结合在一起,而访问权限用来控制方法或者字段是否能在类外使用。

访问权限限定符有四个:public、protected、private、default(默认权限)

 

继承

面向对象思想中提出了继承的概念,专门用来提取代码的共用性,实现代码复用。继承允许程序员在保持原有类特性的基础上进行扩展,添加新的功能,这样产生新的类称为派生类。继承主要解决的问题就是共性的抽取,实现代码的复用。

继承的语法

修饰符 class 子类 extends 父类 {

}

代码示例 

父类Animal.java

public class Animal {
    public String name;
    public int age;
    public void eat() {
        System.out.println(this.name + "吃饭");
    }
    public void sleep() {
        System.out.println(this.name + "睡觉");
    }
}

子类Cat.java 

public class Cat extends Animal {
    public void mew() {
        System.out.println(this.name + "~喵");
    }
}

子类会将父类的成员方法和变量继承到子类中,子类继承父类后需要添加自己特有的成员变量和方法。

父类成员的访问 

· 当父类和子类不存在同名变量时,子类可以任意访问父类的成员变量。

public class Base {
    int a;
    int b;
}
class Derived extends Base {
    int c;
    public void method() {
        a = 10;//访问从父类继承下来的
        b = 20;//访问从父类继承下来的
        c = 30;//访问子类自己的c
        System.out.println("a = " + a + ", b = " + b + ", c = " + c);
    }
}
class Test {
    public static void main(String[] args) {
        Derived derived = new Derived();
        derived.method();
    }
}

· 子类和父类存在同名变量

public class Base {
    int a;
    int b;
    int c;
}
class Derived extends Base {
    int a;//与父类的成员变量名相同,且类型相同
    char b;//与父类中成员变量名相同,但类型不同
    public void method() {
        a = 10;//优先访问自己的
        b = 101;//优先访问自己的
        c = 30;//子类中未定义c,访问从父类继承下来的
        System.out.println("a = " + a + ", b = " + b + ", c = " + c);
    }
}
class Test {
    public static void main(String[] args) {
        Derived derived = new Derived();
        derived.method();
    }
}

在子类方法中或者通过子类对象访问成员时 

· 如果访问的成员变量子类中有,优先访问子类的成员变量

· 如果访问的成员变量子类中没有,访问从父类继承的,如果父类也未定义,则编译报错

· 如果访问的成员变量与父类的成员变量名称相同,优先访问子类的,即子类将父类的同名变量隐藏了

· 在子类中访问父类的成员方法时

· 当成员方法不同名时,优先访问自己的,如果子类中没有,就去父类中找,如果父类中也没有就报错

· 当成员方法同名时:

通过子类对象访问父类和子类同名的方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用方法时传递的参数选择合适的方法访问,如果没有报错;如果父类和子类同名方法原型一致(重写),则只能访问到子类的,父类的无法通过子类对象直接访问到

如何在子类中访问父类同名的成员 

使用super关键字,super关键字的作用就是在子类中访问父类中的与子类同名的成员

例如:

public class Base1 {
    int a = 10;
    public void method() {
        System.out.println("父类同名方法");
    }
}
class Derived1 extends Base1 {
    int a = 20;
    public void method() {
        System.out.println("子类同名方法");
    }
    public void superMethod() {
        System.out.println(super.a);
        super.method();
    }
}
class Test1 {
    public static void main(String[] args) {
        Derived1 d = new Derived1();
        d.superMethod();
    }
}

注意事项:super只能在非静态方法中使用;在子类方法中,访问父类的成员变量

子类构造方法 

在构造子类对象时,先执行父类的构造方法,然后再执行子类的构造方法。因为子类对象是一个父类对象,在构造子类对象时,先要将父类继承下来的成员初始化完整,然后再初始化子类自己新添加的成员

注意事项

1、如果父类定义了无参或者默认的构造方法,在子类构造方法第一行会默认有隐含的super()调用,用来调用父类的构造方法

2、如果父类的构造方法带有参数,此时编译器不会再给子类生成默认的构造方法,就需要coder为子类显示的定义构造方法,并在子类构造方法中选择合适的父类构造方法调用

3、在子类构造方法中,super(...)调用父类构造时,必须是子类构造函数的第一条语句

4、super(...)只能在子类构造方法中出现一次,且不能和this同时出现 

public class Base2 {
    String name;
    int age;
    public Base2() {
        System.out.println("Base2()");
    }
}
class Derived2 extends Base2 {
    public Derived2() {
        System.out.println("Derived2()");
    }
}
class Test2 {
    public static void main(String[] args) {
        Derived2 derived2 = new Derived2();
    }
}

 先执行父类的构造方法,再执行子类的

如果基类的构造方法带有参数,那么在子类中需要使用super(...)调用父类的构造方法

 

在子类使用了super后,可以额外定义自己的构造方法

代码块在继承上的执行顺序

通过下述代码来观察代码块在继承上的执行顺序

public class Person {
    public String name;
    public int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("Person: 构造方法执行");
    }
    {
        System.out.println("Person: 普通代码块执行");
    }
    static {
        System.out.println("Person: 静态代码块执行");
    }
}
class Student extends Person {
    public Student(String name, int age) {
        super(name, age);
        System.out.println("Student: 构造方法执行");
    }
    {
        System.out.println("Student: 普通代码块执行");
    }
    static {
        System.out.println("Student: 静态代码块执行");
    }
}
class Test3 {
    public static void main(String[] args) {
        Student student = new Student("小明", 10);
        System.out.println("============================");
        Student student1 = new Student("小光", 15);
    }
}

 

通过观察,可以总结出

1、静态代码块无论子类还是父类都是优先初始化的,且父类先初始化再初始化子类,且只初始化一次

2、 普通代码块优先于构造方法执行,且父类的先执行,执行完后再执行子类的

多态

通俗的说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时产生不同的状态

多态的实现条件

在Java中要实现多态,必须要满足以下几个条件:

1、必须在继承的体系下

2、子类必须要对父类中的方法进行重写

3、通过父类的引用调用重写的方法

多态的体现,在代码运行时,当传递不同的对象时,会调用对应类中的方法

public class Animal2 {
    String name;
    int age;
    public Animal2(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void eat() {
        System.out.println(name + "吃饭");
    }
}
class Cat2 extends Animal2 {
    public Cat2(String name, int age) {
        super(name, age);
    }
    @Override
    public void eat() {
        System.out.println(name + "吃鱼");
    }
}
class Dog extends Animal2 {
    public Dog(String name, int age) {
        super(name, age);
    }
    @Override
    public void eat() {
        System.out.println(name + "吃骨头");
    }
}
class TestAnimal {
    public static void eat(Animal2 a) {
        a.eat();
    }
    public static void main(String[] args) {
        Cat2 cat = new Cat2("喵", 10);
        Dog dog = new Dog("茶杯犬", 5);
        eat(cat);
        eat(dog);
    }
}

在编写eat方法时,参数类型为Animal(父类),此时该方法内部并不知道也不关注当前的a指向的是哪个子类的实例,此时a这个引用调用eat方法可能会有多种不同形式的表现(和a引用的实例相关),这种行为就称为多态。

重写 

也称为覆盖,重写是子类对父类非静态、非private、非final修饰、非构造方法等的实现过程进行重新编写,返回值和形参都不能变,也就是外壳不变,重写核心,重写的好处在于子类可以根据需要,定义特定于自己的行为。

方法重写的规则

1、子类在重写父类方法时,一般必须与父类方法原型一致:修饰符、返回值类型、方法名、参数列表要完全一致

2、JDK1.7以后,被重写的方法返回值类型可以不同,但是必须具有父子关系

3、访问权限不能比父类方法的访问权限低

4、父类中被static、private修饰的方法、构造方法都不能重写

5、子类和父类在同一个包中,则子类可以重写父类的所有方法,除了声明为private和final的方法

6、子类和父类不在同一个包中,那么子类只能够重写父类声明为public和protected的非final方法

多态的优缺点

1、能够降低代码的“圈复杂度”,避免使用大量的if-else语句

2、可扩展能力强,如果要新加一种状态,使用多态的方式代码改动成本较低

3、多态的缺点是运行效率较低

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

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

相关文章

前置知识-辛几何与辛代数、欧式几何与辛几何、Hamilton量

1.3 Hamilton 系统的辛几何算法 1.3.1 辛几何与辛代数的基本概念(下篇) 定义(辛空间、辛映射) 设 V V V 是定义在实数域 R \mathbb{R} R<

【万能排序之qsort、b_sort 、s_sort】

文章目录前言:star:qsort函数函数参数qsort函数的使用:star:模拟实现万冒泡排序函数参数模拟实现b_sort注意点:star:模拟实现万能选择排序函数参数模拟实现s_sort最后前言 我们所熟悉的冒泡排序&#xff0c;选择排序&#xff0c;插入排序&#xff0c;二分排序等都是基于给定的一…

计算机网络笔记、面试八股(一)——TCP/IP网络模型

Note&#xff1a;【计算机网络笔记、面试八股】系列文章共计5篇&#xff0c;现已更新3篇&#xff0c;剩余2篇&#xff08;TCP连接、Web响应&#xff09;会尽快更新&#xff0c;敬请期待&#xff01; 本章目录1. TCP/IP网络模型1.1 应用层1.1.1 应用层作用1.1.2 应用层有哪些常用…

git push origin master 情况

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3;哈喽&#xff01;大家好&#xff0c;我是「奇点」&#xff0c;江湖人称 singularity。刚工作几年&#xff0c;想和大家一同进步&#x1f91d;&#x1f91d;一位上进心十足的【Java ToB端大厂领…

局域网内浏览器实现远程控制windows设备的解决方案

使用VNC技术实现的局域网内windows远程桌面项目用途服务端的技术实现1. 安装UItraVNC软件&#xff0c;只部署server端即可2. 为UItraVNC设定自定义密码Python 环境的安装Websockify 的使用使用nssm工具将run.bat注册为系统服务&#xff0c;并开机自启结束&#xff0c;这里就是服…

华为OD机试用Python实现 -【查找树中的元素 or 查找二叉树节点】(2023-Q1 新题)

华为OD机试题 华为OD机试300题大纲查找树中的元素 or 查找二叉树节点题目描述输入描述输出描述说明示例一输入输出示例二输入输出Python 代码实现代码编写思路华为OD机试300题大纲 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 O…

啊哈 算法读书笔记 第 2 章 栈、队列、链表

第 2 章 栈、队列、链表 目录 第 2 章 栈、队列、链表 队列&#xff1a; 解密回文——栈 纸牌游戏&#xff1a; 链表 模拟链表 队列&#xff1a; 首先将第 1 个数删除&#xff0c;紧接着将第 2 个数放到这串数的末尾&#xff0c;再将第 3 个数删除并将第 4 个数放到这串…

axios 中如何取消请求_从使用到原理_番茄出品

start 最近频繁遇到一个问题&#xff0c;axios 是如何取消请求的&#xff1f;这篇文章将从新手小白的视角出发&#xff0c;从 axios 取消逻辑的基础使用&#xff0c;到原理分析&#xff0c;带你彻底了解并掌握 axios 中取消请求的“秘密”。编写时间&#xff1a;2023/02/24-23…

Prometheus -- 浅谈Exporter

Prometheus系统 – Exporter原理 为什么我们需要Exporter&#xff1f; 广义上讲所有可以向Prometheus提供监控样本数据的程序都可以被称为一个Exporter。而Exporter的一个实例称为target&#xff0c;如下所示&#xff0c;Prometheus通过轮询的方式定期从这些target中获取样本…

你知道Java架构师学习路线该怎么走吗?你所缺少的是学习方法以及完整规划!

怎么成为一名Java架构师&#xff1f;都需要掌握哪些技术&#xff1f;Java架构师&#xff0c;首先要是一个高级Java攻城狮&#xff0c;熟练使用各种框架&#xff0c;并知道它们实现的原理。jvm虚拟机原理、调优&#xff0c;懂得jvm能让你写出性能更好的代码;池技术&#xff0c;什…

java 面向对象三大特性之多态 万字详解(超详细)

目录 前言 : 一、为什么需要多态 : 1.白璧微瑕 : 2.举栗&#xff08;请甘雨,刻晴,钟离吃饭&#xff09;: 3.代码 : 4.问题 : 二、什么是多态 : 1.定义 : 2.多态的实现步骤&#xff08;重要&#xff09; : 三、多态的使用 : 1.多态中成员方法的使用&#xff08;重要…

一块GPU搞定ChatGPT;ML系统入坑指南;理解GPU底层架构

1. 跑ChatGPT体量模型&#xff0c;从此只需一块GPU 在发展技术&#xff0c;让大模型掌握更多能力的同时&#xff0c;也有人在尝试降低AI所需的算力资源。最近&#xff0c;一种名为FlexGen的技术因为「一块RTX 3090跑ChatGPT体量模型」而获得了人们的关注。 虽然FlexGen加速后的…

Java 修饰符和多态

文章目录一、修饰符1. 权限修饰符2. 状态修饰符2.1 final2.2 static二、多态1. 成员访问特点2. 多态中的转型3. 多态案例一、修饰符 1. 权限修饰符 2. 状态修饰符 2.1 final final 关键字是最终的意思&#xff0c;可以修饰成员方法、成员变量及类。 //1.修饰成员变量 publi…

Git ---- IDEA 集成 Git

Git ---- IDEA 集成 Git1. 配置 Git 忽略文件2. 定位 Git 程序3. 初始化本地库4. 添加到暂存区5. 提交到本地库6. 切换版本7. 创建分支8. 切换分支9. 合并分支10. 解决冲突1. 配置 Git 忽略文件 1. Eclipse 特定文件 2. IDEA 特定文件 3. Maven 工程的 target 目录 问题1…

使用eNSP搭建基础IP网络 和 单交换机与VLAN分布实验(二层+三层)

Hello, 好久不见。上学期因为个人原因一直没有更新&#xff08;主要原因是上学期小小的摆了一下&#xff09;&#xff0c;这个学期我会继续在平台上分享我的学习经验。主要包括网络互联以及攻防的内容&#xff0c;也可能会更新深度学习相关的东西&#xff0c;主要就是看我到底有…

开源启智,筑梦未来!第四届OpenI/O启智开发者大会开幕

2023年2月24日&#xff0c;第四届OpenI/O启智开发者大会在深圳顺利开幕。本次活动由鹏城实验室、新一代人工智能产业技术创新战略联盟&#xff08;AITISA&#xff09;主办&#xff0c;OpenI启智社区、中关村视听产业技术创新联盟&#xff08;AVSA&#xff09;承办&#xff0c;华…

阿里 Java 程序员面试经验分享,附带个人学习笔记、路线大纲

背景经历 当时我工作近5年&#xff0c;明显感觉到了瓶颈期。说句不好听的成了老油条&#xff0c;可以每天舒服的混日子&#xff08;这也有好处&#xff0c;有时间准备面试&#xff09;。这对于个人成长不利&#xff0c;长此以往可能面临大龄失业。所以我觉得需要痛下决心改变一…

Spring Boot系列03--自动配置原理

目录1. 相关注解2. 自动配置原理分析3. 自动配置图示Spring Boot的核心优势&#xff1a;自动装配、约定大于配置。 1. 相关注解 ConfigurationProperties(prefix "前缀名")该注解用于自动配置的绑定&#xff0c;可以将application.properties配置中的值注入到 Bean…

加油站ai系统视频监测 yolov5

加油站ai系统视频监测通过yolov5网络模型深度学习边缘计算技术&#xff0c;加油站ai系统视频监测对现场卸油过程中人员违规离岗、现场灭火器没有按要求正确摆放、以及卸油前需要遵守静电释放15分钟、打电话、明火烟雾情况、抽烟行为进行自动识别。YOLO系列算法是一类典型的one-…

九龙证券|不惧美联储重回鹰派,这个板块强势领涨!游戏才刚刚开始?

美联储开释鹰派信号&#xff0c;商场再度堕入博弈美元反弹的预期之中。 美联储近日发布的2月议息会议纪要显现&#xff0c;上行通胀危险是影响美联储前景的要害因素&#xff0c;在通胀持续回落至2%之前&#xff0c;需求采取限制性方针。叠加欧元区1月份中心通胀升至历史最高纪录…