封装、继承、多态
封装:
隐藏内部的细节,对外提供某种访问的方式。通常实现封装的手段我们都会使用访问修饰符。
包的封装,控制当前包中的哪些类可以被其他包中的类去访问
通常我们在定义一个class的时候都会使用访问修饰符public。(注意:class只能使用public或者是默认的,也就是不需要任何访问修饰符),没有使用public修饰的类,只能被本包中其他类去访问,不能被其他包中的类去访问
类成员的封装,将属性和行为封装在一个类中,并且也可以通过访问修饰符来控制他们的访问权限
行为本身也具备封装的特性,把实现的细节隐藏,对于调用者而言,内部的实现是透明的。
继承:
继承是一种父与子的关系,继承的好处在于将子类共性的东西提取到父类中,让子类做更少的事情,因此达到代码的复用性,这样使整个结构更加清晰。(继承是一种is a的关系)
Java中只能是单继承的关系,也就是一个子类只能有一个父类,但是一个父类有多个子类的。
在java中所有类的默认父类都是Object。
在继承的时候,使用extends关键字。
子类不能继承用用
多态:
一个对象具有多种形态的表现,多态的前提是必须有继承。因为在不同场合或者业务场景中,子类是可以替代父类来完成具体的某件事情。
1)引用多态
父类的引用类型,子类的对象
2)行为上的多态
通常在子类中会重写父类的方法,来完成具体的功能。
编译时看父类,运行时看子类(编译的时候看下父类有没有定义这个方法,运行时看子类有没有重写这个方法,如果子类重写,则优先调用子类重写的方法,如果没有重写,则调用继承父类而来的方法)
关于重写和重载
1)重载,方法名相同,参数的个数和类型不同,对返回值不要求,这就是重载,重载既可以发生在本当中,也可以发生在父类和子类当中。构造方法也是可以重载的。
2)重写(覆盖),方法名相同,参数的个数和类型也必须相同,返回值也必须相同。重写只能发生在父类和子类当中。
子类只能重写父类非final修饰的方法
抽象接口
抽象类:
当一个类不能具体去描述一个对象的时候,我们就认为它是抽象的。因此抽象类不能用来创建实例来使用的,主要用来被继承。
特点:
1、抽象类可以有自己的构造方法
2、抽象类可以有具体的方法
3、抽象类可以有抽象方法,必须使用abstract关键字来修饰,这个反复必须由子类来实现
4、抽象类不能使用new关键字来创建实例
5、定义抽象必须使用adstract关键字声明
6、当一个类中只要有一个抽象方法,这个类就必须有抽象类
7、抽象类可以定义实例变量和静态变量以及常量
8、抽象类可以在继承抽象类,也可以继承普通类
接口:
接口是比抽象类更为抽象的一个组件,它主要用于定于行为的标准。因此接口是用来被实现的,使用implements关键字。
特点:
1、接口只能定义常量
2、接口只能定义抽象方法
3、接口只能继承接口,但不能继承普通的类和抽象类
4、接口是没有构造方法的
注意:
1、在接口中定义常量时,可以不用final static修饰,因为编译器在编译时会自动加上
2、在接口中定义抽象方法时可以省略abstract关键字,编译器在编译时同样会自动加上
静态成员
静态成员也就是用static关键字修饰的变量或者方法或者代码块,他们都属于类的成员。静态成员是在类加载(加载class文件的时候)时就已经初始化好了,并存放在方法区中。可以被多个实例所共享
1)静态变量:静态变量也叫做类变量,因为它只跟类相,跟实例无关,我们才可以通过类名.变量名来访问。静态变量和实例变量的区别在于,静态变量只跟类相关,跟实例无关,当前类的所有实例都会共享这一份静态变量,可以通过类名.属性名访问。
2)静态代码块:也是类的一种成员,它在类加载的时候会执行一次这个代码块的内容,而且只会执行一次
3)静态方法:使用static修饰的方法,同样可以使用类名.方法名进行调用,
(注意:静态方法只能访问外部的静态变量和调用其它的静态方法。不能访问实例变量,也不能调用普通的成员方法,也不使用使用this关键字。因为它也和类相关,和实例无关)
静态方法其实不具备多态性,只看编译时类型
我们都知道在创建一个对象之前,必须要先执行类加载的操作,而这个类加载的过程却做了一系列的初始化操作,最终才构建出这个实例。
在创建一个对象的时候,最先调用的是构造方法
也就是new关键字后面的方法。
在子类的构造方法的第一样会有一个隐式的super(),表示要调用父类的构造方法,并且super()这行代码只能出现在构造方法的第一行。
初始化顺序:
父类的静态成员->子类的静态成员->父类的实例变量以及代码块->父类的构造方法->子类的实例变量以及代码块->子类的构造方法
集合
Collection
List----àArrayList:内部是基本数组实现,在初始化的时候会创建一个长度为10的空列表(也就是数组),当超出范围后,会自动扩充数组的长度。
由于是基于数组的接口,那么在使用ArrayList获取数据的时候,直接依据下表获取内容,性能相对较高。
但是如果要在集合的中间插入新的元素,这将导致后面的所有元素都要进行迁移,性能会下降
但是在调用add的方法时,由于添加进去的元素是直接放在集合的末尾,所以通常不会影响性能。此集合是有序的。
LinkedList:
LinkedList是基于链表的数据结构实现的,链表是一种线性的数据机构。
当从LinkedList中获取元素时,内部必须从第一个元素开始查找,直到找到当前下表元素位置,性能相比ArrayList要低。但是在中间插入元素的时候,它的性能要比ArrayList要高。并且LinkedList支持在头部和尾部进行元素的添加。
此集合是有序的。
HashSet:
它和List的区别:
1)HashSet是无序的
2)它是没有下标的
3)它是不允许重复元素
很多方法都实现了Collection接口
TreeSet,它和HashSet的一样,无下标,不允许重复元素,唯一和HashSet的区别就是它是有序的
HashMap,是以一种键值对的方式进行存储(Key,Value)。
Hashtable在用法上和HashMap是一样的,都是实现了Map接口
区别在于:
1) Hashtable是不允许空键和空值的,而HashMap是允许的。
2) Hashtable是线程安全的,而HashMap是非线程安全的
JDBC
JDBC(Java Date Base Connectivity):
用于连接和操作数据的一个标准接口
既然是一个接口,那么它就是一个标准,所有的数据库厂商都会依据这个标准实现一套自己的产品的驱动,用于访问不同的数据库。这么驱动通常都以jar包的形式发行,它们都是JDBC的标准是实现,所以我们在使用JDBC时,必须导入相应数据库的jar包。
我们在访问数据库的时候,只面向JDBC的接口操作,这就是面向接口编程,将实现细节隐藏。