java面试笔记二:java的面向对象
发布日期:2021-05-28 16:48:17 浏览次数:9 分类:技术文章

本文共 5494 字,大约阅读时间需要 18 分钟。

java面试笔记二:面向对象

  1. 面向对象和面向过程的区别
    • 过程就是函数,就是写方法,就是方法的一种实现。
    • 对象就是将函数,属性的一种封装。用人们思考习惯的方式思考问题。
  2. 匿名对象
    • 即:创建对象时没有指定引用名,直接new拿来使用,就是匿名对象,只适合一次调用,
    • 当对象成员被多次调用时,不能使用匿名对象。必须给对象起名字。
  3. 类的成员
    • 分为成员变量和成员函数。
  4. 成员变量和局部变量的区别:
    • 成员变量直接定义在类中,局部变量定义在方法中,参数上,语句中。
    • 成员变量在整个类中有效,局部变量只在方法中有效,
    • 成员变量存在于堆内存中,随着对象的产生而产生。局部变量存在于栈内存中,随着所属区域的运行而存在。结束而释放。
  5. 构造函数
    • 名称和类名相同,
    • 不需要定义返回值类型,
    • 没有具体的返回值,用于实例化对象。
    • 一个类在定义时,如果没有定义过构造函数,那么该类中会自动生成一个空参数的构造函数,为了方便该类创建对象,完成初始化。如果在类中自定义了构造函数,那么默认的构造函数就没有了。
    • 一个类中,可以有多个构造函数,因为它们的函数名称都相同,所以只能通过参数列表来区分。所以,一个类中如果出现多个构造函数。它们的存在是以重载体现的。
    • 构造函数在对象创建时被调用,成员函数是对象创建后需要调用才会执行。
    • 什么时候使用构造函数:分析事物时,发现具体事物一出现,就具备了一些特征,那就将这些特征定义到构造函数内。
  6. 创建一个对象的执行过程:
    • 先将硬盘上指定位置的Person.class文件加载进内存。即:加载到方法区
    • 执行main方法时,在栈内存中开辟了main方法的空间(压栈—进栈),然后在main方法的栈区分配了一个变量p
    • 在堆内存中开辟一个实体空间,分配了一个内存首地址值。new
    • 在该实体空间中进行属性的空间分配,并进行了默认初始化。
    • 对空间中的属性进行显示初始化。
    • 进行实体的构造代码块初始化。
    • 调用该实体对应的构造函数,进行构造函数初始化。
    • 将首地址赋值给p ,p变量就引用了该实体。(指向了该对象)
  7. 静态代码块、构造代码块、构造函数、普通代码块执行顺序
    • 当加载类到内存时,静态代码块被执行。
    • 接着执行main方法
    • 执行构造代码块,构造代码块相比静态代码块少了一个static修饰
    • 执行无参构造函数,
    • 执行普通代码块
    • 即:静态代码块>main函数>构造代码块>无参构造函数>普通代码块。
  8. 父类和子类执行顺序
    • 父类分别有父类静态代码块,父类构造函数代码块,父类构造函数
    • 子类分别有子类静态代码块,子类构造函数代码块,子类构造函数
    • 执行顺序:父类静态代码块>子类静态代码块>父类构造代码块>父类构造函数>子类构造代码块>子类构造函数

封装

  1. 封装原则:将不需要对外提供的内容都隐藏起来,把属性都隐藏,提供公共方法对其访问。
  2. this:代表对象,就是所在函数所属对象的引用。
    • 哪个对象调用了this所在的函数,this就代表哪个对象,就是哪个对象的引用。在定义功能时,如果该功能内部使用到了调用该功能的对象,这时就用this来表示这个对象。
    • this 还可以用于构造函数间的调用。
    • 调用格式:this(实际参数); this对象后面跟上 . 调用的是成员属性和成员方法(一般方法);this对象后面跟上 () 调用的是本类中的对应参数的构造函数。
    • this调用构造函数必须放在第一行。
