单例模式
单例模式:(书籍推荐:大话设计模式、设计模式之禅、ODD)
什么是单例: 一个类只能产生一个实例对象
什么场景下使用单例:windows系统中的任务管理器, Spring里SessionFactory
如何编写?
1:构造器私有
2:对外提供过去对象的方法
3:声明一个static的成员变量 类加载的时候创建当前单例对象
4:在获取对象方法中返回成员变量的值
饿汉式
优缺点分析:
缺点: 不能做到延迟加载
优点: 天然线程安全
代码:
public class Single {
// 声明一个Single对象
public static Single single = new Single();
//1:将构造器私有
private Single() { }
/***
public : 外界一定是通过该方法获取当前类的实例对象 所以对外一定要可见
* static : 构造器都私有了,外部肯定无法获取到当前类的实例对象,所以只能用static修饰
属于类的 可以通过类名调用
* 不加static要通过对象调用
* 返回值 : 当前类的实例
**/
public static Single getInstance()
{
return single;
}
}
懒汉式
lazy: 懒汉式 能够做到延迟加载 但是线程不安全
代码:
public class Lazy {
private static Lazy lazy = null;
private Lazy() { }
public static Lazy getInstance() {
if(lazy==null) {
lazy = new Lazy();
}
return lazy;
}
}
多态
多态:
多种形态
构成多态的前提条件:
1:继承关系
2:父类变量指向了子类对象
3:一定要有方法的重写
public class Test01 {
public static void main(String[] args) {
/**
Animal an = new Animal(); an.eat();
** Dog d = new Dog(); d.eat(); d.lookDoor();
*/
Animal an1 = new Dog();// 父类变量指向了子类对象
an1.sleep();
an1.eat();// 编译看左边 运行看右边
an1.lookDoor();
}
}
class Animal{
public Animal() {}
public void sleep() {
System.out.println("animal sleep");
}
public void eat() {
System.out.println("animal eat");
}
}
class Dog extends Animal{
public Dog() { }
@Override public void eat() {
System.out.println("dog eat");
}
public void lookDoor() {
System.out.println("看门");
}
}
多态的应用
/***
封装:
* 有一个公司,招人(管饭)
* 中国人: 用筷子 中餐
* 英国人:用刀叉 西餐
*/
public class Test02 {
public static void main(String[] args) {
Chinese ch = new Chinese();
eatRoom(ch);
En en = new En();
eatRoom(en);
}
/*
* public static void eatRoom(Chinese ch) { ch.eat(); }
*
* public static void eatRoom(En en) { en.eat(); }
*/
public static void eatRoom(Person person) {
// Person person = ch; Person person = en; person.eat();
}
}class Person{
public Person() {}
public void eat() { }
}
class Chinese extends Person{
private String name;
private int age;
public Chinese() { }
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
public void eat() {
System.out.println("用筷子吃饭");
}
}
class En extends Person{
private String name;
private int age;
public En() { }
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
public void eat() {
System.out.println("用刀叉吃饭");
}
}
类的加载顺序
{} 代码块:
局部代码块:声明在方法中的代码块
缩减局部变量的生命周期 提高内存是使用率
成员代码块:初始化块
声明在方法外 类中的代码块
初始化块在类加载的时候是不会执行的
在创建对象之前会被调用(对于对象中的一些初始进行初始化操作)
静态代码块:
声明在类中 方法外 且使用static修饰
类加载的时候就会被加载 并且只加载1次 静态内容
类中的执行顺序:
1:首先执行静态内容(加载) 静态代码块
2:初始化块
3:构造器
类加载:
使用当前类中的静态方法、静态变量
创建当前类的实例对象
public class Test02 {
static {
System.out.println("我是静态代码块");
}
int age ;
{
age = 20; System.out.println("我是初始化块");
}
public static void main(String[] args) {
/*
* { int num = 10; System.out.println(num); }
*/
Test02 t = new Test02();
System.out.println(t.age);
new Test02();
}
public Test02() {
System.out.println("我被调用了");
}
}
类型转换
案例
引用类型也有类型转换:
自动转换:
父类型 变量名 = 子类对象;【new 子类对象|子类对象的变量】
强制转换:
子类型 变量名 = (子类型)父类变量; [事先确定了父类变量中实际存储的对象是什么类型]
ClassCastException 类型转换异常
public class Test03 {
// F 是父类 存在 fun方法 S1 S2子类重写了fun方法 并且每个类中都存在一个自己的独有方法m1
public static void main(String[] args) {
F f = new F();
f.fun();
S1 s1 = new S1();
s1.fun();
f = s1;
//f.m1();//编译出错
S1 ss = (S1)f;
//ss.m1();
//S2 s2 = (S2)f;
//s2.m1();
//s2.fun();
}
}
class F{
public void fun() {
System.out.println("f f");
}
}
class S1 extends F{
public void m1() {
System.out.println("S1 m1");
}
public void fun() {
System.out.println("S1 f");
}
}
class S2 extends F{
public void m1() {
System.out.println("S2 m1");
}
public void fun() {
System.out.println("S2 f");
}
}
内存分析
