Java基础知识

  • 面向对象的技术
    • 1. 面向对象与面向过程有什么区别
    • 2. 面向对象有哪些特征
    • 3. 什么是继承
    • 4. 组合和继承的区别
    • 5. 多态的实现机制
    • 6. 重载和覆盖有什么区别
    • 7. 抽象类(abstract class)与接口(interface)有什么异同
    • 8. 内部类有哪些
    • 9. 如何获取父类名
    • 10. this与super的区别

上一篇:Java基础知识(一) 基本概念

面向对象的技术

1. 面向对象与面向过程有什么区别

具体而言,面向对象和面向过程主要有以下方面的不同:

  1. 出发点不同。面向对象方法是用符合常规思维的方式来处理客观世界的问题,强调把问题域的要领直接映射到对象及对象之间的接口上。而面向过程方法强调的则是过程的抽象化与模块化,它是以过程为中心构造或处理客观世界问题的。
  2. 层次逻辑关系不同。面向对象方法则是用计算机逻辑来模拟客观世界中的物理存在,以对象的集合类作为处理问题的基本单位,尽可能地使计算机世界向客观世界靠拢,以使问题的处理更清晰直接,面向对象方法是用类的层次结构来体现类之间的继承和发展。而面向过程方法处理问题的基本单位是能清晰准确地表达过程的模块,用模块的层次结构概括模块或模块间的关系与功能,把客观世界的问题抽象成计算机可以处理的过程。
  3. 数据处理方式与控制程序方式不同。面向对象方法将数据与对应的代码封装成一个整体,原则上其他对象不能直接修改其数据,即对象的修改只能由自身的成员函数完成,控制程序方式上是通过“事件驱动”来激活和运行程序。而面向过程方法是直接通过程序来处理数据,处理完毕后即可显示处理结果,在控制程序方式上是按照设计调用或返回程序,不能自由导航,各模块之间存在着控制与被控制、调用与被调用的关系。
  4. 分析设计与编码转换方式不同。面向对象方法贯穿于软件生命周期的分析、设计及编码中,是一种平滑过程,从分析到设计再到编码是采用一致性的模型表示,即实现的是一种无缝连接。而面向过程方法强调分析、设计及编码之间按规则进行转换,贯穿于软件生命周期的分析、设计及编码中,实现的是一种有缝的连接。

2. 面向对象有哪些特征

面向对象的主要特征包括继承、封装和多态。

  1. 继承。继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),)而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且派生类可以修改或增加新的方法使之更适合特殊的需要。
  2. 封装。封装是指将客观事物抽象成类,每个类对自身的数据和方法实行保护。类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
  3. 多态。多态是指允许不同类的对象对同一消息作出响应。多态包括参数化多态和包含多态。多态性语言具有灵活、抽象、行为共享、代码共享等优势,很好地解决了应用程序函数同名问题。

3. 什么是继承

继承是面向对象中的一个非常重要的特性。通过继承,子类可以使用父类中的一些成员变量与方法,从而能够提高代码的复用性,提高开发效率。在 Java 语言中,被继承的类叫基类(superclass)或父类,继承基类或父类的类叫派生类或子类(subclass)。继承是通过 extends关键字来实现的,使用格式为:class 子类名 extends 父类名。
继承主要有如下几个特性:

  1. Java语言不支持多重继承,也就是说,子类至多只能有一个父类,但是可以通过实现多个接口来达到多重继承的目的。
  2. 子类只能继承父类的非私有(public 与 protected)成员变量与方法。
  3. 当子类中定义的成员变量和父类中定义的成员变量同名时,子类中的成员变量会覆盖父类的成员变量,而不会继承。
  4. 当子类中的方法与父类中的方法有相同的函数签名(相同的方法名,相同的参数个数),子类将会覆盖父类的方法,而不会继承。

4. 组合和继承的区别

