Java 面试题之面向对象(OOP) 部分(一)

2.OOP

2.1.什么是 OOAD?OOAD 怎么实现?

      OOAD(Object Orient Analysis Design,面向对象的分析与设计)是现代软件企业广为采用的一项有效技术。OOAD 方法要求在设计中要映射现实世界中指定问题域的对象和实体,例如:顾客、汽车和销售人员等。这就需要设计要尽可能的接近现实世界,即以最自然的方式表述实体。

      使用UML建模语言创建系统的分析模型与设计模型是 OOAD 实现的主要手段。

2.2.请分别叙述类及对象的创建模式?

      总共有五种创建模式,分别是单例模式,工厂方法模式,抽象工厂模式,建造者模式,原型模式,其中工厂方法模式是类创建模式,其余四种是对象创建模式。下面对各个模式的介绍。

      单例模式(Singleton,对象创建模式):单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供整个实例。

      工厂方法模式(Factory Method,类创建模式):核心工厂类不再负责所有产品的创建,而是将具体的工作交给子类去做,成为一个抽象工厂角色,仅负责给出具体工厂类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。

      抽象工程模式(Abstract Factory,对象创建模式):抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品簇的产品对象。简单来说,是创建一组相关或相互依赖的复杂对象。

      建筑模式(Builder,对象创建模式):将产品的内部表象和产品的生成过程分割开来,从而使一个建筑过程生成具有不同的内部表象的产品对象。建筑模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节。建筑模式可以强制实行一种分步骤进行的建造过程。

      原型模式(Prototype,对象创建模式):通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的方法创建出更多同类型的对象。原始模型模式允许多态的增加或减少产品类,产品类不需要非得有任何事先确定的等级结构,原始模型模式适用于任何的等级结构。缺点是每一个类都必须配备一个克隆的方法。

2.3.什么时候需要改写 hashCode()方法?为什么?

      在改写 equals() 方法的时候总是要改写 hashCode 方法。如果不这样做的话,就会违反 Object 类的 hashCode 方法的通用约定,导致这个类无法与所有基于散列值的集合类结合在一起正常工作,包括 HashMap、HashSet 和 HashTable

2.4.继承和重载的区别?

      Java的继承是子类对象继承父类的成员属性和方法,只允许单继承。

      在继承的过程中可以实现方法的重写/覆盖,即子类定义的一个方法,覆盖从父类哪里继承来的同名的方法。每当子类对象调用该方式时都是子类自己定义的方法,只有使用 super 关键字或者用父类名作为前缀时,才会调用父类原来的方法。方法覆盖时,子类应与父类拥有完全相同的方法名,返回值类型和参数列表,子类中的覆盖方法不能拥有比父类被覆盖的方法更严格的访问权限。

      方法重载要求室友两个或多个方法名相同,只是方法参数列表不同的方法,它对返回值的类型没有要求。

2.5.abstract class 和 interface 有什么区别?

      1)从语法角度来说,抽象类中可以拥有自己的数据成员,也可以拥有非抽象的方法,并赋予行为;而接口一般不定义成员数据,且所有的方法都是抽象的,不能拥有默认的行为。

      2)从编程角度来说,抽象类表示的是一种继承关系,一个类只能使用一次继承关系,但是一个类可以实现多个接口。

      3)从问题域角度来说,抽象类体现的继承关系中,父类和派生类在概念上本质应该是相同的;而接口仅仅定义了一种契约。

2.6.面向对象的三个基本特征

      封装、继承、多态

2.7.叙述对面向对象的特征的理解

      1)抽象:抽象就是忽略一个主题中的与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用注意部分细节。抽象主要包括两个方面:一是抽象的属性,二是抽象的方法

      2)封装:封装是把数据和过程包围起来,对数据的访问只能通过已定义的界面。面向对象设计始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。

      3)继承:继承是一种联结类的层次模型,允许和鼓励类的重用,它提供一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类中继承属性和方法,并且子类可以修改和添加新的方法使之适应特殊的需要。

      4)多态性:多态性是指允许不同类的对象对同一消息作出响应,是类的多种表现方式,比如同名不同参数。多态性包括参数多态性和包含多态性,具体表现在重载和复写。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。

2.8.子类如何调用父类的成员和方法?

      子类可以直接调用父类中未被重写的方法;若子类重写了父类方法,可以在子类中通过"super.方法名()"的形式调用父类方法。创建子类实例时默认调用父类无参的构造函数,若调用有参的构造方法可以在子类构造方法第一行通过"super(参数)"形式调用

2.9.重载 Overload 和重写 Override 有什么区别?

      1)范围:重载发生在同个类中,而重写发生在有继承关系的父类和子类中

      2)参数:重载参数不同,重写参数相同

      3)目的:重载是为了多态性,重写是为了覆盖/修改功能

 2.10.构造器 Constructor 是否可被 override?

      构造器不能被继承,因此不能被重写 Override,但是可以被重载 Overload

2.11.String 类是否可以被继承?

      不可以。String 是 final 类,故不可继承。

