JavaSE入门---掌握面向对象三大特性:封装、继承和多态

文章目录

  • 封装
    • 什么是封装?
    • 如何实现封装?
  • 继承
    • 什么是继承?
    • 继承的语法
    • 父类成员访问
      • 子类访问父类的成员变量
      • 子类访问父类的成员方法
    • 认识super关键字
    • 认识final关键字
    • 子类的构造方法
      • super VS this
      • 在继承关系中各代码块的执行顺序是怎样的?
    • Java支持的继承的方式
    • 继承 VS 组合
  • 多态
    • 什么是多态?
    • 什么是重写?
      • 重写 VS 重载
    • 向上转型和向下转型
      • 向上转型
      • 向下转型

封装

什么是封装?

什么是封装呢? 简单来说就是套壳屏蔽细节

比如:对我们使用的电脑来说,在它运行过程中是有很多的部件相互配合共同执行的。但对于我们使用者而言只需要使用鼠标和键盘就可以操作电脑让它工作。 这其中就是套壳的思想,电脑把它的硬件资源全部套壳(封装起来),只留出几个接口供用户使用就可以和计算机交互。

封装的标准定义:将数据和操作数据的方法有机结合,隐藏对象的属性和实现细节,仅通过对外的公开接口来和对象进行交互。

如何实现封装?

Java中主要通过类和访问权限来实现封装。

类可以将数据和封装数据的方法结合在一起。
访问权限用来控制方法和字段能否直接在类外使用。

Java中提供了四种访问限定修饰符:来设置访问权限
在这里插入图片描述

注: default权限指:什么都不写时的默认权限。

继承

什么是继承?

Java中使用类来对现实世界中的实体进行描述,但是现实世界错综复杂,事物之间可能会存在一些关联、一些共性。比如:猫和狗,他们都是动物,因此他们就具有许多相似的属性,但又有自己独有的一些属性。比如:

在这里插入图片描述

具有这些相同属性的类还有很多,如果我们在这些类中都重新加上这些属性,代码就显的有写累赘。 因此就引入了继承。我们把所有类共同的一些属性写到一个类里,把每个类独有的部分再写到一个类中。

继承:专门用来进行共性抽取,实现代码复用。

共同的部分(类),叫作:父类、基类、超类;
独有的部分(类),叫作:子类、派生类;

继承的语法

借助extends关键字

class Animal{public String name;public int age;public double weight;public void eat(){System.out.println("吃饭");}public void sleep(){System.out.println("睡觉");}
}class Cat extends Animal{public void miao(){System.out.println("喵喵叫");}
}class Dog extends Animal{public void bark(){System.out.println("汪汪叫");}
}

注:

  1. 子类会将父类中所有的成员变量、成员方法添加到子类中。
  2. 子类继承父类后必须新添加自己特有的成员,体现出与父类的不同,否则就没有必要继承了。

父类成员访问

子类访问父类的成员变量

  • 子类和父类中不存在同名的成员变量