Static 关键字的特点和缺点
  1. Static关键字的特点
    • 想要实现对象中的共性数据的对象共享。可以将这个数据进行静态修饰
    • **被静态修饰的成员,可以直接被类名所调用。**也就是说,静态的成员多了一种调用方式。类名.静态方式
    • 静态随着类的加载而加载。而且优先于对象存在
  2. Static关键字的缺点
    • 有些数据是特有的,是不能被静态修饰的,因为静态修饰,就会共享了,因此在定义静态时,必须明确这个数据是否是被对象共享的。
    • 静态方法只能访问静态成员,不能访问非静态成员,因为静态方法在加载类时,已经进入内存了。优先于对象。
    • 静态方法不能使用this,super关键字,this代表对象,静态方法调用时,说不定还不存在对象。
    • 主函数是静态的。
  3. Static关键字能修饰什么
    • 修饰代码块,为静态代码块
    • 修饰类:只能是静态内部类
    • import static java.long.Math.*表示指定导入这个包中的静态资源,可读性不高。
    • 修饰成员变量和方法。
  4. 成员变量和静态变量的区别
    • 所属对象不同:成员变量所属对象,静态变量所属于类。属于类变量
    • 成员变量存在堆内存中,静态变量存在于方法区中。
    • 成员变量随着对象创建而产生,随着对象被回收而回收
    • 静态变量随着类的加载而产生,随着类的消失而消失。
    • 成员变量只能被对象调用,而静态变量可以被类调用也可以被对象调用。
    • 可以看做成员变量是对象的特有数据,静态变量是对象的共享数据。
    • 静态变量的生命周期更长。
单例设计模式
  1. 解决问题:保证一个类在内存中的对象的唯一性
    • 例如:多程序读取一个配置文件,建议配置文件封装成对象,会方便操作其中数据,但是又要保证多个程序读到的是同一个配置文件对象,就需要该配置文件对象在内存中是唯一的。
    • Runtime()方法就是单例设计模式进行设计的。
  2. 如何保证对象唯一性:
    • 不让其他程序或者类创建该类对象。
    • 在本类中创建一个本类对象。
    • 对外提供方法,让其他程序获取这个对象。
  3. 步骤:
    • 因为创建对象需要构造函数初始化,让本类中的构造函数私有化,其他程序就无法再创建该类对象。
    • 就在类中创建一个私有化的静态的本类对象。
    • 定义一个方法,让外界获取该对象。
  4. 代码体现:
    • 私有化构造函数
    • 创建私有并静态的本类对象
    • 定义公有并静态的方法,返回该对象。
  5. 饿汉式
class Single{
private Single(){
} //私有化构造函数。 private static Single s = new Single(); //创建私有并静态的本类对象。 public static Single getInstance(){
//定义公有并静态的方法,返回该对象。 return s; }}
  1. 懒汉式
class Single2{
private Single2(){
} private static Single2 s = null; public static Single2 getInstance(){
if(s==null) s = new Single2(); return s; }}

继承

  1. 继承的好处
    • 提高代码的复用性
    • 让类与类之间产生关系,提供了另一个特征多态的前提。
  2. java只支持单继承,但支持多重继承,即A继承B,B继承C,C继承D
子类出现后类成员的特点
  1. 成员变量
    • 当子父类出现相同的属性时,子类类型的对象,调用该属性,值是子类属性值。(就近原则)
    • 如果想调用父类中的属性值,需要用关键字super
    • this:代表本类对象引用
    • super:代表子类所属的父类的内存引用。
  2. 成员函数
    • 当子父类有同样的方法时,建立子类对象,会运行子类方法,相当于父类中的方法被覆盖掉。
  3. 构造函数
    • 发现子类构造函数运行时,先运行父类构造函数。因为:子类构造函数第一行隐含着 super()方法,调用父类的构造函数。子类继承父类,要继承父类的数据,因此必须要看父类是如何对数据进行初始化的,所以子类在进行对象初始化时,先调用父类的构造函数。
    • 子类的所有构造函数都会默认访问父类中的空参数的构造函数,因为每一个子类构造内第一行都有默认的语句super()
    • 如果父类中没有空参数的构造函数;那么子类的构造函数内,必须通过super语句指定要访问的父类中的构造函数。
    • 如果子类构造函数中用this来指定调用子类自己的构造函数,那么被调用的构造函数也一样会访问父类中的构造函数。
    • super()和this()在构造函数中只能出现一个,因为两者都是定义在构造函数的第一行,第一行只能有一个,super(),this()都是调用构造函数,构造函数用于初始化,初试化要完成因此要放在第一行。
  4. 继承关系判断:
    • 如果被继承后,被继承的类的功能都可以被孩子所具备,那么继承成立,如果不是,不可以被继承。
  5. 方法覆盖(重写):
    • 子类覆盖父类时,必须保证,子类方法的权限必须大于等于父类方法权限可以实现继承,否则编译失败。
    • 覆盖时,要么都静态,要么都不静态。(静态只能覆盖静态,或者被静态覆盖)
  6. 继承的弊端:
    • 打破了封装性,可以通过关键字final来解决。
  7. final关键字:
    • 是一个修饰符,可以修饰类,方法,变量。
    • 被final修饰的类是一个最终类,不可以被继承。
    • final修饰的方法是一个最终的方法,是不可以被重写的。
    • 被final修饰的变量是一个常量,只能赋值一次。
    • 加了final,程序更为严谨。常量名称定义时,有规范,所有字母都大写,如果由多个单词组成,中间用 _ 连接。
抽象类
  1. 是类和方法不断抽取形成的。
  2. 特点:
    • 抽象方法,抽象类,必须由abstract关键字修饰。
    • 抽象方法只能定义方法声明,没有方法实体。
    • 抽象类不能被实例化。
    • 抽象类中可以有抽象方法,也可以有非抽象方法。
    • 抽象类只有被子类继承,并被子类重写方法子类才能实例化,否则还是抽象类。
  3. 抽象类细节:
    • 抽象类中有构造函数,用于给子类对象进行初始化。
    • 抽象关键字和final,private ,static不能共存。
    • 抽象类中可以不定义抽象方法,定义抽象方法的目的是为了不让类创建对象。
模板方法设计模式
  1. 解决问题:
    • 当功能内部一部分实现时确定,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
abstract class GetTime{
public final void getTime(){
  //此功能如果不需要复写,可加final限定 long start = System.currentTimeMillis(); code();   //不确定的功能部分,提取出来,通过抽象方法实现 long end = System.currentTimeMillis(); System.out.println("毫秒是:"+(end—start)); } public abstract void code();   //抽象不确定的功能,让子类复写实现}class SubDemo extends GetTime{
public void code(){
  //子类复写功能方法 for(int y=0; y<1000; y++){
System.out.println("y"); } }}

接口

