1)、单例模式
什么是单例:
一个类只能产生一个实例对象
什么场景下使用单例:
windows 任务管理器 Spring SessionFactory * 如何编写?
1:构造器私有
2:对外提供过去对象的方法
3:声明一个static的成员变量 类加载的时候创建当前单例对象
4:在获取对象方法中返回成员变量的值
饿汉式:
优缺点分析;
缺点: 不能做到延迟加载
优点: 天然线程安全
- package com.mage.single;
- public class Single {
-
// 声明一个Single对象
-
public static Single single = new Single();
-
//1:将构造器私有
-
private Single() {
-
}
-
public static Single getInstance() {
-
return single;
-
}
-
public static void add() {
-
} 19. }
懒汉式:
懒汉式 能够做到延迟加载 但是线程不安全
- package com.mage.single;
- public class Lazy {
-
private static Lazy lazy = null;
-
private Lazy() {
-
}
-
public static Lazy getInstance() {
-
if(lazy==null) {
-
lazy = new Lazy();
-
}
-
return lazy;
-
} 17. }
2)、多态
多态: 多种形态
构成多态的前提条件:
1:继承关系
2:父类变量指向了子类对象
3:一定要有方法的重写
3)、类型转换
引用类型也有类型转换:
自动转换:
父类型 变量名 = 子类对象;【new 子类对象|子类对象的变量】
强制转换:
子类型 变量名 = (子类型)父类变量; [事先确定了父类变量中实际存储的对象是什么类型]
ClassCastException 类型转换异常
4)、abstract抽象类
学习抽象类:
1: 父类中定义的方法不需要具体的实现步骤 子类都不按照父类的做
2: 父类中定义这个方法的目的是告诉子类 一定要保证存在该方法
对于类的要求:
1:父类中不需要定义方法的实现步骤
2:子类必须要重写
抽象类:
包含了抽象方法的的类称之为抽象类。
被abstract修饰的类称之为抽象了
1:抽象类中只能包含抽象方法吗?
既可以定义抽象方法也可以定义普通方法
2:是否可以定义构造器
抽象类可以存在构造器但是无法实例化
抽象类中的构造器是给子类准备的
抽象类就是用来被继承的 抽象方法就是被重写的
3:子类继承了抽象了之后一定要重写所有的抽象方法
抽象方法:
只要方法的声明,没有方法体。通过abstract修饰的方法称之为抽象方法
为什么需要抽象类?
避免子类的随意设计 提高了代码可读性 提高了子类的健壮性
模板方法:
- package com.mage.oop.lian;
- public class DrinkTest01 {
-
public static void main(String[] args) {
-
Water t = new Tea();
-
t.flow();
-
Water o = new Off();
-
o.flow();
-
}
- }
- abstract class Water{
-
//public Water() {}
-
public void heatWater() {
-
System.out.println("烧水!");
-
}
-
abstract void pao();
-
public void drink() {
-
System.out.println("品尝!");
-
}
-
public void flow() {
-
heatWater();
-
pao();
-
drink();
-
}
- }
- class Tea extends Water{
-
public Tea() {
-
}
-
public void pao() {
-
System.out.println("泡茶!");
-
}
- }
- class Off extends Water{
-
public Off() {
-
}
-
public void pao() {
-
System.out.println("搅拌!");
-
} 40. }
5)、类的加载顺序
局部代码块:
声明在方法中的代码块
缩减局部变量的生命周期 提高内存是使用率
成员代码块:
初始化块
声明在方法外 类中的代码块
初始化块在类加载的时候是不会执行的
在创建对象之前会被调用(对于对象中的一些初始进行初始化操作)
静态代码块:
声明在类中 方法外 且使用static修饰
类加载的时候就会被加载 并且只加载1次 静态内容
加载顺序:
先加载静态内容 -> 先执行静态代码块 由于父子关系 所以子类加载之前需要先加载父类执行的父类的初始化块和欧构造器
准备执行子类的构造器 (先执行初始化块 子类构造器中有一个super)
父类的静态代码块
子类的静态代码块
父类的初始化块
父类的构造器
子类的初始化块
子类的构造器
- package com.mage.oop;
- public class Test04 {
-
public static void main(String[] args) {
-
new S2().m();
-
}
- }
- class F{
-
static {
-
System.out.println("F static");
-
}
-
{
-
System.out.println("F init");
-
}
-
public F() {
-
System.out.println("F construct");
-
}
- }
- class S1 extends F{
-
static {
-
System.out.println("S1 static");
-
}
-
{
-
System.out.println("S1 init");
-
}
-
public S1() {
-
System.out.println("S1 construct");
-
}
- }
- class S2 extends F{
-
static {
-
System.out.println("S2 static");
-
}
-
{
-
System.out.println("S2 init");
-
}
-
public S2() {
-
System.out.println("S2 construct");
-
}
-
public void m() {
-
new S1();
-
} 46. }
6)、理解final
final可以修饰类,方法,变量。
final修饰类不可以被继承,但是可以继承其他类。
final修饰的方法不可以被覆写,但可以覆写父类方法。
final修饰的变量称为常量,这些变量只能赋值一次。
内部类在局部时,只可以访问被final修饰的局部变量。
final修饰的引用类型变量,表示该变量的引用不能变,而不是该变量的值不能变;
final 修饰的基本数据类型变量 无法进行修改的
final 修饰的引用类型的变量 只保证地址不变 对象中的内容可以发生改变
静态成员常量不会导致类加载
静态成员常量的值在加载前无法确定 那么会导致类加载
final修饰的变量称之为最终常量 在程序运行期间其值不可发生改变
final修饰的类不可以被继承:太监类
final修饰的方法不可以被重写
7)、接口的理解
接口:
接口是一个规范 是一套标准 比抽象了还抽象
接口如何定义:
学习接口和学习类是一样的
接口定义:
修饰符 interface 接口名{}
接口中的变量都是公开的 静态的最终常量值 默认情况下变量都是public static final修饰
接口中可以定义静态方法(不建议1.8)
接口中定义的对象方法都是抽象方法 接口中的方法默认就是通过abstract修饰的
接口中的默认方法从1.8之后才开始被使用 允许在接口中定义default方法 而且存在方法体
修饰符 class 类名 extends 父类 implements 接口
接口深入:
1、 类和接口直接通过implements 发生关系 类实现接口
2、类必须要实现接口中的所有抽象方法
3、一个类可以实现多个接口 类名 implements 接口1,接口2。。。。。
4、一个类实现了接口之后 要将当前接口以及接口的父接口中的所有抽象方法全部重写
5、接口可以多继承
6、接口无法实例化
7、接口没有构造器
8、接口中也可以使用多态
8)、object类
Object: 是所有类的根基类 超类 父类
当一个类没有显式的继承关系的时候,默认情况下他的父类都是Object
toString方法(默认返回对象的类型+@+内存地址值,通常需要重写改方法)
toString方法返回该对象的字符串表示,其实该字符串内容就是对象的类型+@+内存地址值。由于toString方法返回的结果是内存地址,而在开发中,经常需要按照对象的属性得到相应的字符串表现形式,因此也需要重写它。
9)、equals方法
用于比较两个对象是否相同,它其实就是使用两个对象的内存地址在比较。Object类中的equals方法内部使用的就是==比较运算符
经常重写equals方法,用来比较两个对象的属性。
equals方法就是用来比较两个对象是否相等的,默认Object的equals方法比较是两个对象的地址。
- class Person extends Object{
-
int age ;
-
//复写父类的equals方法,实现自己的比较方式
-
public boolean equals(Object obj) {
-
//判断当前调用equals方法的对象和传递进来的对象是否是同一个
-
if(this == obj){
-
return true;
-
}
-
//判断传递进来的对象是否是Person类型
-
if(!(obj instanceof Person)){
-
return false;
-
}
-
//将obj向下转型为Perosn引用,访问其属性
-
Person p = (Person)obj;
-
return this.age == p.age;
-
} 17. }
10)、instanceof的用法
java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
- if(obj instanceof class)
- {
- System.out.printf(“obj是class类的对象”);
- }
- else {
- System.out.printf(“obj不是class类的对象”);
- }
其返回true情况如下
1.obj是class类的对象
2.obj是class类子类的对象