2.12.简述 static 关键字的作用

       static 表示“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态代码块。只要含有 static 的类被加载,那么 JVM 就能根据类名在运行时数据区的方法区找到他们。因此,static 成员可以在它的任何对象创建之前访问,无需引用任何对象。

      1)static 修饰的成员变量不属于对象,而属于类,且只有“一份”,存在方法区中,而不是堆中,可通过类名进行访问。

      2)static 修饰的成员方法可直接通过类名访问。static 方法的主要作用在于提供一些“工厂方法”和“工具方法”等。

      3)static 修饰的代码块属于静态代码块,在类加载期间只执行一次,可以用来在软件中加载静态资源,以提高加载效率。

2.13.解释 Java 中以下关键字的含义及用法:abstract、extends、final/finally、implements、import、instanceof、synchronized、throw/throws

      1)abstract:抽象,修饰类和方法。含有 abstract 方法的类是抽象类,抽象方法主要是为了让子类继承实现。

      2)extends:继承,子类通过继承父类来添加变量和方法,也可以覆写子类的方法,子接口继承父接口来添加方法

      3)final/finally:final 用于定义常量。finally 用来执行一段代码,不管在前面定义的 try 语句是否有异常或运行时错误发生,都执行。

      4)implement:在类的声明中是可选的,用来指明当前类实现的接口。

      5)import:在源文件的开始部分指明将要引入的类或者包。

      6)instanceof:用来判断一个对象的实际类型。

      7)synchronized:修饰方法或代码块。防止多个线程同时访问这个类中的 synchronized 块。

      8)throw/throws:throw 允许用户抛出一个 exception 对象或者任何实现 throwable 的对象。throws 用在方法的声明中来说明哪些异常,这个方法是不处理的,而是提交到程序的更高一层。

2.14.简述静态变量和实例变量的区别?

      静态变量也成为类变量,归全类共有,它不依赖与某个对象,可直接通过类名访问;而实例变量必须依依存于某一个实例,只能通过对象才能访问到它。

2.15.GC 是什么?为什么要有 GC?简述优点及原理

      GC 垃圾收集的意思,garbage Collection。内存处理是编程人员容易出现问题的地方,忘记和错误的内存回收容易导致程序或系统不稳定甚至崩溃,java 提供的 GC 功能可以自动检测对象是否超过作用于从而达到自动回收内存的目的。Java 程序员编程时,不用考虑变量不用时2释放内存,JVM 可以自动判断并收集到垃圾。

       列举两种垃圾回收机制:

      1)增量收集器:增量收集器把堆栈氛围多个域,每次仅从一个域收集垃圾。这会造成较小的应用程序中断。

      2)分代收集器:这种收集器把堆栈分为两个或多个域,用以存放不同寿命的对象。JVM 生成的新对象一般放在其中的某个域中。过一段时间,继续存在的对象将获得试用期并转入更长寿命的域中。分代收集器对不同的域使用不同的算法以优化性能。

2.16.接口是否可继承接口?抽象类是否可实现接口?抽象类是否可继承实体类?

      接口可继承接口;抽象类可以实现接口;抽象类可以继承实体类。

2.17.public class MyString extends String{} 有什么错?

      String 类是 final 类,不可以被继承。

2.18.子类 A 继承父类 B,A a = new A();则父类 B 构造函数、父类 B 静态代码块、父类 B 非静态代码块、子类 A 构造函数、子类 A 静态代码块、子类 A 非静态代码块,执行的先后顺序是?

       顺序为:B 静 -》 A 静 -》B 非静 -》 B 构造 -》 A 非静 -》 A 构造

2.19.简述“类(class)”、“类库(class library)”、“包(package)”、“jar文件”这四个概念间的联系?

      1)实际上是对某种类型的对象定义变量和方法的原型。他表示对现实生活中一类具有共同特征的事情的抽象。

      2)为了更好地组织类,Java 提供了机制。包(package)是类的容器,用于分隔类名空间。

      3)类库是用来实现各种功能的类的集合

      4)jar 文件用于发布和使用类库,可被编译器和 JVM 直接使用。

2.20.heap 和 stack 有什么区别?

      堆和栈都是 Java 用来在内存中存放数据的地方,二者区别在于:

      1)存放基本类型变量和对象引用,当超过作用域后释放;堆存放 new 出来的对象和数组。

      2)可以动态的分配内存大小,生存期也不必事先告诉编译器,Java 的垃圾收集器会自动收走这些不再使用的数据。存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈的存取速度比堆要快,仅次于直接位于 CPU 中的寄存器。堆由于要在运行时态动态分配内存,存取速度较慢。

      3)数据可以共享,如字面量 2 等;堆不可以。

      4)是一种线性集合,其添加和删除元素的操作应在同一段完成,栈按照先进后厨的方式进行处理;对地址是不连续的,可随机访问。

发布了7 篇原创文章 · 获赞 10 · 访问量 3002

猜你喜欢

转载自blog.csdn.net/qq_40798777/article/details/104342766
今日推荐