class Animal{public String name;    //由于需要被子类对象使用,所有用public修饰public int age;
}class Dog extends Animal{public String color;public void method(){name = "小黄";   // 直接访问父类的age = 2;        // 直接访问父类的color = "黄色";  // 访问自己的}
}
  • 子类和父类中存在同名的成员变量
class Animal{public String name;public int age;
}class Dog extends Animal{public String name;public String color;public void method(){name = "小黄";   // 优先访问自己的nameage = 2;        // 直接访问父类的color = "黄色";  // 访问自己的}
}

注:

  1. 如果访问的成员变量子类中有,优先访问自己的成员变量;
  2. 如果访问的成员变量子类中无,则访问父类继承下来的;如果父类中也没,则编译报错;
  3. 如果访问的成员变量与父类中的成员变量同名,则优先访问自己的;

子类访问父类的成员方法

  • 成员方法名字不同
class Animal{public void eat(){System.out.println("吃饭");}
}class Dog extends Animal{public void bark(){System.out.println("汪汪叫");}public void method(){bark();    //访问子类自己的eat();     //访问父类的}
}
  • 成员方法名字相同
class Animal{public void eat(){System.out.println("动物吃饭");}
}class Dog extends Animal{public void eat(){System.out.println("狗吃饭");}public void method(){eat();     //访问自己的}
}

注:

  1. 通过子类对象访问 父类与子类中不同名的方法时,优先在子类中找,找到则访问;否则在父类中找,找到则访问,否则编译报错;
  2. 通过子类对象访问 父类与子类中同名的方法时,如果父类和子类的同名方法参数列表相同,则优先访问子类自己的;如果参数列表不同,则根据调用方法时传递的参数选择合适的方法访问,若没有则报错;

认识super关键字

如果子类中存在和父类相同的成员时,如何不访问子类的成员,而去访问父类的成员呢? 这就需要用到super关键字。

super:在子类方法中访问父类的成员

class Animal{public String name;public void eat(){System.out.println("动物吃饭");}
}class Dog extends Animal{public String name;public void eat(){System.out.println("狗吃饭");}public void method(){super.name = "动物名";   //访问父类的成员变量super.eat();            //访问父类的成员方法}
}

注:

  1. 只能在子类方法中使用;
  2. 只能在非静态方法中使用;

认识final关键字

final可以被用来修饰:变量、成员方法、类;

  • final修饰变量或字段,表示常量—不能修改;
  • final修饰类,表示此类不能被继承;
  • finnal修饰方法,表示此方法不能被重写(多态中会使用到);

子类的构造方法

父子父子,先有父再有子;即:子类对象构造时,需要先调用父类的构造方法构造父类,然后执行子类的构造方法构造子类;

class Animal{public Animal(){System.out.println("执行父类构造方法");}
}class Dog extends Animal{public Dog(){System.out.println("执行子类构造方法");}
}//再main中创建子类时,结果为:
//执行父类构造方法
//执行子类构造方法

为什么还会调用到父类的构造方法呢?
子类对象中成员是由两部分组成的:父类继承下来的成员和子类新增的成员;父子父子,肯定先有父再有子。因此,需要先调用父类的构造方法,将从父类继承下来的成员构造完整;再调用子类自己的构造方法,将自己新增的成员构造完整。

注:

  1. 如果父类没有定义构造方法,在子类的构造方法中第一行会隐含的调用super(),即执行父类空的构造方法。
  2. 如果父类定义了无参的构造方法,在子类的构造方法中第一行会隐含的调用super(),即执行父类无参的构造方法。
  3. 如果父类定义了有参数的构造方法,此时编译器不会默认生成隐含的super()—因为它不知道参数是啥,需要用户显示的指定父类的构造方法。
  4. 在子类构造方法中,使用super(…)调用父类的构造方法时,super必须放在子类构造方法的第一行。
  5. super只能在子类构造方法中出现一次,且不能和this同时出现。

super VS this

相同点:

  1. 都是Java的关键字;
  2. 只能在类的非静态方法中使用,访问非静态的变量和非静态的方法
  3. 在构造方法中调用时,都必须在构造方法的第一行,且不能同时存在。

不同点:

  1. this是当前对象的引用,即引用当前对象的成员;super是从父类继承下来的成员的引用,即引用父类中的成员。
  2. this是非静态成员方法的一个隐藏参数,super不是一个隐藏参数;
  3. 在构造方法中,this用来调用本类构造方法,super用来构造父类构造方法;不能同时出现在一个构造方法里。
  4. 构造方法中一定存在super的调用,用户没有写编译器也会增加;但是this用户不写则没有。

在继承关系中各代码块的执行顺序是怎样的?

class Animal{{System.out.println("父类执行实例代码块");}static {System.out.println("父类执行静态代码块");}public Animal(){System.out.println("父类执行构造方法");}
}class Dog extends Animal{{System.out.println("子类执行实例代码块");}static {System.out.println("子类执行静态代码块");}public Dog(){System.out.println("子类执行构造方法");}
}
public class test {public static void main(String[] args) {Dog dog = new Dog();}
}//结果:
父类执行静态代码块
子类执行静态代码块
父类执行实例代码块
父类执行构造方法
子类执行实例代码块
子类执行构造方法

注:

  1. 父类静态代码块优先于子类静态代码块执行,且都是最早执行;
  2. 父类实例代码块和父类构造方法再执行;
  3. 子类实例代码块和子类构造方法再执行;
  4. 实例代码块优先于构造方法执行;
  5. 第二次实例化子类对象时,父类和子类的静态代码块都不执行;

Java支持的继承的方式

在这里插入图片描述

继承 VS 组合

组合:和继承类似,也是一种表达类之间关系的方式。也能够达到代码复用的效果,它是将一个类的实例作为另一个类的字段。

//以汽车为例,说明继承和组成的不同//轮胎类
class Tire{}//发动机类
class Engine{}//车内系统类
class VehicleSystem{}//组成
class Car{private Tire tire;private Engine engine;private VehicleSystem vehicleSystem;
}//继承  奔驰继承了汽车类
class Benz extends Car{}

注:

  1. 继承表示对象之间是 is-a 的关系,即 猫是动物、狗是动物;
  2. 组合表示对象之间是 has-a的关系,即 汽车有轮子、发动机、车载系统;
  3. 继承借助extends关键字,会自动将父类成员加载到子类中;组合需要手动在某个类当中引入其他类的成员;

多态

什么是多态?

多态:即多种形态;具体点就是去完成某个行为时,不同的对象去完成时会产生不同的状态。

实现多态的条件:

  1. 必须在继承体系下;
  2. 子类必须对父类方法进行重写;
  3. 通过父类的引用调用重写方法;
class Animal{public String name;public int age;public Animal(String name,int age){this.name = name;this.age = age;}public void eat(){System.out.println(name + "吃饭");}
}class Cat extends Animal{public Cat(String name,int age){super(name,age);}@Overridepublic void eat() {System.out.println(name + "cat吃鱼");}
}class Dog extends Animal{public Dog(String name, int age){super(name,age);}@Overridepublic void eat() {System.out.println(name + "dog吃骨头");}
}
public class test {//通过父类调用eat方法才能看出来重写的作用//没有重写时,子类中没有eat方法,只能使用父类的eat方法,不管是哪个子类最后都会打印出 动物吃饭//重写后,子类中有重写的eat方法,调用父类的eat方法时,会自动识别出哪个子类调用的eat方法,会打印出对应动物的吃饭////子类有重写方法后,当然也可以不通过调用父类eat方法,而是直接调用自己重写后的eat方法打印出对应的动物的吃饭//但这样就看不出重写的作用了public static void eat(Animal a){a.eat();}public static void main(String[] args) {Cat cat = new Cat("小猫",1);Dog dog = new Dog("小狗",2);eat(cat);eat(dog);}
}

什么是重写?

重写:也叫覆盖,是子类对父类非静态、非private修饰、非final修饰、非构造方法等的重新编写,返回值和形参都不能改变。即外壳不变,核心重写

注:

  1. 子类在重写父类方法时,一般必须与父类方法原型一致:即修饰符、返回值类型、方法名、参数列表要完全一致。
  2. 特殊情况下,返回值类型可以不同,但是必须具有父子关系。
  3. 子类中重写方法的访问权限不能比父类方法中的访问权限更低。
  4. 父类中被static修饰的、private修饰的、final修饰的方法和构造方法,不能被重写。
  5. 重写后的方法要加上 @Override 注解。

重写 VS 重载

在这里插入图片描述

向上转型和向下转型

向上转型

向上转型:实际就是创建一个子类对象,将其当成父类对象来使用。

语法格式: 父类类型 对象名 = new 子类类型()

		// animal是父类类型但是可以引用一个子类对象   把小范围的对象放到大范围的对象里Animal animal = new Dog("小狗",2);

使用场景:

  1. 直接赋值
  2. 方法传参
  3. 方法返回

注:

  1. 向上转型的优点:让代码实现更简单灵活。
  2. 向上转型的缺点:不能调用到子类特有的方法

向下转型

向下转型:将子类对象向上转型后就无法调用子类特有的方法,但是有时候可能需要调用到子类特有的方法,此时就需要向下转型:将父类引用再还原为子类对象

		Cat cat = new Cat("小猫",1);Dog dog = new Dog("小狗",2);//向上转型Animal animal = cat;//向下转型: 按道理可以转为继承Animal的任意子类对象  但是有些不安全//必须强制类型转换Cat cat1 = (Cat) animal;    //安全  因为向上转型时就是Cat转的Dog dog1 = (Dog) animal;    //不安全 会抛出异常  因为向上转型是Cat转的  但是现在却要把猫类成员赋值给狗类

Java中为了提高向下转型的安全性,引入了 instanceof :类型匹配 如果为true则可以安全转换。

		Cat cat = new Cat("小猫",1);Dog dog = new Dog("小狗",2);//向上转型Animal animal = cat;//向下转型if (animal instanceof Cat){Cat cat1 = (Cat) animal;}if (animal instanceof Dog){Dog dog1 = (Dog) animal;}

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

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

相关文章

数据可视化与GraphQL:利用Apollo创建仪表盘

前言 「作者主页」:雪碧有白泡泡 「个人网站」:雪碧的个人网站 「推荐专栏」: ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄,vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

YOLO目标检测——人脸识别数据集【对应voc、coco和yolo三种格式标签】

实际项目应用:安全监控、智能驾驶、人机交互、人脸门禁、人脸支付、人脸搜索数据集说明:人脸识别数据集,真实场景的高质量图片数据,数据场景丰富,含有人脸图片标签说明:使用lableimg标注软件标注&#xff0…

OSG嵌入QT的简明总结2

正文 我之前在这篇博文《OSG嵌入QT的简明总结》中论述了OSG在QT中显示的可视化问题。其中提到官方提供的osgQt项目(地址:https://github.com/openscenegraph/osgQt )很久前已经更新了。但是我一直没有时间同步更新,最近重新尝试了…

PHP 基础

PHP 基础 概述 在PHP 文件中&#xff0c;可以与HTML 和JavaScript 混编。 开始标记<?php 表示进入PHP 模式&#xff0c;结束标记?>&#xff0c;标识退出PHP 模式。 PHP 模式之外的内容会被作为字符输出到浏览器中。 PHP 在服务端执行&#xff0c;HTML 和 JS 在浏览…

vim的使用以及配置

vim的使用以及配置 vim的介绍vim的使用vim的三种模式vim的三种模式的转换方式三个模式的运用命令模式插入模式底行模式 vim的配置vim一键配置命令 vim的介绍 百度官方介绍&#xff1a; Vim是一个类似于Vi的著名的功能强大、高度可定制的文本编辑器&#xff0c;在Vi的基础上改进…

【iOS】UITableView总结(Cell的复用原理、自定义Cell、UITableViewCell协议方法)

UITableView 列表的特点&#xff1a; 数据量大样式较为统一通常需要分组垂直滚动通常可视区只有一个 -> 视图的复用 UITableViewDataSource UITableView作为视图&#xff0c;只负责展示&#xff0c;协助管理&#xff0c;不管理数据 需要开发者为UITableView提供展示所需…

登上抖音热搜榜:如何让你的内容火爆全网

在当今信息爆炸的时代&#xff0c;抖音已经成为了很多人获取信息、娱乐和社交的重要平台。每一天&#xff0c;都有大量的短视频在抖音上诞生&#xff0c;然而&#xff0c;只有少数幸运儿能够登上抖音热搜榜&#xff0c;成为万人瞩目的焦点。那么&#xff0c;如何让你的内容火爆…

Go并发编程之四

一、前言 今天我们介绍一下Go并发编程另外一个重要概念【多路复用】&#xff0c;多路复用最开始是在网络通讯领域&#xff08;硬件&#xff09;应用&#xff0c;指的是用同一条线路承载多路信号进行通信的方式&#xff0c;有频分多路复用、时分多路复用等等技术&#xff0c;然…

MySQL日志 错误日志 二进制日志 查询日志 慢查询日志

一、错误日志 错误日志是MySQL中最重要的日志之一,它记录了当mysqld启动和停止时,以及服务器在运行过程中发生任何严重错误时的相关信息。当数据库出现任何故障导致无法正常使用时,建议首先查看此日志。 该日志是默认开启的&#xff0c;默认存放目录/var/log/,默认的日志文件名…

小程序路由传参的方法?

小程序路由传参的方法有两种&#xff1a; 1.通过URL参数传递&#xff1a;可以在跳转页面时在URL中携带参数&#xff0c;目标页面可以通过获取URL参数来使用。使用wx.navigateTo或wx.redirectTo方法进行页面跳转&#xff0c;并在URL中添加参数。 示例代码如下&#xff1a; // …

2019年亚太杯APMCM数学建模大赛A题基于图像分析的二氧化硅熔化表示模型求解全过程文档及程序

2019年亚太杯APMCM数学建模大赛 A题 基于图像分析的二氧化硅熔化表示模型 原题再现 铁尾矿的主要成分是二氧化硅&#xff0c;而二氧化硅是铁尾矿成分中最难熔化的部分。因此&#xff0c;铁尾矿的熔融行为可以用二氧化硅的熔融行为来表示。然而&#xff0c;高温熔池的温度超过…

Android FloatingActionButton 使用神坑记录

1.FloatingActionButton 死活都不是圆形 必须加上下面这个属性才是圆形 app:shapeAppearance"style/ShapeAppearanceOverlay.Material3.Button"2.FloatingActionButton 中间的icon不居中 加上下面的属性&#xff0c;然后大小跟你的控件大小一致 app:fabCustomSiz…

C语言标准规范版本介绍

0 Preface/Foreword ANSI&#xff1a;American National Standards Institute&#xff0c;美国国家标准协会 ISO&#xff1a;International Organization for Standardization&#xff0c;国际标准组织 IEC&#xff1a;International Electrotechnical Commission&#xff0…

Jmeter的性能测试

性能测试的概念 定义&#xff1a;软件的性能是软件的一种非功能特性&#xff0c;它关注的不是软件是否能够完成特定的功能&#xff0c;而是在完成该功能时展示出来的及时性。 由定义可知性能关注的是软件的非功能特性&#xff0c;所以一般来说性能测试介入的时机是在功能测试…

Python---练习:while循环嵌套(用两次while三步走--里外各一次)

1、循环嵌套的引入 案例&#xff1a; 有天女朋友又生气了&#xff0c;惩罚&#xff1a;说3遍“老婆大人&#xff0c; 我错了”&#xff0c;这个程序是不是循环即可&#xff1f;但如果女朋友说&#xff1a;还要刷今天晚饭的碗&#xff0c;这个程序怎么书写&#xff1f; 思考&…

面试题 01.06. 字符串压缩

​​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;面试题 01.06. 字符串压缩 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 计算压缩后的字符串长度&#xff0c;如果该长度小于原字符串长度&#xff0c;返回压缩后的字符串&#xff0c;否则…

MOSFET(五):DrMos

一、简介 DrMos&#xff08;Driver MOSFET&#xff09;技术是 Intel 于2004年推出的服务器主板节能技术&#xff0c;即把 2 个MOSFET和 1 个MOS驱动器 三合一&#xff0c;集成在一个封装中。集成后的 DrMos 面积是分离MOSFET的 &#xff0c;功率密度是其 倍&#xff0c;通过搭…

Flink中的时间和窗口操作

1.窗口概念 在大多数场景下,我们需要统计的数据流都是无界的,因此我们无法等待整个数据流终止后才进行统计。通常情况下,我们只需要对某个时间范围或者数量范围内的数据进行统计分析:如每隔五分钟统计一次过去一小时内所有商品的点击量;或者每发生1000次点击后,都去统计一…

android 13/14高版本SurfaceFlinger出现VSYNC-app/VSYNC-appSf/VSYNC-sf剖析

问题背景&#xff1a; 了解surfaceflinger的vsync同学都可能知道vsync属于一个节拍器&#xff0c;主要用来控制有节奏的渲染&#xff0c;不至于会产生什么画面撕裂等现象。 一般vsync都有会有2部分&#xff1a; app部分vsync&#xff0c;控制各个app可以有节奏的上帧 surfacef…

UVM-什么是UVM方法学

概念简介 百度对UVM的解释如下&#xff1a; 通用验证方法学&#xff08;Universal Verification Methodology, UVM&#xff09;是一个以SystemVerilog类库为主体的验证平台开发框架&#xff0c;验证工程师可以利用其可重用组件构建具有标准化层次结构和接口的功能验证环境 UVM…