【Java初阶(六)上】封装 继承 多态

❣博主主页: 33的博客❣
▶文章专栏分类: Java从入门到精通◀
🚚我的代码仓库: 33的代码仓库🚚

目录

  • 1.前言
  • 2.封装
    • 2.1如何实现封装
    • 2.2 访问限定符
    • 2.3包的概念
      • 2.3.1导入包中的类
      • 2.3.2自定义包
  • 3.继承
    • 3.1为什么要继承
    • 3.2继承的概念
    • 3.3继承的语法
    • 3.4父类成员访问
      • 3.4.1子类中访问父类的成员变量
    • 3.5子类构造方法
    • 3.6super和this
    • 3.7继承方式
    • 3.8final 关键字
    • 3.9继承和组合
  • 4.总结

1.前言

对于面向对象程序三大特性:封装、继承、多态。这篇文章将会详细讲解到如何实现封装、继承、多态,以及具体的应用。

本章重点

掌握封装的概念,如何实现封装,包的概念,继承的概念,为什么要继承,继承的相关语法,子类构造方法等等。


2.封装

对于电脑这样一个复杂的设备,提供给用户的就只是:开关机、通过键盘输入,显示器,USB插孔等,让用户来和计算机进行交互,完成日常事务。但实际上:电脑真正工作的却是CPU、显卡、内存等一些硬件元件。因此计算机厂商在出厂时,在外部套上壳子,将内部实现细节隐藏起来,仅仅对外提供开关机、鼠标以及键盘插孔等,让用户可以与计算机进行交互即可。
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互


2.1如何实现封装

class Student {private String name;//用private权限修饰可以实现,此时name只能在当前类中使用private int age;private String sex;
}

那么这个时候我如果想在其他类值获取被private修饰的成员变量的值,该如何修改呢?其实,只需要设置set和get方法,就可以在其他类中访问了。
快捷生成方式如下:
在这里插入图片描述


2.2 访问限定符

Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。Java中提供了四种访问限定符:
在这里插入图片描述

public:可以理解为一个人的外貌特征,谁都可以看得到
default: 对于自己家族中(同一个包中)不是什么秘密,对于其他人来说就是隐私了
private:只有自己知道,其他人都不知道
protected:子类或者同一类都可以访问


2.3包的概念

在上面四种权限中,我们可以看到多次提到了包,那么什么是包呢?其实包简单来说就是一个文件夹。为了更好的管理类,把多个类收集在一起成为一组,称为软件包有点类似于目录。比如:为了更好的管理电脑中的歌曲,一种好的方式就是将相同属性的歌曲放在相同文件下,也可以对某个文件夹下的音乐进行更详细的分类。
在这里插入图片描述
包还有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在不同的包中即可。


2.3.1导入包中的类

其实在之前,认识键盘输入的时候,我们已经接触过导入包中的类了:

import java.util.Scanner;

如果我们需要导入util中的其他类也导入,格式如下:

import java.util.*;

虽然导入了util这个文件底下的所有类,但在Java中用到那个类才会导入它。
但这样导入一个包下所有类有弊端l,两个包底下出现了同一个类就不能编译:比如util包和sql包下都有Date类,当调用Date类的时候,编译器也不知道用谁的。

import java.util.*;
import java.sql.*;
Date date1 = new Date();
Date date1 = new Date();

我建议显式的指定要导入的类名. 否则容易出现冲突的情况。


2.3.2自定义包

基本规则

  • 在文件的最上方加上一个 package 语句指定该代码在哪个包中.
  • 包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式例如:(com.baidu.www)
  • 包名要和代码路径相匹配. 例如创建代码(com.baidu.www)的包,那么会存在一个对于路径com/baidu/www
  • 如果一个类没有 package 语句, 则该类被放到一个默认包中
    操作步骤:
    1. 在 IDEA 中先新建一个包: 右键 src -> 新建 -> 包
    在这里插入图片描述
    2. 在弹出的对话框中输入包名,例如com.baidu.www,下图是按一层一层进行显示
    在这里插入图片描述

3.继承

3.1为什么要继承

Java中使用类对现实世界中实体来进行描述,类经过实例化之后的产物对象,则可以用来表示现实中的实体,但是现实世界错综复杂,事物之间可能会存在一些关联,那在设计程序是就需要考虑。
比如:狗和猫,它们都是一个动物。

// Dogpublic class Dog{string name;int age;float weight;public void eat(){System.out.println(name + "正在吃饭");}public void sleep(){System.out.println(name + "正在睡觉");}
void Bark(){
System.out.println(name + "汪汪汪~~~");}}// Catpublic class Cat{string name;int age;float weight;public void eat(){System.out.println(name + "正在吃饭");}public void sleep(){System.out.println(name + "正在睡觉");}void mew(){System.out.println(name + "喵喵喵~~~");}}

观察上面代码,我们会发现它们都存在大量相同的属性和方法

狗:
string name;
int age;
public void eat()
public void sleep()
void Bark()

猫:
string name;
int age;
public void eat()
public void sleep()
void mew()

