面向对象常见问题总结

重点回顾

1.==equals 的区别

== 作用于基本数据类型变量,比较的是其存储的值是否相等;作用于应用数据类型变量,比较的是所指向的对象的地址

equlse equlse方法的继承自Object类,如果没有对equlse方法进行重写的话,比较的是引用类型变量所指向的对象的地址。equlse重写比较的是两个对象的内容是否一样

2.hashcode()和equlse()

hashcode()的作用就是获取哈希码(散列码),通过获取到的哈希码来确认该对象在哈希表中的位置

为啥要有hashcode:

以hashcode如何检查重复为例,当把对象加入到hashset时,hashset会优先计算对象的hashcode值来判断加入的位置,同时也会和其他人已经加入的对象的hashcode值作比较,如果没有相同的hashcode,hashset会认为对象没有重复出现。如果有相同的hashcode,会调用equlse方法来检查hashcode相等的对象是否真的相同,如果相同hashset就不会让其加入,如果不同,就会重新散列到其他位置。这样就大大减少了euqlse比较额次数,提高了执行速度。

为啥重写equlse方法还要重写hashcode方法?

为啥两个对象有相同的hashcode值,它们不一定是相同的

因为hashcode所使用的杂凑算法也许刚好会让多个对象传回相同的杂凑值。越糟糕的杂凑算法越容易碰撞(不同的对象得到相同的hashcode)

3.自动装箱和自动拆箱

装箱:将基本数据类型转换为包装类型,通过调用包装器类的valueOf方法实现。

拆箱:将包装类型转换为基本数据类型,通过调用包装器类的xxxvalueOf方法实现,xxx代表基本数据类型。

4、8种数据类型的包装类和常量池

Byte,short,Integer,Long这四种包装类默认创建了数值[-128,127]的相应类型的缓存戴数据

Character创建了数值在[0,127]范围会创建新的对象

Boolean直接返回True和False。超出范围会创建新的对象

5、为啥java只会值传递?

概念:形参和实参

形参,是指在定义函数时使用的参数,目的是用于接收调用该函数时传入的参数。简单理解,就是所有函数(即方法)的参数都是形参。

实参,是指调用函数时,传递给函数的参数。

值传递和引用传递

值传递:是指在调用函数时,将实际参数复制一份传递给函数,这样在函数中修改参数时,不会影响到实际参数。其实,就是在说值传递时,只会改变形参,不会改变实参。

引用传递:是指在调用函数时,将实际参数的地址传递给函数,这样在函数中对参数的修改,将影响到实际参数。

这里,需要特别强调的是,千万不要以为传递的参数是值就是值传递,传递的是引用就是引用传递。也不要以为传递的参数是基本数据类型就是值传递,传递的是对象就是引用传递。 这是大错特错的。以前的我,一直都是这样认为的,现在想来真是太天真了。判断是值传递还是引用传递的标准,和传递参数的类型是没有关系。

6、重写和重载的区别

重载:发生在同一类型中,方法名必须相同,参数列表不同(参数类型不同,个数不同,顺序不同)返回值类型和访问修饰符可以不同,与方法返回值类型和访问修饰符无关,即重载的方法不能根据返回类型进行区分

重写:发生在父子类中,方法名,参数列表相同。访问修饰符的范围大于等于重写方法的修饰符,重写方法一定不能抛出新的检查异常或者必备重写方法声明更加宽泛的检查型异常,子类方法返回值类型应比父类方法返回值类型更小或者相等

7、深拷贝和浅拷贝

基本数据类型:数据直接存储在栈中;引用数据类型:存储在栈中的是对象的引用地址,真实的对象数据存放在堆内存里

浅拷贝:复制基本数据类型的数据值;引用数据类型,复制栈中对象的引用地址,不复制堆内存中的对象

深拷贝:复制基本数据类型的数据值;引用数据类型,复制栈中对象的引用地址并且在堆中开辟一个新的内存空间,在这个里面复制一个一摸一样的对象

浅拷贝实现Cloneable

实现Serialiable接口,然后自定义深拷贝方法deepClone();

9、构造器Constructor是否可以被Override(覆盖)

构造器(构造方法)Constructor 不能被继承,因此不能重写 Override,但可以被重载 Overload(不

同参数即可)。

每一个类必须有自己的构造函数,在创建对象时自动调用,如果添加有参构造函数后,默认无参构造函数则被覆

