JavaSE复习
面向对象
- 面向对象编程(Object - Oriented Programming / OOP)
- 面向对象编程的本质:以类的方式组织代码,以对象的方式封装数据
- 三大特性:封装、继承、多态
从认识论角度考虑是先有对象后有类。对象是具体的事物。类是抽象的。
从代码的角度来考虑是现有类再有对象,类是对象的模板。
面向过程 & 面向对象
- 面像过程思想
- 步骤清晰简单,第一步做什么,第二步做什么。。。
- 面向过程适合处理一些较为简单的问题
- 面向对象思想
- 以 分类 的思维模式解决问题,先思考解决问题需要哪些分类,然后进行单独思考。最后才对某个分类下的细节进行面向过程的思考。
- 面向对象适合处理复杂的问题,适合处理需要多人协作的问题
对于描述复杂的事物,从宏观、整体上合理分析,需要用到面向对象的思考方式来分析整个系统,但是具体到细节上,任然需要用到面向过程的思考方式来处理
类与对象
- 类是一种抽象的东西,是定义某一类东西的东西,但并不代表某一个具体的事物
- 例如:家具,食物,餐具......
- 类更像是制造一个对象的图纸
- 对象是类的具体实例
- 例如:椅子,炸鸡,筷子......
- 对象是一个具体的实例,有自己的特点,不是某一个种类,单独的一个个体,不是抽象的
创建与初始化对象
类
-
类中的构造器\构造方法,构造器在创建对象时会调用。
- 类中只有,属性 和 方法
- 特点一:必须和类的名字相同
- 特点二:一定,必须没有返回值,但也不能用void。
对象
-
使用
new
关键字创建对象- 使用
new
关键字创建对象的时候,会给这个对象分配空间 - 创建好的对象会进行默认初始化,以及对类中构造器的调用
- 实例化一个对象的过程就像,类是玩具的图纸,通过这个图纸(类)拼出来一个玩具(对象)
- 使用
构造器
什么是构造器?
构造器通常也叫构造方法、构造函数、缺省构造器,构造器在
new
对象的时候会被调用,可以完成对象的创建同时给变量赋值使用new关键字,本质是在调用构造器
语法
- 必须和类的名字相同
- 一定,必须没有返回值,但也不能用void
- 当一个类没有构造方法时,系统默认提供无参构造
例:
- 创建一个空的
Person
类
- 发现能实例化出来这个
Person
类
- 说明
Person
类里存在一个空的构造器(无参构造器)
- 结论:一个类里面即使什么都不写,也会存在一个方法(无参构造器)
显示的定义一个无参构造器
-
无参构造器能实例化初始值
结果:
有参构造器
- 一旦定义有参构造器就一定得显示的定义一个无参构造器
-
在使用
Person
这个类创建对象时会出现方法重载结果:w
因为使用这个类时有值传入,所以程序就往有参构造那走了
封装
在面向对象程式设计方法中,封装(Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。
也就是隐藏内部的实现细节,外部不能查看,通过提供对外的方法来调用与修改。
封装能让代码更易于理解与维护,同时也增强了代码的安全性。
- 封装(数据的隐藏)
- 程序设计追求 “高内聚,低耦合”
- 高内聚:类的内部数据操作细节自己完成,不允许外部干涉
- 低耦合:仅暴露少量的方法给外部使用
- 简单来说就两个东西:
get
和set
- 所有实例相关的东西都是用
引用.
来访问 - 所有静态相关的东西都是用
类名.
来访问
实现封装
- 通过
private
关键字设置为私有属性,再设置公共的 get、set 方法方便外部取得、设置name的值。
-
封装还可以进行判断输入值是否合法,或者更多骚操作。
-
实例:
调用:
结果:
继承
- B类继承A类,则A类是B类的超类(superclass)、父类、基类,B类是A类的子类(subclass)、派生类、扩展类
- 子类继承父类,且拥有父类的实例域和方法,但构造方法不继承,私有属性不能在子类中直接访问(通过
super.
关键字来访问) - 继承能增加代码的重复利用率
- Java中只有单继承,没有多继承(一个孩子一个爹)
- 所有类都继承至一个
Object
类,它是所有类的祖宗 - 继承的缺点:耦合度高,父类一旦修改,所有的子类全都受到牵连
类的继承格式
Java中通过 extends
关键字声明
Objext
类是个特殊类,我称之为祖宗类,所有类都默认继承Object
类。- 子类具有父类所有字段,之后定义不能和父类重复。
super & this
-
super
关键字:-
代表父类,子类调用父类的字段时,用
super.fileldName
调用。 -
只能在有继承的情况下才能使用
-
构造方法:
this( );
本类的构造器
-
-
this
关键字:- 代表自己,指向自己的引用,用
this.fileldName
调用。 - 没有继承也可以使用
- 构造方法:
super( );
父类的构造器
- 代表自己,指向自己的引用,用
实例:
- 定义一个
Person
类
- 再定义一个
Student
类继承Person
类
- 实例化 student 对象查看效果
结果:
super 注意点
super
调用父类构造方法,必须在构造方法的第一个。super
必须只能出现在子类的方法或构造方法中。super
和 this 不能同时调用构造方法。(因为两者都必须在第一行,有冲突)
protected
- 在继承中,子类无法访问父类的
private
字段或者private
方法。 protected
关键字可以把字段和方法的访问权限控制在继承树内部,一个protected
字段和方法可以被其子类,以及子类的子类所访问。
无法调用:
成功调用:
- 由于
private
关键字使得子类无法调用,则可以把private
改为protected
,这样子类便能调用父类被protected
修饰的字段。
继承中的构造器
- 子类并不继承父类的构造器(构造方法或者构造函数),只是调用(隐式或显式)。
结果:
当显示调用父类无参构造则必须在子类构造器的第一行。(不写一般都默认调用父类无参构造器)
若父类的构造器带有参数,则必须在子类的构造器中显式地通过
super
关键字调用父类的构造器并配以适当的参数列表。若父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。
方法重写(override)
为什么要重写?
- 父类的功能,子类不一定需要,或子类需要的更多!
特点:
- 子类和父类需要有继承关系
- 重写是对父类可访问的方法的重写,和属性无关
- 声明为 final 的方法不能被重写
- 声明为 static 的方法不能被重写,但是能够被再次声明
- 修饰符的范围可以扩大但不能缩小。(public > protected > Default > private)
- 抛出的异常范围可以被缩小,但不能扩大
- 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类。(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)
- 方法名、返回值、形参必须相同,方法体不同。(外壳不变,核心重写)
例:
输出:
多态
一个类的多种形态
父类型引用指向子类型对象
编译时一种形态,运行时一种形态,这就是多态
编译时多态:通过 overloading(重载) 实现
编译阶段绑定父类型的方法
运行时多态:通过 overriding(重写) 和 继承实现
运行阶段动态绑定子类型对象的方法
多态存在的三个条件
- 拥有继承关系
- 子类重写父类方法
- 父类引用指向子类对象:Parent p = new Child( );
- upcasting 向上转型(父-->子 自动类型转换):将子类对象直接赋值给父类引用
- 只有向上转型过的对象才能向下转型
- downcasting 向下转型(子-->父 强制类型转换):将指向子类对象的父类引用赋值给子类引用
实例:
和父类有继承关系的Student类:
调用:
结果:
由此可以看出多态成员访问的特点:
成员变量:编译看父类(左边),运行看父类(左边)
在程序的编译阶段,根据父类中的变量进行编译,实际运行时也是根据父类的变量进行运行
成员方法:编译看父类(左边),运行看子类(右边)
在程序的编译阶段,根据父类的方法进行编译,父类有这个方法编译通过,没有则报 ClassCastException
异常(类型转换异常),在实际运行时则运行的是子类中的方法
具体分析
例:有一个Animal
的父类,有一个move()
方法,一个Dog
子类,重写了父类的move
方法
编译阶段:
对于编译器来说,编译器只知道dog
这个对象的类型是Animal
,所以编译器在检查语法的时候只会去Animal.class
字节码文件中找父类的move()
方法,找到了就绑定上move()
方法,编译通过,静态绑定成功!(编译阶段属于静态绑定)
运行阶段:
在运行阶段中,实际上堆内存中创建的java对象是Dog
的对象,所以运行move()
方法时,实际参与的是一只dog
,是对Dog
对象中重写的move()
方法的调用。(运行阶段绑定属于动态绑定)
向上转型
向上转型(Upcasting)是指将子类的引用赋值给父类的变量的过程,又或者说是将一个对象的类型转换为它的父类型或接口类型。这个过程也称为向上转型。这种转型是自动的,并且在大多数情况下都是安全的。
特点:
- 向上转型是安全的:由于父类包含了子类的所有方法和属性,所以向上转型后对象仍然可以使用所有的方法和属性
- 向上转型会丢失子类特有的方法和属性:由于向上转型后的对象只能访问父类的方法和属性,所以子类特有的方法和属性将不再可用
- 向上转型可以使用 instanceof 运算符进行检测:可以使用 instanceof 运算符来检测对象是否是特定类型的实例。这对于在向上转型后确定对象的类型很有用
- 向上转型可以使用强制类型转换进行恢复:如果需要访问子类特有的方法和属性,则可以使用强制类型转换将对象转回原来的子类类型。但是,这需要进行类型检查,以确保转换是安全的
例:假设有一个类型为Dog
的对象,它有一个父类型为Animal
。在这种情况下,可以将Dog
对象向上转型为Animal
类型,如下所示:
在这种情况下,animal
变量仍然指向原来的Dog
对象,但是可以通过animal
变量调用的方法受到限制。例如,如果Dog
类中有一个名为run
的方法,则无法通过animal
变量调用这个方法,因为Animal
类中没有这个方法,这个方法是子类Dog
特有的方法。
向下转型
向下转型(downcasting)是指将一个对象的引用从父类型向子类型转型。因为它可以让我们在不改变对象本身的情况下改变对对象的引用。这种转型不是自动的,且不安全!
特点:
- 只有向上转型过的对象才可以向下转型
- 向下转型是不安全的:由于向下转型后的对象会访问子类特有的方法和属性,所以如果对象本身不是子类的实例,就会发生类型转换异常
- 向下转型可以使用 instanceof 运算符进行检测:可以使用 instanceof 运算符来检测对象是否是特定类型的实例。这对于在向下转型前确定对象的类型很有用
- 向下转型必须使用强制类型转换:必须使用强制类型转换将对象转换为子类类型。但是,这需要进行类型检查,以确保转换是安全的
例:假设有一个类Animal
和它的子类Dog
,并且有一个Animal
类型的对象animal
,我们可以将animal
向下转型为Dog
类型,如下所示:
但是,如果animal
对象本身不是Dog
类的实例,animal
是其他类new
实例化出来的对象,在这种情况下,尝试向下转型将会导致类型转换异常ClassCastException
。如下所示:
因此,在进行向下转型之前,通常会使用instanceof
运算符来检测对象是否是特定类型的实例,以确保转换是安全的。
instanceof
运算符的使用
可以在运行阶段动态判断引用指向的对象的类型,instanceof
运算符的运算结果只能是布尔类型
规范:任何时候,任何地点,对类型进行向下转型时,一定要使用instanceof
运算符进行判断
语法
例1: a 是一个引用, a 变量保存了内存地址指向了堆中的对象
-
a instanceof Animal
运算结果为true
a
引用指向的堆内存中的java对象是一个Animal
-
a instanceof Animal
运算结果为true
: -
a
引用指向的堆内存中的java对象不是一个Animal
例2:父类Animal
,子类1Cat
,子类2Dog
。
使用instanceof
运算符进行判断
什么时候需要使用向下转型?
父类需要访问子类中特有的方法时需要向下转型
多态在开发中的实际应用
多态在开发中的作用:降低程序的耦合度,提高程序的扩展力
编写一个程序模拟主人
喂养宠物
的场景:
提示1:
- 主人类:Master
- 宠物类:Pet
- 宠物类子类:Dog、Cat、fish
提示2:
- 主人应该提供一个喂养的方法:
feed()
- 宠物应该有一个吃的方法:
eat()
要求:主人类中只提供一个feet()
方法,达到喂养各种类型宠物的目的
编写测试程序:
- 创建主人对象
- 创建各种宠物对象
- 调用主人的
feed()
方法喂养不同的宠物,观察执行结果
编写过程:
-
创建主人类
-
创建宠物类,实现
eat()
方法 -
创建宠物类子类,重写父类的
eat()
方法-
Dog类
-
Cat类
-
Fish类
-
-
在主人类中添加
feed()
方法实现喂养多种类型的宠物 -
编写测试类开始测试
-
输出结果
__EOF__

本文链接:https://www.cnblogs.com/WNAOII/p/17028161.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」