那能否将这些共性抽取呢?面向对象思想中提出了继承的概念,专门用来进行共性抽取,实现代码复用。


3.2继承的概念

继承(inheritance)机制:是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加新功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构, 体现了由简单到复杂的认知过程。继承主要解决的问题是:共性的抽取,实现代码复用。
在这里插入图片描述
上述图示中,Dog和Cat都继承了Animal类,其中:Animal类称为父类/基类或超类,Dog和Cat可以称为Animal的子类/派生类,继承之后,子类可以复用父类中成员,子类在实现时只需关心自己新增加的成员即可。


3.3继承的语法

在Java中要表示类之间的继承关系,需要借助extends关键字,具体如下:

修饰符 class 子类 extends 父类 {// ...  
}

注意

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

3.4父类成员访问

在继承体系中,子类将父类中的方法和字段继承下来了,那在子类中能否直接访问父类中继承下来的成员呢?

3.4.1子类中访问父类的成员变量

1.访问不同名的成员变量

//父类
public class Base {int a;int b;}//子类public class Derived extends Base{int c;public void method(){a = 10;    // 访问从父类中继承下来的ab = 20;    // 访问从父类中继承下来的bc = 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}}

那如在同名的情况下,我想访问父类的成员,该怎么办呢?可以使用super关键字

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

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

  • 如果访问的成员变量子类中有,优先访问自己的成员变量。
  • 如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。
  • 如果访问的成员变量与父类中成员变量同名,则优先访问自己的。
  • 如果想访问父类成员,可以使用super关键字。
  • 成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找。

3.5子类构造方法

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

//Animal
public  String name;public  int age;public String color;public void eat(){System.out.println(this.name+"正在吃饭");}public Animal(String name, int age, String color) {this.name = name;this.age = age;this.color = color;}
//Cat
public class Cat extends Animal{public Cat(String name, int age, String color) {super(name, age, color);//初始化父类构造方法}public void mew(){System.out.println("喵喵喵~~~");}
}

如果我父类没有构造方法,子类也不调用,会报错吗?答案是不会的,因为父类没有构造方法会默认生成一个,此时就会调用生成的构造方法,只不过看不见。
注意

  • 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构
    造方法
  • 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的
    父类构造方法调用,否则编译失败。
  • 在子类构造方法中,super(…)调用父类构造时,必须是子类构造函数中第一条语句。
  • super(…)只能在子类构造方法中出现一次,并且不能和this同时出现

3.6super和this

super和this都可以在成员方法中用来访问:成员变量和调用其他的成员函数,都可以作为构造方法的第一条语句,那他们之间有什么区别呢?
【相同点】

