封装
设计模式:
前人总结的(编码)套路
23种:
遵循5大原则,以开闭原则为基础
(模式推荐书籍:大话设计模式、设计模式之禅、ODD)
单例模式:
什么是单例:
一个类只能产生一个实例对象
- 什么场景下使用单例:windows 任务管理器 Spring SessionFactory
如何编写?
- 1:构造器私有
- 2:对外提供过去对象的方法
- 3:声明一个static的成员变量 类加载的时候创建当前单例对象
- 4:在获取对象方法中返回成员变量的值
饿汉式
优缺点分析:
- 缺点: 不能做到延迟加载
- 优点: 天然线程安全
代码
public class Test01 {
public static void main(String[] args) {
//创建Single对象 通过类名.方法名获取类对象
/*
* Single s1 = Single.getInstance(); Single s2 = Single.getInstance();
* System.out.println(s1); System.out.println(s2); System.out.println(s1==s2);
*/
Single.add();
//System.out.println(Single.single);
Lazy l1 = Lazy.getInstance();
Lazy l2 = Lazy.getInstance();
System.out.println(l1==l2);
System.out.println(l1);
System.out.println(l2);
}
}
package com.mage.single;
public class Single {
// 声明一个Single对象
public static Single single = new Single();
//1:将构造器私有
private Single() {
}
/**
* public : 外界一定是通过该方法获取当前类的实例对象 所以对外一定要可见
* static : 构造器都私有了 外部肯定无法获取到当前类的实例对象 所以只能用static修饰 属于类的 可以通过类名调用
* 不加static要通过对象调用 对象没有
* 返回值 : 当前类的实例
*
*/
public static Single getInstance() {
return single;
}
public static void add() {
}
}
- 注意:
- public : 外界一定是通过该方法获取当前类的实例对象 所以对外一定要可见
- static : 构造器都私有了 外部肯定无法获取到当前类的实例对象 所以只能用
static修饰 属于类的 可以通过类名调用。不加static要通过对象调用 对象没有 - 返回值 : 当前类的实例
懒汉式
优缺点分析:
lazy: 懒汉式 能够做到延迟加载 但是线程不安全
代码
public class Lazy {
private static Lazy lazy = null;
private Lazy() {
}
public static Lazy getInstance() {
if(lazy==null) {
lazy = new Lazy();
}
return lazy;
}
}
引用类型的类型转换
- 自动转换
父类型 变量名 = 子类对象;【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");
}
}
多态:
多种形态
构成多态的前提条件:
- 1:继承关系
- 2:父类变量指向了子类对象
- 3:一定要有方法的重写
注意:编译看左边 运行看右边
package com.mage.oop;
import javax.sound.midi.Soundbank;
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("看门");
}
}
多态的实例
package com.mage.oop;
/*
*
* 封装:
*
*
*
* 有一个公司,招人(管饭)
* 中国人: 用筷子 中餐
* 英国人:用刀叉 西餐
*/
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("我被调用了");
}
}
- 内存分析