  1. 由关键字interface定义
  2. 接口中包含的成员:
    • 全局常量,抽象方法。
    • 接口中的成员都有固定的修饰符
  3. 接口中有抽象方法,说明接口不可以被实例化,接口的实现类必须实现所有的抽象方法后该子类才可以实例化,否则该子类还是一个抽象类。
  4. 接口可以多实现,用于弥补类只能单继承的弊端。
  5. 接口与接口之间也可以存在继承关系。
  6. 接口是对外提供的原则,接口是功能的扩展,接口降低了耦合性。
接口和抽象类的特点分析
  1. 抽象类:一般用于描述一个体系单元,将一组共性内容进行抽取,特点:可以在类中定义抽象内容让子类实现,可以定义非抽象内容让子类直接使用。它里面定义的都是一些体系中的基本内容。
  2. 接口:一般用于定义对象的扩展功能,是在继承之外还需要这个对象具备的一些功能。
  3. 抽象类和接口的共性:都是不断向上抽取的结果。
抽象类和接口的区别:
  1. 抽象类只能被继承,而且只能单继承。
  2. 接口需要被实现,是多实现。
  3. 抽象类可以定义非抽象方法,子类可以直接继承使用。
  4. 接口中都有抽象方法,需要子类实现。
  5. 抽象类使用的是is a关系,接口使用的是like a关系。
  6. 抽象类的成员 修饰符可以自定义,接口中的成员修饰符是固定的,全都是public.

多态

  1. 父类引用或者接口的引用指向了自己的子类对象。
  2. 多态提高了程序的扩展性,但是只能访问父类中具备的方法,不可以访问子类中特有的方法。访问有了局限性。
  3. 多态前提是:必须要有关系,比如继承,或者实现。
  4. 多态中父类对象调用的是子类重写后的方法,如果子类没有重写,那么相当于子类直接继承了父类的方法,就会调用该继承的方法,多态无法调用子类特有的方法。
  5. 关键字instanceof:用于判断一个对象是否属于指定的类型。格式:对象 instanceof 类型。
多态在子父类中成员上体现的特点:
  1. 成员变量:
    • 无论编译还是运行,成员变量参考的都是引用变量所属的类中的成员变量。
    • 即:成员变量—编译和运行都看左边。
  2. 成员函数:
    • 编译看左边,运行看右边。其实道理很简单,编译是为了检查代码有误错误 由于多态最终执行的是父类中具备的方法,那么编译时检查一下父类中有没有该方法就行了。运行时执行子类覆盖的方法。
  3. 静态函数:
    • 静态函数不属于哪个对象,是属于类的内容。因此调用静态方法的引用是哪个类的引用就是那个类的静态方法。
    • 静态函数–编译运行都看左边。

转载地址:https://blog.csdn.net/qq_33322074/article/details/90177690 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:java面试笔记三:Object类、内部类、异常、四种权限修饰符的理解、包的导入
下一篇:java面试总结一:基础篇

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年02月28日 17时57分44秒