  1. 都是Java中的关键字
  1. 只能在类的非静态方法中使用,用来访问非静态成员方法和字段
  2. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在
    【不同点】
  1. this是当前对象的引用,当前对象即调用实例方法的对象,super相当于是子类对象中从父类继承下来部分成员的引用。
  2. 在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性。
  3. 在构造方法中:this(…)用于调用本类构造方法,super(…)用于调用父类构造方法,两种调用不能同时在构造方法中出现。
  4. 构造方法中一定会存在super(…)的调用,用户没有写编译器也会增加,但是this(…)用户不写则没有。

在这里插入图片描述


3.7继承方式

在现实生活中,事物之间的关系是非常复杂,灵活多样,比如:
在这里插入图片描述
Java中的几种继承:
单继承:

public class A{
}
public class B extend A{
}

多层继承

public class A{
}
public class B extend A{
}
public class C extend B{
}

注意:Java中不支持多继承,指的是不支持一个类继承多个父类。
但是即使如此, 我们并不希望类之间的继承层次太复杂. 一般我们不希望出现超过三层的继承关系. 如果继承层次太多, 就需要考虑对代码进行重构了。
如果想从语法上进行限制继承, 就可以使用 final 关键字。


3.8final 关键字

final关键可以用来修饰变量、成员方法以及类。
1.修饰变量:表示常量

final int a = 10;//此时a是一个常量不能再改变
  1. 修饰类:表示此类不能被继承
final public class Animal {}

3.9继承和组合

和继承类似, 组合也是一种表达类之间关系的方式, 也是能够达到代码重用的效果组合并没有涉及到特殊的语法(诸如 extends 这样的关键字), 仅仅是将一个类的实例作为另外一个类的字段。
继承表示对象之间是is-a的关系,比如:狗是动物,猫是动物
组合表示对象之间是has-a的关系,比如:汽车

例如

// 轮胎类
class Tire{
//....}
// 发动机类
class Engine{// ...} 
// 车载系统类
class VehicleSystem{// ...}
//组合 
class Car{private Tire tire;          // 可以复用轮胎中的属性和方法private Engine engine;      // 可以复用发动机中的属性和方法private VehicleSystem vs;   // 可以复用车载系统中的属性和方法 // ...} 
// 继承:奔驰是汽车
class Benz extend Car{// 将汽车中包含的:轮胎、发送机、车载系统全部继承下来
}

4.总结

本篇文章主要讲了有关封装和继承的相关知识点,在下一篇文章中博主将继续更新多态的相关知识点,感兴趣的同学可以关注博主哦。


下期预告:多态

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

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

相关文章

『Apisix进阶篇』动态负载均衡:APISIX的实战演练与策略应用

🚀『Apisix系列文章』探索新一代微服务体系下的API管理新范式与最佳实践 【点击此跳转】 📣读完这篇文章里你能收获到 🎯 掌握APISIX中多种负载均衡策略的原理及其适用场景。📈 学习如何通过APISIX的Admin API和Dashboard进行负…

QtCreator调试时无法显示std::string的内容

在银河麒麟V10或Ubuntu下使用QtCreator调试代码时&#xff0c;std::string类型变量在大多数情况下不显示实际内容&#xff0c;而是显示"<无法访问>"字样&#xff0c;鼠标点击进去也是看不见任何有用信息&#xff0c;这样非常影响调试效率&#xff0c;为此&…

android 11 SystemUI 状态栏打开之后的界面层级关系说明之一

比如WiFi 图标的父layout为&#xff1a; Class Name: ButtonRelativeLayout Class Name: QSTileView Class Name: TilePage Class Name: PagedTileLayout Class Name: QSPanel Class Name: NonInterceptingScrollView Class Name: QSContainerImpl Class Name: FrameLayout Cl…

软件开发服务合同套用模板(WORD原件)

一、合作方式 二、合同标的 三、开发进度及软件成果交付 四、开发费用 五、付款结算方式 六、知识产权条款 七、双方的权利和义务 八、验收 九、售后服务支持 十、培训 十一、保密责任 十二、不可抗力 十三、争议的解决 十四、其它事项 软件全套资料包领取&#xff1a;软件开发…

手机termux免root安装kali:一步到位+图形界面_termux安装kali-

1.工具 安卓包括鸿蒙手机、WiFi、充足的电量、脑子 2.浏览器搜索termuxvnc viewer下载安装。 3.对抗华为纯净模式需要一些操作先断网弹窗提示先不开等到继续安装的时候连上网智能检测过后就可以了 termux正常版本可以通过智能监测失败了就说明安装包是盗版 4.以后出现类似…

区块链技术与大数据结合的商业模式探索

hello宝子们...我们是艾斯视觉擅长ui设计和前端开发10年经验&#xff01;希望我的分享能帮助到您&#xff01;如需帮助可以评论关注私信我们一起探讨&#xff01;致敬感谢感恩&#xff01; 随着区块链技术和大数据技术的不断发展&#xff0c;两者的结合为企业带来了新的商业模式…

聊聊多模态大模型处理的思考

多模态&#xff1a;文本、音频、视频、图像等多形态的展现形式。目前部门内业务要求领域大模型需要是多模态——支持音频/文本。从个人思考的角度来审视下&#xff0c;审视下多模态大模型的实现方式。首先就要区分输入与输出&#xff0c;即输入的模态与输出的模态。从目前来看&…

HBase的Python API(happybase)操作

一、Windows下安装Python库&#xff1a;happybase pip install happybase -i https://pypi.tuna.tsinghua.edu.cn/simple 二、 开启HBase的Thrift服务 想要使用Python API连接HBase&#xff0c;需要开启HBase的Thrift服务。所以&#xff0c;在Linux服务器上&#xff0c;执行如…

2024最新版克魔助手抓包教程(9) - 克魔助手 IOS 数据抓包

引言 在移动应用程序的开发中&#xff0c;了解应用程序的网络通信是至关重要的。数据抓包是一种很好的方法&#xff0c;可以让我们分析应用程序的网络请求和响应&#xff0c;了解应用程序的网络操作情况。克魔助手是一款非常强大的抓包工具&#xff0c;可以帮助我们在 Android …

前端Webpack5高级进阶课程

课程介绍 本套视频教程主要内容包含React/Vue最新版本脚手架分析、基于Webpack5编写自己的loader和plugin等&#xff0c;让你开发时选择更多样&#xff0c;最后&#xff0c;用不到一百行的代码实现Webpack打包。通过本套视频教程的学习&#xff0c;可以帮你彻底打通Webpack的任…

分类预测 | Matlab实现CNN-LSTM-Mutilhead-Attention卷积神经网络-长短期记忆网络融合多头注意力机制多特征分类预测

分类预测 | Matlab实现CNN-LSTM-Mutilhead-Attention卷积神经网络-长短期记忆网络融合多头注意力机制多特征分类预测 目录 分类预测 | Matlab实现CNN-LSTM-Mutilhead-Attention卷积神经网络-长短期记忆网络融合多头注意力机制多特征分类预测分类效果基本介绍模型描述程序设计参…

Python 从0开始 一步步基于Django创建项目(13)将数据关联到用户

在city_infos应用程序中&#xff0c;每个城市信息条目是关联到城市的&#xff0c;所以只需要将城市条目关联到用户即可。 将数据关联到用户&#xff0c;就是把‘顶层’数据关联到用户。 设计思路&#xff1a; 1、修改顶层数据模型&#xff0c;向其中添加‘用户’属性 2、根…