组合和继承是面向对象中两种代码复用的方式。组合是指在新类里面创建原有类的对象,重复利用已有类的功能。继承是面向对象的主要特性之一,它允许设计人员根据其他类的实现来定义一个类的实现。组合和继承都允许在新的类中设置子对象(subobject),只是组合是显式的,而继承则是隐式的。组合和继承存在着对应关系:(组合中的整体类和继承中的子类对应,组合中的局部类和继承中的父类对应。

二者的区别在哪里呢?首先分析一个实例。Car 表示汽车对象,Vehicle 表示交通工具对象,Tire 表示轮胎对象。三者的类关系如图所示。

从图4-2 中可以看出,Car 是 Vehicle 的一种,因此是一种继承关系(又被称为“is - a”关系)而 Car 包含了多个 Tire,因此是一种组合关系(又被称为“has -a”关系)。其实现方式如下:

继承

class Vehicle {}class Car extends Vehicle {}

组合

class Tire{}
class Car{private List<Tire> tires = new ArrayList<>();
}

既然继承和组合都可以实现代码的重用,那么在实际使用时又该如何选择呢?一般情况下,遵循以下两点原则。

  1. 除非两个类之间是“is-a”的关系,否则不要轻易地使用继承,不要单纯地为了实现代码的重用而使用继承,因为过多地使用继承会破坏代码的可维护性,当父类被修改时,会影响到所有继承自它的子类,从而增加程序的维护难度与成本。
  2. 不要仅仅为了实现多态而使用继承,如果类之间没有“is-a”的关系,可以通过实现接口与组合的方式来达到相同的目的。设计模式中的策略模式可以很好地说明这一点,采用接口与组合的方式比采用继承的方式具有更好的可扩展性。

由于 Java 语言只支持单继承,如果想同时继承两个类或多个类,在 Java 中是无法直接实现的。同时,在 Java 语言中,如果继承使用太多,也会让一个 class 里面的内容变得臃肿不堪。所以,在 Java 语言中,能使用组合就尽量不要使用继承。

5. 多态的实现机制

多态是面向对象程序设计中代码重用的一个重要机制,它表示当同一个操作作用在不同对象时,会有不同的语义,从而会产生不同的结果,例如,同样是执行“+”操作,“3 +4”用来实现整数相加,而“3”+“4”却实现了字符串的连接。在 Java语言中,多态主要有以下
两种表现方式:

  1. 方法的重载(overload)重载是指同一个类中有多个同名的方法,但这些方法有着不同的参数,因此在编译时就可以确定到底调用哪个方法,它是一种编译时多态。重载可以被看作一个类中的方法多态性。
  2. 方法的覆盖(overide)子类可以覆盖父类的方法,因此同样的方法会在父类与子类中有着不同的表现形式。通过方法覆盖实现的多态也可以被称为运行时多态,示例如下。
class Vehicle {public void run(){System.out.println("我可以裁人");}
}class Car extends Vehicle {@Overridepublic void run(){System.out.println("我可以裁人,在地上跑");}
}class Airplane extends Vehicle {@Overridepublic void run(){System.out.println("我可以裁人,在天上飞");}
}/*** 创建时间 2021/7/30 11:05* 多态的测试* @author Ye* @version 1.0*/
public class Test4 {public static void main(String[] args) {Vehicle vehicle1 = new Car();Vehicle vehicle2 = new Airplane();vehicle1.run();vehicle2.run();}
}

运行截图:

6. 重载和覆盖有什么区别

重载(overload)和覆盖(override)是Java 多态性的不同表现方式。其中,重载是在一个类中多态性的一种表现,是指在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型。在使用重载时,需要注意以下几点:

  1. 重载是通过不同的方法参数来区分的,例如不同的参数个数、不同的参数类型或不同的参数顺序。
  2. 不能通过方法的访问权限、返回值类型和抛出的异常类型来进行重载。
  3. 对于继承来说,如果基类方法的访问权限为 private,那么就不能在派生类对其重载;如果派生类也定义了一个同名的函数,这只是一个新的方法,不会达到重载的效果。

覆盖是指派生类函数覆盖基类函数。覆盖一个方法并对其重写,以达到不同的作用。在使用覆盖时需要注意以下几点:

  1. 派生类中的覆盖方法必须要和基类中被覆盖的方法有相同的函数名和参数。
  2. 派生类中的覆盖方法的返回值必须和基类中被覆盖白方法的返回值相同。
  3. 派生类中的覆盖方法所抛出的异常必须和基类或是其子类中被覆盖的方法所抛出的异常一致。
  4. 基类中被覆盖的方法不能为 private,否则其子类只是定义了一个方法,并没有对其覆盖。

重载与覆盖的区别主要有以下几个方面:

  1. 覆盖辈子类和父类之间的关系,是垂直关系。重载是同一个类中方法之间的关系,是水平关系。
  2. 覆盖只能由一个方法或只能由一对方法产生关系;重载是多个方法之间的关系。
  3. 覆盖要求参数列表相同;重载要求参数列表不同。
  4. 覆盖关系中,调用方法体是根据对象的类型(对象对应存储空间类型)来决定而重载关系是根据调用时的实参表与形参表来选择方法体的。

7. 抽象类(abstract class)与接口(interface)有什么异同

如果一个类中包含抽象方法那么这个类就是抽象类。在 Java 语言中,可以通过把类或者类中的某些方法声明为 abstract
(abstract 只能用来修饰类或者方法,不能用来修饰属性)来
表示一个类是抽象类。接口就是指一个方法的集合接口中的所有方法都没有方法体,在 Java语言中,接口是通过关键字 interface 来实现的。

抽象类(abstract class)和接口(interface)都是支持抽象类定义的两种机制(注意:此句中的前后两个抽象类的意义不一样,前者表示的是一个实体,后者表示的是一个概念)。二者具有很大的相似性,甚至有时候是可以互换的。但同时,二者也存在很大的区别。

只要包含一个抽象方法的类就必须被声明为抽象类,抽象类可以声明方法的存在而不去实现它,被声明为抽象的方法不能包含方法体。在实现时,必须包含相同的或者更低的访问级别(public->protected->private)。抽象类在使用的过程中不能被实例化,但是可以创建一个对象使其指向具体子类的一个实例。抽象类的子类为父类中的所有抽象方法提供具体的实现,否则它们也是抽象类。接口可以被看作抽象类的变体。接口中的所有方法都是抽象的可以通过接口来间接地实现多重继承。接口中的成员变量都是 static final 类型,由于抽象类可以包含部分方法的实现,因此,在一些场合下抽象类比接口存在更多的优势。

接口与抽象类的相同点如下:

  1. 都不能被实例化
  2. 接口的实现类或抽象类的子类都只有实现了接口或抽象类中的方法后才能被实例化。

接可与抽象类的不同点如下:

  1. Java 8 之前,接口只有定义,其方法不能在接口中实现,只有实现接口的类才能实现接口中定义的方法,而抽象类可以有定义与实现,即其方法可以在抽象类中被实现。
  2. 接口需要实现(用 implements),但抽象类只能被继承(用 extends)。一个类可以实现多个接中,但一个类只能继承一个抽象类,因此使用接口可以间接地达到多重继承的目的。
  3. 接口强调特定功能的实现,其设计理念是“has-a”关系;而抽象类强调所属关系,其设计理念为“is-a”关系。
  4. 接口中定义的成员变量默认为 publice static final,只能够有静态的不能被修改的数据成员,而且,必须给其赋初值,其所有成员方法都是public abstract 的,而且只能被这两个关键字修饰而抽象类可以有自己的数据成员变量,也可以有非抽象的成员方法,而且,抽象类中的成员变量默认为 default,本包可见,当然也可以被定义为 private、protected 和public,这些成员变量可以在子类中被重新定义,也可以被重新赋值,抽象类中的象方法
    (其前有 abstract修饰)不能用 private、static、symchronized、native 等访问修饰符修饰同时方法必须以分号结尾,并且不带花括号。所以,当功能需要累积时,用抽象类;不需要累积时,用接口。
  5. 接口被用于实现比较常用的功能,便于日后维护或者添加删除方法;而抽象类更倾向于充当公共类的角色,不适于日后重新对立面的代码进行修改。

8. 内部类有哪些

在 Java 语言中,可以把一个类定义到另外一个类的内部,在类里面的这个类就叫做内部类,外面的类叫做外部类。在这种情况下,这个内部类可以被看作外部类的一个成员(与类的属性和方法类似)。还有一种类被称为顶层(top-level)类,指的是类定义代码不嵌套在其他类定义中的类。

需要注意的是,嵌套类(Nested Class)与内部类(Iner Class)类似,只是嵌套类是C ++的说法,而内部类是 Java 的说法而已。内部类可以分为很多种,主要有以下 4 种:
静态内部类(statice inner class)、成员内部类(member inner class)、局部内部类(loeal inner class)和匿名内部类(anonymous inner class)。

静态内部类是指被声明为static的内部类,它可以不依赖于外部类实例而被实例化,而通常的内部类需要在外部类实例化后才能实例化。静态内部类不能与外部类有相同的名字,不能访向外部类的普通成员变量,只能访问外部类中的静态成员和静态方法(包括私有类型)

一个静态内部类,如果去掉“static”关键字,就成为成员内部类。成员内部类为非静态内部类,它可以自由地引用外部类的属性和方法,无论这些属性和方法是静态的还是非静态的。但是它与一个实例绑定在了一起,不可以定义静态的属性和方法。只有在外部的类被实例化后,这个内部类才能被实例化。需要注意的是,非静态内部类不能有静态成员。

局部内部类指的是定义在一个代码块内的类,它的作用范围为其所在的代码块,是内部类中最少使用到的一种类型。局部内部类像局部变量一样,不能被 public、protected。 private 以及 slatic 修饰,只能访问方法中定义为 final 类型的局部变量。对一个静态内部类,去掉其声明中的“static”天键字,将其定义移入其外部类的静态方法或静态初始化代码段中就成为了局部静态内部类。对一个成员类,将其定义移人其外部类的实例方法或实例初始化代码中就成为了局部内部类。局部静态内部类与静态内部类的基本特性相同。局部内部类与内部类的基本特性相同。

匿名内部类是一种没有类名的内部类,你使用关键字 class、extends、implements,没有构造函数,它必须继承(extends)其他类或实现其他接口。匿名内部类的好处是代码更加简洁、紧凑,但带来的问题是易读性下降。它一般应用于 GUI (Graphical User-Interface,图形用户界面)编程中实现事件处理等。在使用匿名内部类时,需要牢记以下几个原则:

  1. 匿名内部类不能有构造函数。
  2. 匿名内部类不能定义静态成员、方法和类。
  3. 匿名内部类不能是 public、protected、private、static。
  4. 只能创建匿名内部类的一个实例。
  5. 一个匿名内部类一定是在 new 的后面,这个匿名类必须继承一个父类或实现一个接口。
  6. 因为匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。

9. 如何获取父类名

可以通过Java的反射机制,使用this.getClass().getSuperclass().getName()来获取,代码如下所示:

package com.test.test;class Son{}
/*** 创建时间 2021/7/30 14:15* 获取父类名* @author Ye* @version 1.0*/
public class Test5 extends Son{public void test(){System.out.println(this.getClass().getSuperclass().getName());}public static void main(String[] args) {new Test5().test();}
}

运行截图:

10. this与super的区别

this 用来指向当前实例对象,它的一个非常重要的作用就是用来区分对象
的成员变量与方法的形参(当一个方法的形参与成员变量的名字相同时,就会覆盖成员变量)。

super 可以用来访问父类的方法或成员变量。当子类的方法或成员变量与父类有相同名字时也会覆盖父类的方法或成员变量,要想访问父类的方法或成员变量只能通过 super 关键字来访问。

参考:《Java程序员面试笔试宝典》 何昊、薛鹏、叶向阳 编著

Java基础知识(二) 面向对象的技术相关推荐

  1. JAVA基础知识二(面向对象、常用API)

    五.面相对象 1.面向对象 面向过程和面向对象都是解决问题的一种思想模式. 面向过程:指的就是按照一定的步骤,逐一执行,将问题进行解决. 相当于是一个 执行者 角色. 面向对象:指的就是找对象(对象内 ...

  2. Java基础知识(一) 基本概念

    Java基础知识 基本概念 1. Java语言的优点 2. Java与c/c++有什么异同 3. 为什么需要public static void main(String[] args)这个方法 4. ...

  3. java基础知识之整体内容概述(二)

    一.Java基础知识图解 1.1软件开发的介绍: 1.软件开发 软件,即一系列按照特定顺序组织的计算机数据和指令的集合.有系统软件和应用软件之分. 2.人机交互方式   (1)图形化界面(Graphi ...

  4. Java基础知识(二)(Object类的常用方法、日期时间类、System类、StringBuilder类、包装类、Collection集合、Iterator迭代器、泛型、list集Set接口...)

    文章目录 Java基础知识(二) 1.Object类的常用方法 1.1 toString方法 1.2 equals方法 1.3 Objects类 2.日期时间类 2.1 Date类 2.2 DateF ...

  5. CV:计算机视觉技术之图像基础知识(二)—图像内核的可视化解释

    CV:计算机视觉技术之图像基础知识(二)-图像内核的可视化解释 目录 图像内核的可视化解释 测试九种卷积核 官方Demo DIY图片测试 DIY实时视频测试 相关文章 CV:计算机视觉技术之图像基础知 ...

  6. CV:计算机视觉技术之图像基础知识(二)—以python的skimage和numpy库来了解计算机视觉图像基础(图像存储原理-模糊核-锐化核-边缘检测核,进阶卷积神经网络(CNN)的必备基础)

    CV:计算机视觉技术之图像基础知识(二)-以python的skimage和numpy库来了解计算机视觉图像基础(图像存储原理-模糊核-锐化核-边缘检测核,进阶卷积神经网络(CNN)的必备基础) 目录 ...

  7. 超详细的Java面试题总结(二)之Java基础知识篇

    系列文章: 超详细的Java面试题总结(一)之Java基本知识 超详细的Java面试题总结(二)之Java基础知识篇 超详细的Java面试题总结(三)之Java集合篇常见问题 超详细的Java面试题总 ...

  8. CV:计算机视觉技术之图像基础知识(二)—图像内核的九种卷积核可视化解释(blur/bottom sobel /emboss/identity /sobel /outline/sharpen)

    CV:计算机视觉技术之图像基础知识(二)-图像内核的九种卷积核可视化解释(blur/bottom sobel /emboss/identity /left sobel /outline/right s ...

  9. JAVA基础知识(四)面向对象基础

    文章目录 JAVA基础知识(四)面向对象基础 1. 类 2. 访问权限修饰符 3. `static`修饰符 3.1 静态代码块 4. `new`一个对象 5. 方法 5.1 `this` 5.2 方法 ...

最新文章

  1. PC2日记——坑爹的第一天2014/08/28
  2. Nodejs的安装及环境配置
  3. unlegal android,百度地图定位 Cordova 插件 cordova-plugin-baidumaplocation
  4. LeetCode练习及自己理解记录(1)
  5. 很多人理解互联网是“年轻化”
  6. 修改VS2017打开在文件中查找窗口以及格式化代码的快捷键
  7. SQL注入了解认识及注入方式
  8. Linux From Scratch docker lfs build 在Fedora 31 Linux上自己动手从源码一步一步编译出一个x86_64架构LFS Linux操作系统
  9. ctf逆向解题——re1
  10. Spring运行时值注入分析
  11. 如何批量一键下单寄快递
  12. 绘制带有角度的CAD图形
  13. 名帖116 文徵明 小楷《离骚经》
  14. 中小公司IT经理面试指南
  15. 【深度】广告流量分配HWM算法
  16. 带问题重读ijkPlayer
  17. 循环世界模型(Recurrent World Models)——真实世界建模的强化学习利器
  18. 怎么把图片拼接成长图,3招教你快速处理
  19. 任正非:新荣耀要做华为最强竞争对手;小米集团王嵋因错误表达致歉并请辞;全球 5G 网络三分之一来自中国技术 | EA周报...
  20. 按键精灵361插件后台脚本

热门文章

  1. matlab emd功率谱密度,基于EMD方法的地心运动时间序列分析
  2. ruoyi框架默认的导出Excel功能代码简析
  3. java学习总结(16.06.28)包装类和包装类的常用方法
  4. frida hook svc调用
  5. nepctf2021
  6. SAP 领料BAPI BAPI_GOODSMVT_CREATE 提示 短缺未限制使用的SL
  7. 2020华为春招面试:一面二面三面(一下午4h左右完成)已挂
  8. 如何查看计算机硬盘的软件内存条,内存检测工具,内存检测软件 - 内存条检测工具就用金山卫士 - 安全专题...
  9. 低成本成FS68001A、FS68003无线充SOC芯片
  10. 蓝牙连接打印机打印资产标签.