盖。子类不会覆盖父类的构造函数,但是在创建子类对象的时候,会自动调用父类构造函数。

10、面向对象的三大特性?

  • 封装:指把一个对象的状态信息(属性)隐藏在对象内部,不允许外部对象直接访问对象的内部信息,但可以一共一些可以被外界访问的方法来操作属性

  • 继承:继承就是使用已存在的类定义作为基础建立新类的技术。通过使用继承,可以快速的创建新的类,可以提高代码的重用,程序的可维护性,节省大量创建新类的时间,提高我们的开放效率。

继承中几个重要的点:

子类拥有父类对象所有的属性和方法(包含私有属性和私有方法),但是父类中的私有属性和方法子类是 无法访问的,只是拥有

子类可以拥有自己的属性个方法,即子类可以对父类进行扩展

  • 多态:一个对象具有多种状态,具体表现为父类的引用指向子类的实例

    多条存在的三个必要条件:要有继承;要有重写;父类引用指向子类对象。

11、在一个静态方法内调用一个非静态成员为啥是非法的?

类的静态成员属于类本身,在类加载的时候就会分配内存,可以通过内存直接访问。非静态成员属于类的对象,只有在类的对象实例化时才会分配内存,然后通过类的实例化去访问,静态方法优先于对象的存在,所以一个类的静态方法去调用非静态方法或者变量的时候,类的非静态成员可能不存在

12、静态方法和实例化方法有何不同

在外部调用静态方法时,可以使用“类名.方法名”和“对象名.方法名”的方式。但实例化方法只能使用后面这种方式,调用静态方法可以不用创建对象

静态方法只允许访问静态成员(静态成员和静态方法),不允许访问实例成员变量和实例方法。实例方法就没有这个限制

13、抽象类和接口

  • 抽象类中可以有构造器方法,普通方法和普通成员变量。接口中只能声明静态公共常量,默认都是抽象方法

  • 抽象类中抽线方法的访问类型可以是public、protected和default,但接口中的抽象方法默认为 public abstract 类型

  • 抽象类中可以包含静态方法,接口中不能包含静态方法

  • 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量默认为public static final类型

  • 接口可以多继承,多实现,抽象类单继承

  • 接口中可以不声明任何方法和成员变量

    -jdk8在接口可以有默认方法和静态方法功能,jdk9在接口中引入了私有方法和私有成员变量

14、抽象类能使用final修饰吗?

不能 抽象类就是让其他类继承的,如果定义为final该类就不能被继承

15、final的作用

用于修饰类、属性和方法

  • 被final修饰的类不能被继承

  • 被final修饰的方法不能被重写

  • 如果变量是基本数据类型,初始化之后变量的值不能被改变,如果变量是引用类型,那么它只能值像初始化时指向的那个对象,不能再指向别的对象,但是对象当中的内容时允许改变的

16、final、finally、finalize的区别

  • final的作用是用于修饰类、属性和方法,用于表示是最终的、不可变的

  • finally作用再try-catch块中,再异常处理时,我们将一定要执行的代码方法finally代码块中,不管是否出现异常该代码块都会执行

  • finalize属于object的一个方法,该方法有垃圾回收器来调用,当调用System.gc()方法的时候,有垃圾回收器调用finalize方法来回收垃圾,一个对象是否可以回收的最后判断

17、this的用法

this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针

this的用法:

  • 普通的直接引用,this相当于指向当前对象本身

  • 形参于成员名字重用,用this来区分

  • 引用本类的构造函数

18、this和super的区别?

this指向对象本身的一个指针;super是指向父类对象的一个指针,而这父类指的是离自己最近的一个父类

super()再子类中调用父类的构造方法,this()再本类内调用的其他构造方法

super()和this()均需放在构造方法内第一行

this和super不能同时出现再一个构造函数里面

this()和super()都指是对象,所以均不可以再static环境中使用

19、static存在的意义

即使没有创建对象,也可以使用属性和方法

用来形成静态代码块来优化程序的性能

注意:1、静态只能访问静态 2、非静态既可以访问非静态的,也可以访问静态的

20、多态和多态机制,Java语言如何实现多态的

父类类型的变量指向子类创建的对象,使用该变量调用父类中一个被子类重写的方法,则父类中的方法呈现出不同的行为特征,他是通过动态绑定来实现的

