面向过程:把过程抽象成方法,通过方法执行解决问题
面向对象:抽象出对象,用对象执行方法的方式解决问题;更易维护、易复用、易扩展
new 运算符,new 创建对象实例(对象实例在堆内存中),对象引用指向对象实例(对象引用存放在栈内存中)
一个对象引用可以指向 0 个或 1 个对象(一根绳子可以不系气球,也可以系一个气球);一个对象可以有 n 个引用指向它(可以用 n 条绳子系住一个气球)
内存存放的内容
指向的内存地址
构造方法是特殊的方法,主要作用是完成对象的初始化
可以
一个类即使没有声明构造方法也会有默认的不带参数的构造方法
在创建对象的时候后面要加一个括号(因为要调用无参的构造方法)
重载了有参的构造方法,记得都要把无参的构造方法也写出来(无论是否用到),因为这可以帮助我们在创建对象的时候少踩坑
名字与类名相同。
没有返回值,但不能用 void 声明构造函数。
生成类的对象时自动执行,无需调用。
构造方法不能被 override(重写),但是可以 overload(重载),所以你可以看到一个类中有多个构造函数的情况
封装:把一个对象的状态信息(也就是属性)隐藏在对象内部,不允许外部对象直接访问对象的内部信息。但是可以提供一些可以被外界访问的方法来操作属性; 如果属性不想被外界访问,我们大可不必提供方法给外界访问。但是如果一个类没有提供给外界访问的方法,那么这个类也没有什么意义了
继承:不同类型的对象,相互之间经常有一定数量的共同点;继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类;子类拥有父类对象所有的属性和方法(包括私有属性和私有方法,但是父类中的私有属性和方法子类是无法访问);子类可以对父类进行扩展;子类可以用自己的方式实现父类的方法
多态:表示一个对象具有多种的状态,具体表现为父类的引用指向子类的实例;对象类型和引用类型之间具有继承(类)/实现(接口)的关系;引用类型变量发出的方法调用的到底是哪个类中的方法,必须在程序运行期间才能确定;多态不能调用“只在子类存在但在父类不存在”的方法;如果子类重写了父类的方法,真正执行的是子类覆盖的方法,如果子类没有覆盖父类的方法,执行的是父类的方法
共同:不能被实例化;可以包含抽象方法;都可以有默认实现的方法
区别:接口用于对类的行为进行约束,实现了某个接口就是具有了对应的行为;抽象类强调所属,用于代码复用; 一个类只能继承一个类,但可以多个接口; 接口中的成员变量只能是 public static final
类型的,不能被修改且必须有初始值;抽象类的成员变量默认 default,可在子类中被重新定义,也可被重新赋值
浅拷贝:浅拷贝会在堆上创建一个新的对象,如果原对象内部的属性是引用类型的话,浅拷贝会直接复制内部对象的引用地址,也就是说拷贝对象和原对象共用同一个内部对象
深拷贝 :深拷贝会完全复制整个对象,包括这个对象所包含的内部对象
== 和 equals() 的区别
基本数据类型中==是值,引用数据类型中==是地址
equals()只能用于判断两个对象是否相等,不可用于基本数据类型
没重写的话等价于==,重写了比较的是两个对象的属性是否相等
hashCode() 有什么用
获取哈希码,也称为散列码。这个哈希码的作用是确定该对象在哈希表中的索引位置
散列表存储的是键值对:能根据“键”快速的检索出对应的“值”。
为什么要有 hashCode
equals
方法判断两个对象是相等的,那这两个对象的 hashCode
值也要相等。
两个对象有相同的 hashCode
值,他们也不一定是相等的(哈希碰撞)
String | StringBuffer | StringBuilder | |
可变性 | 不可变 | 可变
在
| |
线程安全性 | 安全 | 对方法加了同步锁,线程安全 | 没有同步锁,非安全 |
性能 | 每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象 | 对 StringBuffer 对象本身进行操作 | 相同情况下使用 StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险 |
|
著作权归所有 原文链接:https://javaguide.cn/java/basis/java-basic-questions-02.html