1.1 面向对象特性
-
封装性:是指隐藏对象的属性和方法实现细节,对外提供访问属性的公共方法。
好处:
- 能够更好的把控成员变量,甚至是管理类的内部结构。
- 良好的封装能够减少耦合,使得代码更加健壮。
- 外部程序通过对外方法即可访问,无需关注实现细节。
-
继承性:继承是使用
已存在的类的定义
作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承我们能够非常方便地复用以前的代码
。注意:
- 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
- 子类可以有自己的方式实现父类的方法。即方法重写。
- 子类拥有父类对象所有的属性的方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类无法访问,只是拥有。
-
多态性:是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定。(动态绑定)
通俗一点讲:我们在方法中接收父类类型参数,在方法实现中调用父类类型的各种方法。当把子类作为参数传递给这个方法时,JVM虚拟机会根据实际创建的对象类型,调用子类中相应的方法(存在方法重写时)。
两种实现多态的方式
- 继承----多个子类对同⼀方法的重写。
- 接口----实现接口并覆盖接口中同⼀方法。
好处:可以增强程序的可扩展性及可维护性,使代码更加简洁。
注意:
多态的向上转型会丢失子类的新增方法,同时会保留子类重写的方法。
动态绑定(后期绑定)是指:在程序运行过程中,根据具体的实例对象才能具体确定是哪个方法。
静态绑定(前期绑定)是指:在程序运行前就已经知道方法是属于那个类的,在编译的时候就可以连接到类的中,定位到这个方法。
1.2 重载与重写
-
重载:在同一个类中,如果多个方法有相同的方法名称、不同的参数类型、参数个数、参数顺序,即为重载。
注意:不能有两个方法名称完成相同,参数类型和个数也相同,但返回类型不同的方法。
-
重写:是子类对父类的允许访问的方法的实现过程进行重新编写。
注意:
- 返回值类型、方法名、参数列表必须相同,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类。
- 构造方法无法被重写。
- 如果父类方法访问修饰符为
private/final/static
则子类就不能重写该方法,但是被 static 修饰的方法能够被再次声明。
1.3 泛型
Java 泛型就是类型参数化
。被称为伪泛型,主要是因为在编译期期间,所有的泛型信息都会被擦除掉,整个Java泛型都是在编译期层面实现的。
类型擦除:使用泛型的时候加上的类型参数,会在编译器编译的时候去掉类型信息。(生成的Java字节码中不包含泛型中的类型信息。
原始类型:没有泛型的最初类型,即擦除去了泛型信息,最后在字节码中的类型变量的真正类型。
-
没有限定类型时,类型变量被擦除,原始类型为Object。
class Colleage<T>{ private T student; public Colleage(T student){ this.student=student; } public T getStudent() { return student; } public void setStudent(T student) { this.student = student; } }
-
有限定类型时,类型变量被擦除,原始类型是其限定类型。对于有多个限定的类型变量,那么原始类型就用第一个边界的类型变量来替换。
class Colleage <T extends Comparable & Serializable>{
此时Colleage的原始类型就是Comparable。
问题:编译的时候进行类型擦除,那所有的泛型类型变量最后都会被替换为原始类型。并且获取的时候不需要手动的类型转换,那么类型转换是在什么时候进行的?
public E get(int index) {
RangeCheck(index);
return (E) elementData[index];
}
可以看到,在return之前,会根据泛型变量进行强转。假设泛型类型变量为Date,虽然泛型信息会被擦除掉,但是会将(E) elementData[index]
,编译为(Date)elementData[index]
。所以我们不用自己进行强转。当存取一个泛型域时也会自动插入强制类型转换。
优点
- 类型安全,如果放入的类型不是泛型指定的类型,编译器会报错。
- 提升可读性。
- 代码重用。
1.4 关键字
1.4.1 static
- 修饰成员变量和成员方法:被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享,可以并且建议通过类名调用。调用格式:
类名.静态变量名
类名.静态方法名()
- 静态代码块:静态代码块定义在类中方法外, 静态代码块在非静态代码块之前执行(静态代码块—>非静态代码块—>构造方法)。 该类不管创建多少对象,静态代码块只执行一次。
- 静态内部类:静态内部类与非静态内部类之间存在一个最大的区别: 非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围类,但是静态内部类却没有。没有这个引用就意味着:1. 它的创建是不需要依赖外围类的创建。2. 它不能使用任何外围类的非static成员变量和方法。
- 静态导包: 格式为:
import static
这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名调用类中静态成员,可以直接使用类中静态成员变量和成员方法。
1.4.2 final
final关键字,意思是最终的、不可修改的
,用来修饰类、方法和变量
。
具有以下特点:
- final修饰的
类不能被继承
,final类中的所有成员方法都会被隐式的指定为final方法; - final修饰的
方法不能被重写
; - final修饰的变量是常量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能让其指向另一个对象。
1.5 字符串类比较
-
String是不可变的。
String
类中使用 final 关键字修饰字符数组来保存字符串,private final char value[]
,所以String
对象是不可变的。 -
StringBuffer 和 StringBuilder 是可变的。
StringBuilder
与StringBuffer
都继承自AbstractStringBuilder
类,在AbstractStringBuilder
中是使用字符数组保存字符串char[] value
但是没有用final
关键字修 饰,所以这两种对象都是可变的。 -
String
中的对象是不可变的,也就可以理解为常量,线程安全。 -
StringBuffer
对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。 -
StringBuilder
并没有对方法进行加同步锁,所以是非线程安全的。