Java实现多态的三个必要条件:继承、重写、向上转型

继承:再多态中必须存在有击沉关系的子类和父类

重写:子类对父类中某些方法进行重新定义,再调用这些方法时就会调用子类的方法

向上转型:再多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能地道用父类的方法和子类的方法

21、面向对象的6大基本原则

  • 单一职责原则SRP(Single Responsibility Principle)

    类的功能要单一,不能包罗万象,跟杂货铺似的

  • 开放封闭原则OCP(Open - Close Principle)

    一个模块对于扩展是卡方的,对于修改是封闭的,想要增加功能热烈欢迎,想要修改不乐意

  • 里氏替换原则LSP

子类可以替换父类出现父类能够出现的任何地方。

  • 依赖倒置原则DIP

    高层次的模块不应该依赖低层次的模块,他们都应该依赖于抽象。抽象不应该依赖于具体实现

    具体实现应该依赖于抽象

  • 接口分离原则ISP

    设计时采用多个于特定客户类有关的接口比采用一个通用的接口更好

22、内部类

将一个类定义放在另一个类的定义内部

成员内部类、局部内部类、匿名内部类和静态内部类

23、内部类的优点

一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据

内部类不为同一包的其他类可见,具有良好的分装性

内部类有效实现了“多重继承”,优化java单继承的缺陷

24、创建一个对象用哪些关键字?对象实例与对象引用有啥不同?

new关键字,new创建对象实例,对象引用指向对象实例/一个对象应用可以指向0或1个对象;一个对象可以有n个对象引用指向它

25、String、StringBuffer、StringBuilder的区别是啥?String为啥是不可变的?

String类中可以使用final关键字修饰字符数组来保存字符串。private final char value[],所以String是不可变的

StringBuffer和StringBuilder都继承子AbstractStringBilder类,在AbstractStringBuilder中也是使用字符串数组保存字符串char[]value,但是没有用final修饰,所以这两种对象都是可变的

StringBuffer:线程安全的,方法被sychronized修饰,底层使用char[],长度是16

SreingBuilder:线程不安全, 效率高,底层使用char[]

26、Object类常见方法总结

public final native Class<?>getClass() native 方法,用于反扭当前运行时对象的Class对象,使用了final关键字修饰,故不允许子类重写

public native int hashCode() native方法,用与返回当前运行时对象的class对象,使用了final关键字修饰,故不允许子类重写

public boolean equals(Object obj)用于比较俩个对象的内存地址是否相等,String类对该方法进行了重写故比较字符串的值是否相等

proteced native Object clone() throws CloneNotSupportedException naitve方法,用于创建并返回当前对象的一份拷贝。一般情况下,对于任何对象x,表达式x.clone()!=x 为true x.clone().getClass() == x.getClass() 为true Object本身没有实现Cloneable接口,所以补充些clone方法并且进行调用的话会发生CloneNotSupportedException异常

public String toString() 返回类的名字@实例的哈希码的16进制的字符串。建议Object所有的子类都重写这个方法

public final native void notify() natice方法,不能重写。唤醒一个在此对象监视器上等待的线程(监视器就相当于是锁的概念)。如果有多个线程在等待只会任意唤醒一个

public final native void notifyAll() native方法,不能重写。跟notify一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程

public final native void wait(long timeout) throws InterruptesException native 方法,并且不能重写。暂停线程的执行。注意:sleep方法没有释放锁,而wait方法释放了锁。timeout是等待时间

public final void wait(long timeout,int nanos) throws InterruptedException 多了nanos参数,这个参数表示额外时间(一毫秒为单位,范围是0-999999)。所以超时的时间还需要加上nanos毫秒

public final void wait() throws InterruptedException 跟之前的两个wait方法一样,只不过该方法一直等待,没超时时间这个概念

protected void finalize() throws Throwable 实例被垃圾回收器回收的时候触发的操作

27.Java访问修饰符private、default、protected、public的区别

  • private:私有的,被private修饰的类、方法、属性只能被本类的对象访问

  • default:默认的,在这种模式下,只能在同一个包内访问

  • protected:受保护的,被protected修饰的类、方法、属性只能被本类,本包、不同包的子类所访问(注意这里是不同包的子类

  • public:公共的,被public修饰的类、方法、属性可以跨类和跨包访问

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值